diff --git a/.playwright-mcp/console-2026-03-07T19-59-28-775Z.log b/.playwright-mcp/console-2026-03-07T19-59-28-775Z.log deleted file mode 100644 index 1a84b8e..0000000 --- a/.playwright-mcp/console-2026-03-07T19-59-28-775Z.log +++ /dev/null @@ -1 +0,0 @@ -[ 71ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:3000/favicon.ico:0 diff --git a/.playwright-mcp/console-2026-03-07T20-32-14-148Z.log b/.playwright-mcp/console-2026-03-07T20-32-14-148Z.log deleted file mode 100644 index e9b2839..0000000 --- a/.playwright-mcp/console-2026-03-07T20-32-14-148Z.log +++ /dev/null @@ -1,12 +0,0 @@ -[ 469877ms] [ERROR] Failed to load resource: the server responded with a status of 500 (Internal Server Error) @ http://localhost:3000/orgs/rawpotion/destinations:0 -[ 473324ms] [ERROR] Failed to load resource: the server responded with a status of 500 (Internal Server Error) @ http://localhost:3000/orgs/rawpotion/destinations:0 -[ 473751ms] [ERROR] Failed to load resource: the server responded with a status of 500 (Internal Server Error) @ http://localhost:3000/orgs/rawpotion/destinations:0 -[ 473934ms] [ERROR] Failed to load resource: the server responded with a status of 500 (Internal Server Error) @ http://localhost:3000/orgs/rawpotion/destinations:0 -[ 474119ms] [ERROR] Failed to load resource: the server responded with a status of 500 (Internal Server Error) @ http://localhost:3000/orgs/rawpotion/destinations:0 -[ 474291ms] [ERROR] Failed to load resource: the server responded with a status of 500 (Internal Server Error) @ http://localhost:3000/orgs/rawpotion/destinations:0 -[ 474467ms] [ERROR] Failed to load resource: the server responded with a status of 500 (Internal Server Error) @ http://localhost:3000/orgs/rawpotion/destinations:0 -[ 474629ms] [ERROR] Failed to load resource: the server responded with a status of 500 (Internal Server Error) @ http://localhost:3000/orgs/rawpotion/destinations:0 -[ 560213ms] [ERROR] Failed to load resource: the server responded with a status of 404 () @ chrome-error://chromewebdata/:0 -[ 561436ms] [ERROR] Failed to load resource: the server responded with a status of 404 () @ chrome-error://chromewebdata/:0 -[ 561803ms] [ERROR] Failed to load resource: the server responded with a status of 404 () @ chrome-error://chromewebdata/:0 -[ 561970ms] [ERROR] Failed to load resource: the server responded with a status of 404 () @ chrome-error://chromewebdata/:0 diff --git a/.playwright-mcp/console-2026-03-07T20-35-27-169Z.log b/.playwright-mcp/console-2026-03-07T20-35-27-169Z.log deleted file mode 100644 index 06f9559..0000000 --- a/.playwright-mcp/console-2026-03-07T20-35-27-169Z.log +++ /dev/null @@ -1 +0,0 @@ -[ 157ms] [ERROR] Failed to load resource: the server responded with a status of 404 () @ https://rawpotion.io/favicon.ico:0 diff --git a/.playwright-mcp/console-2026-03-07T21-49-57-898Z.log b/.playwright-mcp/console-2026-03-07T21-49-57-898Z.log deleted file mode 100644 index 7f45087..0000000 --- a/.playwright-mcp/console-2026-03-07T21-49-57-898Z.log +++ /dev/null @@ -1,4 +0,0 @@ -[ 6ms] [ERROR] Failed to load resource: the server responded with a status of 403 (Forbidden) @ http://localhost:3000/orgs/my-org/releases:0 -[ 1711ms] [ERROR] Failed to load resource: the server responded with a status of 403 (Forbidden) @ http://localhost:3000/orgs/my-org/releases:0 -[ 2177ms] [ERROR] Failed to load resource: the server responded with a status of 403 (Forbidden) @ http://localhost:3000/orgs/my-org/releases:0 -[ 2346ms] [ERROR] Failed to load resource: the server responded with a status of 403 (Forbidden) @ http://localhost:3000/orgs/my-org/releases:0 diff --git a/.playwright-mcp/console-2026-03-07T23-04-16-205Z.log b/.playwright-mcp/console-2026-03-07T23-04-16-205Z.log deleted file mode 100644 index a3b9632..0000000 --- a/.playwright-mcp/console-2026-03-07T23-04-16-205Z.log +++ /dev/null @@ -1 +0,0 @@ -[ 72ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:3000/favicon.ico:0 diff --git a/.playwright-mcp/console-2026-03-07T23-06-48-917Z.log b/.playwright-mcp/console-2026-03-07T23-06-48-917Z.log deleted file mode 100644 index 99da8b8..0000000 --- a/.playwright-mcp/console-2026-03-07T23-06-48-917Z.log +++ /dev/null @@ -1 +0,0 @@ -[ 9ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:3000/users/kjuulh:0 diff --git a/.playwright-mcp/console-2026-03-07T23-08-47-266Z.log b/.playwright-mcp/console-2026-03-07T23-08-47-266Z.log deleted file mode 100644 index b5186e4..0000000 --- a/.playwright-mcp/console-2026-03-07T23-08-47-266Z.log +++ /dev/null @@ -1 +0,0 @@ -[ 7745ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:3000/users/kjuulh:0 diff --git a/.playwright-mcp/console-2026-03-07T23-28-21-144Z.log b/.playwright-mcp/console-2026-03-07T23-28-21-144Z.log deleted file mode 100644 index 7d44f01..0000000 --- a/.playwright-mcp/console-2026-03-07T23-28-21-144Z.log +++ /dev/null @@ -1 +0,0 @@ -[ 243429ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:3000/users/kjuulh:0 diff --git a/.playwright-mcp/console-2026-03-08T13-09-32-749Z.log b/.playwright-mcp/console-2026-03-08T13-09-32-749Z.log deleted file mode 100644 index b96515c..0000000 --- a/.playwright-mcp/console-2026-03-08T13-09-32-749Z.log +++ /dev/null @@ -1 +0,0 @@ -[ 11ms] [ERROR] Failed to load resource: the server responded with a status of 403 (Forbidden) @ http://localhost:3000/orgs/testorg/projects/my-api/policies:0 diff --git a/.playwright-mcp/console-2026-03-08T14-22-14-670Z.log b/.playwright-mcp/console-2026-03-08T14-22-14-670Z.log deleted file mode 100644 index 0d80f56..0000000 --- a/.playwright-mcp/console-2026-03-08T14-22-14-670Z.log +++ /dev/null @@ -1 +0,0 @@ -[ 83695ms] [ERROR] Failed to load resource: the server responded with a status of 500 (Internal Server Error) @ http://localhost:3000/orgs/rawpotion/projects/other-example/pipelines:0 diff --git a/.playwright-mcp/console-2026-03-08T14-24-37-198Z.log b/.playwright-mcp/console-2026-03-08T14-24-37-198Z.log deleted file mode 100644 index a0f0225..0000000 --- a/.playwright-mcp/console-2026-03-08T14-24-37-198Z.log +++ /dev/null @@ -1 +0,0 @@ -[ 27797ms] [ERROR] Failed to load resource: the server responded with a status of 500 (Internal Server Error) @ http://localhost:3000/orgs/rawpotion/projects/other-example/pipelines:0 diff --git a/.playwright-mcp/console-2026-03-08T15-10-54-843Z.log b/.playwright-mcp/console-2026-03-08T15-10-54-843Z.log deleted file mode 100644 index ffbe8ce..0000000 --- a/.playwright-mcp/console-2026-03-08T15-10-54-843Z.log +++ /dev/null @@ -1,10 +0,0 @@ -[ 183938ms] [ERROR] Failed to load resource: the server responded with a status of 502 (Bad Gateway) @ http://localhost:3000/orgs/rawpotion/projects/other-example/events:0 -[ 185942ms] [ERROR] Failed to load resource: the server responded with a status of 502 (Bad Gateway) @ http://localhost:3000/orgs/rawpotion/projects/other-example/events:0 -[ 189946ms] [ERROR] Failed to load resource: the server responded with a status of 502 (Bad Gateway) @ http://localhost:3000/orgs/rawpotion/projects/other-example/events:0 -[ 197960ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3000/orgs/rawpotion/projects/other-example/events:0 -[ 213961ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3000/orgs/rawpotion/projects/other-example/events:0 -[ 243962ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3000/orgs/rawpotion/projects/other-example/events:0 -[ 273963ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3000/orgs/rawpotion/projects/other-example/events:0 -[ 303968ms] [ERROR] Failed to load resource: the server responded with a status of 502 (Bad Gateway) @ http://localhost:3000/orgs/rawpotion/projects/other-example/events:0 -[ 333973ms] [ERROR] Failed to load resource: the server responded with a status of 502 (Bad Gateway) @ http://localhost:3000/orgs/rawpotion/projects/other-example/events:0 -[ 363977ms] [ERROR] Failed to load resource: the server responded with a status of 502 (Bad Gateway) @ http://localhost:3000/orgs/rawpotion/projects/other-example/events:0 diff --git a/.playwright-mcp/console-2026-03-08T18-58-10-322Z.log b/.playwright-mcp/console-2026-03-08T18-58-10-322Z.log deleted file mode 100644 index 41f899f..0000000 --- a/.playwright-mcp/console-2026-03-08T18-58-10-322Z.log +++ /dev/null @@ -1 +0,0 @@ -[ 69ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:3000/favicon.ico:0 diff --git a/.playwright-mcp/console-2026-03-08T19-03-18-217Z.log b/.playwright-mcp/console-2026-03-08T19-03-18-217Z.log deleted file mode 100644 index 1722d64..0000000 --- a/.playwright-mcp/console-2026-03-08T19-03-18-217Z.log +++ /dev/null @@ -1,4 +0,0 @@ -[ 42748ms] [ERROR] Failed to load resource: net::ERR_INCOMPLETE_CHUNKED_ENCODING @ http://localhost:3000/orgs/rawpotion/projects/service-example/events:0 -[ 43749ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3000/orgs/rawpotion/projects/service-example/events:0 -[ 49108ms] [ERROR] Failed to load resource: net::ERR_INCOMPLETE_CHUNKED_ENCODING @ http://localhost:3000/orgs/rawpotion/projects/service-example/events:0 -[ 50109ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3000/orgs/rawpotion/projects/service-example/events:0 diff --git a/.playwright-mcp/console-2026-03-08T19-16-00-412Z.log b/.playwright-mcp/console-2026-03-08T19-16-00-412Z.log deleted file mode 100644 index edaca28..0000000 --- a/.playwright-mcp/console-2026-03-08T19-16-00-412Z.log +++ /dev/null @@ -1 +0,0 @@ -[ 281704ms] [ERROR] Failed to load resource: the server responded with a status of 500 (Internal Server Error) @ http://localhost:3000/orgs/rawpotion/projects/service-example:0 diff --git a/.playwright-mcp/console-2026-03-08T20-27-09-753Z.log b/.playwright-mcp/console-2026-03-08T20-27-09-753Z.log deleted file mode 100644 index f8d1c17..0000000 --- a/.playwright-mcp/console-2026-03-08T20-27-09-753Z.log +++ /dev/null @@ -1,10 +0,0 @@ -[ 136576ms] [ERROR] Failed to load resource: net::ERR_INCOMPLETE_CHUNKED_ENCODING @ http://localhost:3000/orgs/rawpotion/projects/service-example/events:0 -[ 137577ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3000/orgs/rawpotion/projects/service-example/events:0 -[ 139578ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3000/orgs/rawpotion/projects/service-example/events:0 -[ 152714ms] [ERROR] Failed to load resource: net::ERR_INCOMPLETE_CHUNKED_ENCODING @ http://localhost:3000/orgs/rawpotion/projects/service-example/events:0 -[ 153715ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3000/orgs/rawpotion/projects/service-example/events:0 -[ 601126ms] [ERROR] Failed to load resource: net::ERR_INCOMPLETE_CHUNKED_ENCODING @ http://localhost:3000/orgs/rawpotion/projects/service-example/events:0 -[ 602127ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3000/orgs/rawpotion/projects/service-example/events:0 -[ 604128ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3000/orgs/rawpotion/projects/service-example/events:0 -[ 608129ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3000/orgs/rawpotion/projects/service-example/events:0 -[ 616130ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3000/orgs/rawpotion/projects/service-example/events:0 diff --git a/.playwright-mcp/console-2026-03-08T21-01-30-414Z.log b/.playwright-mcp/console-2026-03-08T21-01-30-414Z.log deleted file mode 100644 index 23ff7b5..0000000 --- a/.playwright-mcp/console-2026-03-08T21-01-30-414Z.log +++ /dev/null @@ -1,5 +0,0 @@ -[ 80067ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3000/notifications?_partial=1:0 -[ 90065ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3000/notifications?_partial=1:0 -[ 100065ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3000/notifications?_partial=1:0 -[ 110065ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3000/notifications?_partial=1:0 -[ 120065ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3000/notifications?_partial=1:0 diff --git a/.playwright-mcp/console-2026-03-08T21-05-06-279Z.log b/.playwright-mcp/console-2026-03-08T21-05-06-279Z.log deleted file mode 100644 index 7964b38..0000000 --- a/.playwright-mcp/console-2026-03-08T21-05-06-279Z.log +++ /dev/null @@ -1 +0,0 @@ -[ 1030036ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3000/notifications?_partial=1:0 diff --git a/.playwright-mcp/console-2026-03-09T13-04-47-784Z.log b/.playwright-mcp/console-2026-03-09T13-04-47-784Z.log deleted file mode 100644 index 5136cc9..0000000 --- a/.playwright-mcp/console-2026-03-09T13-04-47-784Z.log +++ /dev/null @@ -1 +0,0 @@ -[ 7ms] [ERROR] Failed to load resource: the server responded with a status of 503 (Service Unavailable) @ http://localhost:3000/orgs/rawpotion/settings/integrations:0 diff --git a/.playwright-mcp/console-2026-03-09T13-52-57-420Z.log b/.playwright-mcp/console-2026-03-09T13-52-57-420Z.log deleted file mode 100644 index 05e3d4c..0000000 --- a/.playwright-mcp/console-2026-03-09T13-52-57-420Z.log +++ /dev/null @@ -1 +0,0 @@ -[ 15272ms] [ERROR] Pattern attribute value [a-z0-9][a-z0-9-]*[a-z0-9] is not a valid regular expression: Uncaught SyntaxError: Invalid regular expression: /[a-z0-9][a-z0-9-]*[a-z0-9]/v: Invalid character class @ http://localhost:3000/dashboard:0 diff --git a/.playwright-mcp/console-2026-03-09T19-50-53-447Z.log b/.playwright-mcp/console-2026-03-09T19-50-53-447Z.log deleted file mode 100644 index efa63a9..0000000 --- a/.playwright-mcp/console-2026-03-09T19-50-53-447Z.log +++ /dev/null @@ -1 +0,0 @@ -[ 227ms] [ERROR] Failed to load resource: the server responded with a status of 404 () @ https://client.dev.forage.sh/favicon.ico:0 diff --git a/.playwright-mcp/console-2026-03-11T07-32-37-946Z.log b/.playwright-mcp/console-2026-03-11T07-32-37-946Z.log deleted file mode 100644 index 56a2149..0000000 --- a/.playwright-mcp/console-2026-03-11T07-32-37-946Z.log +++ /dev/null @@ -1 +0,0 @@ -[ 42ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:3000/favicon.ico:0 diff --git a/.playwright-mcp/console-2026-03-11T07-40-40-472Z.log b/.playwright-mcp/console-2026-03-11T07-40-40-472Z.log deleted file mode 100644 index 11802da..0000000 --- a/.playwright-mcp/console-2026-03-11T07-40-40-472Z.log +++ /dev/null @@ -1 +0,0 @@ -[ 105ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:3000/favicon.ico:0 diff --git a/.playwright-mcp/console-2026-03-15T16-15-09-664Z.log b/.playwright-mcp/console-2026-03-15T16-15-09-664Z.log deleted file mode 100644 index 7671b82..0000000 --- a/.playwright-mcp/console-2026-03-15T16-15-09-664Z.log +++ /dev/null @@ -1 +0,0 @@ -[ 314ms] [ERROR] Failed to load resource: the server responded with a status of 404 () @ https://client.dev.forage.sh/favicon.ico:0 diff --git a/.playwright-mcp/console-2026-03-15T16-15-44-059Z.log b/.playwright-mcp/console-2026-03-15T16-15-44-059Z.log deleted file mode 100644 index a051137..0000000 --- a/.playwright-mcp/console-2026-03-15T16-15-44-059Z.log +++ /dev/null @@ -1 +0,0 @@ -[ 61ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ chrome-error://chromewebdata/:0 diff --git a/.playwright-mcp/console-2026-03-15T17-34-15-943Z.log b/.playwright-mcp/console-2026-03-15T17-34-15-943Z.log deleted file mode 100644 index 21d69a5..0000000 --- a/.playwright-mcp/console-2026-03-15T17-34-15-943Z.log +++ /dev/null @@ -1,29 +0,0 @@ -[ 4219ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 73166ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 74210ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 76255ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 80299ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 121662ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 122707ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 124752ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 132300ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 133345ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 135391ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 163462ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 165512ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 169559ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 206249ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 208295ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 229228ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 231273ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 240041ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 242090ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 246135ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 254184ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 270230ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 300275ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 335152ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 337223ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 341292ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 349341ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 365388ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 diff --git a/.playwright-mcp/console-2026-03-15T17-40-47-271Z.log b/.playwright-mcp/console-2026-03-15T17-40-47-271Z.log deleted file mode 100644 index 9ea53d1..0000000 --- a/.playwright-mcp/console-2026-03-15T17-40-47-271Z.log +++ /dev/null @@ -1 +0,0 @@ -[ 80ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example:0 diff --git a/.playwright-mcp/console-2026-03-15T17-40-57-477Z.log b/.playwright-mcp/console-2026-03-15T17-40-57-477Z.log deleted file mode 100644 index e6e3d54..0000000 --- a/.playwright-mcp/console-2026-03-15T17-40-57-477Z.log +++ /dev/null @@ -1,70 +0,0 @@ -[ 28066ms] [ERROR] Failed to load resource: net::ERR_NETWORK_CHANGED @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 29193ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 31313ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 36650ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 38721ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 180246ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 181291ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 183336ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 187382ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 195427ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 211472ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 308815ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 309884ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 311956ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 316026ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 324096ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 400986ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 411491ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 445156ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 649304ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 659749ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 675977ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 678046ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 754725ms] [ERROR] Failed to load resource: net::ERR_NETWORK_CHANGED @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 755871ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 757999ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 763330ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 765397ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 978143ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 980214ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 984281ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1080173ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1082246ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1086330ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1121684ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1123773ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1141045ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1143115ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1147188ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1155258ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1502223ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1504292ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1513751ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1515821ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1519891ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1527937ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1543982ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1574052ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1654209ms] [ERROR] Failed to load resource: net::ERR_NETWORK_CHANGED @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1655305ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1657399ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1661443ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1775829ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1776875ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1778919ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1783494ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1784539ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1786584ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1821582ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1822627ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1824676ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1861759ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1864040ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1865688ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1867222ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1868813ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1870286ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1871945ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1873590ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 1875131ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 diff --git a/.playwright-mcp/console-2026-03-15T18-28-02-722Z.log b/.playwright-mcp/console-2026-03-15T18-28-02-722Z.log deleted file mode 100644 index 4a96684..0000000 --- a/.playwright-mcp/console-2026-03-15T18-28-02-722Z.log +++ /dev/null @@ -1,7 +0,0 @@ -[ 8921ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 93203ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 94247ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 96291ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 124526ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 126598ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 130667ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 diff --git a/.playwright-mcp/console-2026-03-15T18-30-49-631Z.log b/.playwright-mcp/console-2026-03-15T18-30-49-631Z.log deleted file mode 100644 index b0c1d8e..0000000 --- a/.playwright-mcp/console-2026-03-15T18-30-49-631Z.log +++ /dev/null @@ -1,6 +0,0 @@ -[ 9418ms] [ERROR] Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 10488ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 12557ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 16626ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 24672ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 -[ 40718ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example/events:0 diff --git a/.playwright-mcp/console-2026-03-15T18-31-57-555Z.log b/.playwright-mcp/console-2026-03-15T18-31-57-555Z.log deleted file mode 100644 index 0b062b6..0000000 --- a/.playwright-mcp/console-2026-03-15T18-31-57-555Z.log +++ /dev/null @@ -1 +0,0 @@ -[ 53ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ chrome-error://chromewebdata/:0 diff --git a/.playwright-mcp/console-2026-03-15T18-32-21-150Z.log b/.playwright-mcp/console-2026-03-15T18-32-21-150Z.log deleted file mode 100644 index e9f56ea..0000000 --- a/.playwright-mcp/console-2026-03-15T18-32-21-150Z.log +++ /dev/null @@ -1 +0,0 @@ -[ 55ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://client.dev.forage.sh/orgs/rawpotion/projects/service-example:0 diff --git a/.playwright-mcp/element-2026-03-08T21-50-01-232Z.png b/.playwright-mcp/element-2026-03-08T21-50-01-232Z.png deleted file mode 100644 index c9be955..0000000 Binary files a/.playwright-mcp/element-2026-03-08T21-50-01-232Z.png and /dev/null differ diff --git a/.playwright-mcp/element-2026-03-08T21-50-44-447Z.png b/.playwright-mcp/element-2026-03-08T21-50-44-447Z.png deleted file mode 100644 index f1f4d54..0000000 Binary files a/.playwright-mcp/element-2026-03-08T21-50-44-447Z.png and /dev/null differ diff --git a/.playwright-mcp/element-2026-03-08T21-53-14-160Z.png b/.playwright-mcp/element-2026-03-08T21-53-14-160Z.png deleted file mode 100644 index c39c6dd..0000000 Binary files a/.playwright-mcp/element-2026-03-08T21-53-14-160Z.png and /dev/null differ diff --git a/.playwright-mcp/element-2026-03-08T21-54-05-889Z.png b/.playwright-mcp/element-2026-03-08T21-54-05-889Z.png deleted file mode 100644 index ae2755b..0000000 Binary files a/.playwright-mcp/element-2026-03-08T21-54-05-889Z.png and /dev/null differ diff --git a/.playwright-mcp/element-2026-03-08T21-55-10-800Z.png b/.playwright-mcp/element-2026-03-08T21-55-10-800Z.png deleted file mode 100644 index b1229f9..0000000 Binary files a/.playwright-mcp/element-2026-03-08T21-55-10-800Z.png and /dev/null differ diff --git a/.playwright-mcp/element-2026-03-08T22-01-34-066Z.png b/.playwright-mcp/element-2026-03-08T22-01-34-066Z.png deleted file mode 100644 index 6c64a30..0000000 Binary files a/.playwright-mcp/element-2026-03-08T22-01-34-066Z.png and /dev/null differ diff --git a/.playwright-mcp/page-2026-03-08T21-56-48-888Z.png b/.playwright-mcp/page-2026-03-08T21-56-48-888Z.png deleted file mode 100644 index 62d636a..0000000 Binary files a/.playwright-mcp/page-2026-03-08T21-56-48-888Z.png and /dev/null differ diff --git a/.playwright-mcp/page-2026-03-08T22-02-01-741Z.png b/.playwright-mcp/page-2026-03-08T22-02-01-741Z.png deleted file mode 100644 index bcbcf4b..0000000 Binary files a/.playwright-mcp/page-2026-03-08T22-02-01-741Z.png and /dev/null differ diff --git a/.playwright-mcp/page-2026-03-08T22-02-47-973Z.png b/.playwright-mcp/page-2026-03-08T22-02-47-973Z.png deleted file mode 100644 index 5b071d1..0000000 Binary files a/.playwright-mcp/page-2026-03-08T22-02-47-973Z.png and /dev/null differ diff --git a/.playwright-mcp/page-2026-03-08T22-03-28-305Z.png b/.playwright-mcp/page-2026-03-08T22-03-28-305Z.png deleted file mode 100644 index cc70867..0000000 Binary files a/.playwright-mcp/page-2026-03-08T22-03-28-305Z.png and /dev/null differ diff --git a/.playwright-mcp/page-2026-03-08T22-05-01-496Z.png b/.playwright-mcp/page-2026-03-08T22-05-01-496Z.png deleted file mode 100644 index fcffd79..0000000 Binary files a/.playwright-mcp/page-2026-03-08T22-05-01-496Z.png and /dev/null differ diff --git a/.playwright-mcp/page-2026-03-08T22-05-11-433Z.png b/.playwright-mcp/page-2026-03-08T22-05-11-433Z.png deleted file mode 100644 index 07d88f3..0000000 Binary files a/.playwright-mcp/page-2026-03-08T22-05-11-433Z.png and /dev/null differ diff --git a/.playwright-mcp/page-2026-03-08T22-06-34-348Z.png b/.playwright-mcp/page-2026-03-08T22-06-34-348Z.png deleted file mode 100644 index efe09df..0000000 Binary files a/.playwright-mcp/page-2026-03-08T22-06-34-348Z.png and /dev/null differ diff --git a/.playwright-mcp/page-2026-03-08T22-06-46-712Z.png b/.playwright-mcp/page-2026-03-08T22-06-46-712Z.png deleted file mode 100644 index 6d26718..0000000 Binary files a/.playwright-mcp/page-2026-03-08T22-06-46-712Z.png and /dev/null differ diff --git a/.playwright-mcp/page-2026-03-08T22-16-17-928Z.png b/.playwright-mcp/page-2026-03-08T22-16-17-928Z.png deleted file mode 100644 index 5e1a45d..0000000 Binary files a/.playwright-mcp/page-2026-03-08T22-16-17-928Z.png and /dev/null differ diff --git a/.playwright-mcp/page-2026-03-08T22-16-32-040Z.png b/.playwright-mcp/page-2026-03-08T22-16-32-040Z.png deleted file mode 100644 index b39e079..0000000 Binary files a/.playwright-mcp/page-2026-03-08T22-16-32-040Z.png and /dev/null differ diff --git a/.playwright-mcp/page-2026-03-08T22-17-03-001Z.png b/.playwright-mcp/page-2026-03-08T22-17-03-001Z.png deleted file mode 100644 index a29a08e..0000000 Binary files a/.playwright-mcp/page-2026-03-08T22-17-03-001Z.png and /dev/null differ diff --git a/crates/forage-core/src/integrations/router.rs b/crates/forage-core/src/integrations/router.rs index fa2c5e0..28dfa1e 100644 --- a/crates/forage-core/src/integrations/router.rs +++ b/crates/forage-core/src/integrations/router.rs @@ -520,6 +520,7 @@ pub fn format_pipeline_blocks( "RUNNING" => ":arrows_counterclockwise:", "FAILED" => ":x:", "CANCELLED" => ":no_entry_sign:", + "AWAITING_APPROVAL" => ":shield:", _ => ":radio_button:", // PENDING }; @@ -546,6 +547,16 @@ pub fn format_pipeline_blocks( _ => format!("Wait {dur_str}"), } } + "plan" => { + let env = stage.environment.as_deref().unwrap_or("unknown"); + match stage.status.as_str() { + "SUCCEEDED" => format!("Plan approved for `{env}`"), + "RUNNING" => format!("Planning `{env}`"), + "AWAITING_APPROVAL" => format!("Awaiting plan approval for `{env}`"), + "FAILED" => format!("Plan failed for `{env}`"), + _ => format!("Plan `{env}`"), + } + } _ => format!("Stage {}", stage.stage_id), }; @@ -928,6 +939,8 @@ mod tests { error_message: None, wait_until: None, release_ids: vec![], + approval_status: None, + auto_approve: None, }, PipelineRunStageState { stage_id: "s2".into(), @@ -942,6 +955,8 @@ mod tests { error_message: None, wait_until: None, release_ids: vec![], + approval_status: None, + auto_approve: None, }, PipelineRunStageState { stage_id: "s3".into(), @@ -956,6 +971,8 @@ mod tests { error_message: None, wait_until: None, release_ids: vec![], + approval_status: None, + auto_approve: None, }, PipelineRunStageState { stage_id: "s4".into(), @@ -970,6 +987,8 @@ mod tests { error_message: None, wait_until: None, release_ids: vec![], + approval_status: None, + auto_approve: None, }, PipelineRunStageState { stage_id: "s5".into(), @@ -984,6 +1003,8 @@ mod tests { error_message: None, wait_until: None, release_ids: vec![], + approval_status: None, + auto_approve: None, }, ]; @@ -1024,6 +1045,8 @@ mod tests { error_message: Some("OOM killed".into()), wait_until: None, release_ids: vec![], + approval_status: None, + auto_approve: None, }]; let blocks = format_pipeline_blocks(&stages); diff --git a/crates/forage-core/src/platform/mod.rs b/crates/forage-core/src/platform/mod.rs index 609a00e..37b4209 100644 --- a/crates/forage-core/src/platform/mod.rs +++ b/crates/forage-core/src/platform/mod.rs @@ -130,8 +130,8 @@ pub struct DestinationState { pub struct PipelineRunStageState { pub stage_id: String, pub depends_on: Vec, - pub stage_type: String, // "deploy" or "wait" - pub status: String, // "PENDING", "RUNNING", "SUCCEEDED", "FAILED", "CANCELLED" + pub stage_type: String, // "deploy", "wait", or "plan" + pub status: String, // "PENDING", "RUNNING", "SUCCEEDED", "FAILED", "CANCELLED", "AWAITING_APPROVAL" pub environment: Option, pub duration_seconds: Option, pub queued_at: Option, @@ -141,6 +141,10 @@ pub struct PipelineRunStageState { pub wait_until: Option, #[serde(default)] pub release_ids: Vec, + #[serde(default)] + pub approval_status: Option, + #[serde(default)] + pub auto_approve: Option, } /// Combined response from get_destination_states: destinations only. @@ -302,6 +306,7 @@ pub struct PipelineStage { pub enum PipelineStageConfig { Deploy { environment: String }, Wait { duration_seconds: i64 }, + Plan { environment: String, auto_approve: bool }, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -628,6 +633,43 @@ pub trait ForestPlatform: Send + Sync { release_intent_id: &str, target_environment: &str, ) -> Result; + + async fn approve_plan_stage( + &self, + access_token: &str, + release_intent_id: &str, + stage_id: &str, + ) -> Result<(), PlatformError>; + + async fn reject_plan_stage( + &self, + access_token: &str, + release_intent_id: &str, + stage_id: &str, + reason: Option<&str>, + ) -> Result<(), PlatformError>; + + async fn get_plan_output( + &self, + access_token: &str, + release_intent_id: &str, + stage_id: &str, + ) -> Result; +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct PlanOutput { + pub plan_output: String, + pub status: String, + pub outputs: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct PlanDestinationOutput { + pub destination_id: String, + pub destination_name: String, + pub plan_output: String, + pub status: String, } #[cfg(test)] diff --git a/crates/forage-grpc/src/grpc/forest/v1/forest.v1.rs b/crates/forage-grpc/src/grpc/forest/v1/forest.v1.rs index 81938ec..f2b5e18 100644 --- a/crates/forage-grpc/src/grpc/forest/v1/forest.v1.rs +++ b/crates/forage-grpc/src/grpc/forest/v1/forest.v1.rs @@ -654,13 +654,28 @@ pub struct GetPlanOutputRequest { #[prost(string, tag="2")] pub stage_id: ::prost::alloc::string::String, } -#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct GetPlanOutputResponse { + /// deprecated: use outputs #[prost(string, tag="1")] pub plan_output: ::prost::alloc::string::String, /// RUNNING, AWAITING_APPROVAL, APPROVED, REJECTED #[prost(string, tag="2")] pub status: ::prost::alloc::string::String, + #[prost(message, repeated, tag="3")] + pub outputs: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct PlanDestinationOutput { + #[prost(string, tag="1")] + pub destination_id: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub destination_name: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub plan_output: ::prost::alloc::string::String, + /// SUCCEEDED, FAILED, RUNNING, etc. + #[prost(string, tag="4")] + pub status: ::prost::alloc::string::String, } #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct Source { @@ -2813,7 +2828,7 @@ pub struct PolicyEvaluation { #[prost(string, tag="4")] pub reason: ::prost::alloc::string::String, #[prost(message, optional, tag="10")] - pub approval_state: ::core::option::Option, + pub external_approval_state: ::core::option::Option, } // ── CRUD messages ─────────────────────────────────────────────────── @@ -3404,6 +3419,9 @@ pub struct WorkAssignment { /// Full destination configuration including metadata. #[prost(message, optional, tag="6")] pub destination: ::core::option::Option, + /// Execution mode. Defaults to DEPLOY if unset. + #[prost(enumeration="ReleaseMode", tag="7")] + pub mode: i32, } /// Destination configuration sent with the work assignment. #[derive(Clone, PartialEq, ::prost::Message)] @@ -3526,10 +3544,47 @@ pub struct CompleteReleaseRequest { /// Error description when outcome is FAILURE. #[prost(string, tag="3")] pub error_message: ::prost::alloc::string::String, + /// Plan output text when mode was "plan" and outcome is SUCCESS. + /// Stored in release_states.plan_output for UI review. + #[prost(string, optional, tag="4")] + pub plan_output: ::core::option::Option<::prost::alloc::string::String>, } #[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)] pub struct CompleteReleaseResponse { } +/// Execution mode for a work assignment. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum ReleaseMode { + Unspecified = 0, + /// Normal deployment execution. + Deploy = 1, + /// Dry-run / plan only (e.g. terraform plan). Runner should capture + /// plan output and include it in CompleteRelease.plan_output. + Plan = 2, +} +impl ReleaseMode { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "RELEASE_MODE_UNSPECIFIED", + Self::Deploy => "RELEASE_MODE_DEPLOY", + Self::Plan => "RELEASE_MODE_PLAN", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "RELEASE_MODE_UNSPECIFIED" => Some(Self::Unspecified), + "RELEASE_MODE_DEPLOY" => Some(Self::Deploy), + "RELEASE_MODE_PLAN" => Some(Self::Plan), + _ => None, + } + } +} #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum ReleaseOutcome { diff --git a/crates/forage-server/src/forest_client.rs b/crates/forage-server/src/forest_client.rs index 74e43a1..40fa376 100644 --- a/crates/forage-server/src/forest_client.rs +++ b/crates/forage-server/src/forest_client.rs @@ -6,7 +6,7 @@ use forage_core::platform::{ ApprovalDecisionEntry, ApprovalState, Artifact, ArtifactContext, ArtifactDestination, ArtifactRef, ArtifactSource, CreatePolicyInput, CreateReleasePipelineInput, CreateTriggerInput, Destination, DestinationType, Environment, ForestPlatform, NotificationPreference, Organisation, - OrgMember, PipelineStage, PipelineStageConfig, PlatformError, Policy, PolicyConfig, + OrgMember, PipelineStage, PipelineStageConfig, PlanOutput, PlatformError, Policy, PolicyConfig, PolicyEvaluation, ReleasePipeline, Trigger, UpdatePolicyInput, UpdateReleasePipelineInput, UpdateTriggerInput, }; @@ -583,8 +583,8 @@ fn convert_pipeline_stage(s: forage_grpc::PipelineStage) -> PipelineStage { Some(forage_grpc::pipeline_stage::Config::Wait(w)) => { PipelineStageConfig::Wait { duration_seconds: w.duration_seconds } } - Some(forage_grpc::pipeline_stage::Config::Plan(_)) => { - PipelineStageConfig::Deploy { environment: String::new() } + Some(forage_grpc::pipeline_stage::Config::Plan(p)) => { + PipelineStageConfig::Plan { environment: p.environment, auto_approve: p.auto_approve } } None => PipelineStageConfig::Deploy { environment: String::new() }, }; @@ -603,6 +603,7 @@ fn convert_pipeline_stage_state( let stage_type = match forage_grpc::PipelineRunStageType::try_from(s.stage_type) { Ok(forage_grpc::PipelineRunStageType::Deploy) => "deploy", Ok(forage_grpc::PipelineRunStageType::Wait) => "wait", + Ok(forage_grpc::PipelineRunStageType::Plan) => "plan", _ => "unknown", }; let status = match forage_grpc::PipelineRunStageStatus::try_from(s.status) { @@ -611,6 +612,7 @@ fn convert_pipeline_stage_state( Ok(forage_grpc::PipelineRunStageStatus::Succeeded) => "SUCCEEDED", Ok(forage_grpc::PipelineRunStageStatus::Failed) => "FAILED", Ok(forage_grpc::PipelineRunStageStatus::Cancelled) => "CANCELLED", + Ok(forage_grpc::PipelineRunStageStatus::AwaitingApproval) => "AWAITING_APPROVAL", _ => "PENDING", }; forage_core::platform::PipelineRunStageState { @@ -626,6 +628,8 @@ fn convert_pipeline_stage_state( error_message: s.error_message, wait_until: s.wait_until, release_ids: s.release_ids, + approval_status: s.approval_status, + auto_approve: s.auto_approve, } } @@ -663,6 +667,12 @@ fn convert_stages_to_grpc(stages: &[PipelineStage]) -> Vec { + forage_grpc::pipeline_stage::Config::Plan(forage_grpc::PlanStageConfig { + environment: environment.clone(), + auto_approve: *auto_approve, + }) + } }), }) .collect() @@ -1872,6 +1882,81 @@ impl ForestPlatform for GrpcForestClient { .map_err(map_platform_status)?; Ok(convert_approval_state(resp.into_inner().state)) } + + async fn approve_plan_stage( + &self, + access_token: &str, + release_intent_id: &str, + stage_id: &str, + ) -> Result<(), PlatformError> { + let req = platform_authed_request( + access_token, + forage_grpc::ApprovePlanStageRequest { + release_intent_id: release_intent_id.into(), + stage_id: stage_id.into(), + }, + )?; + self.release_client() + .approve_plan_stage(req) + .await + .map_err(map_platform_status)?; + Ok(()) + } + + async fn reject_plan_stage( + &self, + access_token: &str, + release_intent_id: &str, + stage_id: &str, + reason: Option<&str>, + ) -> Result<(), PlatformError> { + let req = platform_authed_request( + access_token, + forage_grpc::RejectPlanStageRequest { + release_intent_id: release_intent_id.into(), + stage_id: stage_id.into(), + reason: reason.map(|s| s.into()), + }, + )?; + self.release_client() + .reject_plan_stage(req) + .await + .map_err(map_platform_status)?; + Ok(()) + } + + async fn get_plan_output( + &self, + access_token: &str, + release_intent_id: &str, + stage_id: &str, + ) -> Result { + let req = platform_authed_request( + access_token, + forage_grpc::GetPlanOutputRequest { + release_intent_id: release_intent_id.into(), + stage_id: stage_id.into(), + }, + )?; + let resp = self + .release_client() + .get_plan_output(req) + .await + .map_err(map_platform_status)?; + let inner = resp.into_inner(); + Ok(PlanOutput { + plan_output: inner.plan_output, + status: inner.status, + outputs: inner.outputs.into_iter().map(|o| { + forage_core::platform::PlanDestinationOutput { + destination_id: o.destination_id, + destination_name: o.destination_name, + plan_output: o.plan_output, + status: o.status, + } + }).collect(), + }) + } } fn convert_policy_evaluation(e: forage_grpc::PolicyEvaluation) -> PolicyEvaluation { @@ -1881,7 +1966,7 @@ fn convert_policy_evaluation(e: forage_grpc::PolicyEvaluation) -> PolicyEvaluati 3 => "approval", _ => "unknown", }; - let approval_state = e.approval_state.map(|s| convert_approval_state(Some(s))); + let approval_state = e.external_approval_state.map(|s| convert_approval_state(Some(s))); PolicyEvaluation { policy_name: e.policy_name, policy_type: policy_type.into(), diff --git a/crates/forage-server/src/main.rs b/crates/forage-server/src/main.rs index 522570a..e7e2a28 100644 --- a/crates/forage-server/src/main.rs +++ b/crates/forage-server/src/main.rs @@ -11,6 +11,7 @@ mod templates; use std::net::SocketAddr; use std::sync::Arc; +use std::time::Duration; use forage_core::session::{FileSessionStore, SessionStore}; use forage_db::PgSessionStore; @@ -54,8 +55,8 @@ fn init_telemetry() { ) .build(); - let otel_layer = tracing_opentelemetry::layer() - .with_tracer(tracer_provider.tracer("forage-server")); + let otel_layer = + tracing_opentelemetry::layer().with_tracer(tracer_provider.tracer("forage-server")); tracing_subscriber::registry() .with(env_filter) @@ -119,7 +120,10 @@ async fn main() -> anyhow::Result<()> { let mut mad = notmad::Mad::builder(); // Session store + integration store: PostgreSQL if DATABASE_URL is set - let (sessions, integration_store): (Arc, Option>); + let (sessions, integration_store): ( + Arc, + Option>, + ); if let Ok(database_url) = std::env::var("DATABASE_URL") { tracing::info!("using PostgreSQL session store"); @@ -129,12 +133,16 @@ async fn main() -> anyhow::Result<()> { let pg_store = Arc::new(PgSessionStore::new(pool.clone())); // Integration store (uses same pool) - let encryption_key = std::env::var("INTEGRATION_ENCRYPTION_KEY") - .unwrap_or_else(|_| { - tracing::warn!("INTEGRATION_ENCRYPTION_KEY not set — using default key (not safe for production)"); - "forage-dev-key-not-for-production!!".to_string() - }); - let pg_integrations = Arc::new(forage_db::PgIntegrationStore::new(pool, encryption_key.into_bytes())); + let encryption_key = std::env::var("INTEGRATION_ENCRYPTION_KEY").unwrap_or_else(|_| { + tracing::warn!( + "INTEGRATION_ENCRYPTION_KEY not set — using default key (not safe for production)" + ); + "forage-dev-key-not-for-production!!".to_string() + }); + let pg_integrations = Arc::new(forage_db::PgIntegrationStore::new( + pool, + encryption_key.into_bytes(), + )); // Session reaper component mad.add(session_reaper::PgSessionReaper { @@ -143,11 +151,15 @@ async fn main() -> anyhow::Result<()> { }); sessions = pg_store; - integration_store = Some(pg_integrations as Arc); + integration_store = + Some(pg_integrations as Arc); } else { let session_dir = std::env::var("SESSION_DIR").unwrap_or_else(|_| "target/sessions".into()); - tracing::info!("using file session store at {session_dir} (set DATABASE_URL for PostgreSQL)"); - let file_store = Arc::new(FileSessionStore::new(&session_dir).expect("failed to create session dir")); + tracing::info!( + "using file session store at {session_dir} (set DATABASE_URL for PostgreSQL)" + ); + let file_store = + Arc::new(FileSessionStore::new(&session_dir).expect("failed to create session dir")); // File session reaper component mad.add(session_reaper::FileSessionReaper { @@ -159,8 +171,13 @@ async fn main() -> anyhow::Result<()> { }; let forest_client = Arc::new(forest_client); - let mut state = AppState::new(template_engine, forest_client.clone(), forest_client.clone(), sessions) - .with_grpc_client(forest_client.clone()); + let mut state = AppState::new( + template_engine, + forest_client.clone(), + forest_client.clone(), + sessions, + ) + .with_grpc_client(forest_client.clone()); // Slack OAuth config (optional, enables "Add to Slack" button) if let (Ok(client_id), Ok(client_secret)) = ( @@ -220,7 +237,9 @@ async fn main() -> anyhow::Result<()> { }); } else { // Fallback: direct dispatch (no durability) - tracing::warn!("NATS_URL not set — using direct notification dispatch (no durability)"); + tracing::warn!( + "NATS_URL not set — using direct notification dispatch (no durability)" + ); mad.add(notification_worker::NotificationListener { grpc: forest_client, store: store.clone(), @@ -234,12 +253,11 @@ async fn main() -> anyhow::Result<()> { } // HTTP server component - mad.add(serve_http::ServeHttp { - addr, - state, - }); + mad.add(serve_http::ServeHttp { addr, state }); - mad.run().await?; + mad.cancellation(Some(Duration::from_secs(10))) + .run() + .await?; Ok(()) } diff --git a/crates/forage-server/src/routes/platform.rs b/crates/forage-server/src/routes/platform.rs index b649739..c6b37ca 100644 --- a/crates/forage-server/src/routes/platform.rs +++ b/crates/forage-server/src/routes/platform.rs @@ -125,6 +125,18 @@ pub fn router() -> Router { post(delete_pipeline), ) .route("/users/{username}", get(user_profile)) + .route( + "/api/orgs/{org}/projects/{project}/plan-stages/{stage_id}/approve", + post(approve_plan_stage_submit), + ) + .route( + "/api/orgs/{org}/projects/{project}/plan-stages/{stage_id}/reject", + post(reject_plan_stage_submit), + ) + .route( + "/api/orgs/{org}/projects/{project}/plan-stages/{stage_id}/output", + get(get_plan_output_api), + ) .route( "/api/orgs/{org}/projects/{project}/timeline", get(timeline_api), @@ -402,7 +414,12 @@ async fn fetch_notifications( if let Some(run_stages) = intent_stages_by_artifact.get(aid) { let sorted = topo_sort_run_stages(run_stages); for rs in sorted { - let display_status = deploy_stage_display_status(rs, &matching_states); + let base_status = deploy_stage_display_status(rs, &matching_states); + let display_status = if rs.stage_type == "plan" && rs.approval_status.as_deref() == Some("AWAITING_APPROVAL") { + "AWAITING_APPROVAL" + } else { + base_status + }; pipeline_stages.push(context! { id => rs.stage_id, stage_type => rs.stage_type, @@ -413,6 +430,7 @@ async fn fetch_notifications( completed_at => rs.completed_at, error_message => rs.error_message, wait_until => rs.wait_until, + approval_status => rs.approval_status, }); } } @@ -895,7 +913,7 @@ async fn artifact_detail( )); } - let (artifact_result, projects, dest_states, release_intents, pipelines) = tokio::join!( + let (artifact_result, projects, dest_states, release_intents, pipelines, environments) = tokio::join!( state .platform_client .get_artifact_by_slug(&session.access_token, &slug), @@ -911,6 +929,9 @@ async fn artifact_detail( state .platform_client .list_release_pipelines(&session.access_token, &org, &project), + state + .platform_client + .list_environments(&session.access_token, &org), ); // Fetch artifact spec after we have the artifact_id (needs artifact_result first). @@ -954,44 +975,62 @@ async fn artifact_detail( .any(|ri| ri.artifact_id == artifact.artifact_id && !ri.stages.is_empty()) }); - // Build pipeline stages from intent data. + // Build pipeline stages from the most recent release intent for this artifact. let mut pipeline_stages: Vec = Vec::new(); - for ri in &release_intents { - if ri.artifact_id == artifact.artifact_id && !ri.stages.is_empty() { - let sorted = topo_sort_run_stages(&ri.stages); - for rs in sorted { - let display_status = deploy_stage_display_status(rs, &matching_states); - pipeline_stages.push(context! { - id => rs.stage_id, - stage_type => rs.stage_type, - environment => rs.environment, - duration_seconds => rs.duration_seconds, - status => display_status, - started_at => rs.started_at, - completed_at => rs.completed_at, - error_message => rs.error_message, - wait_until => rs.wait_until, - }); - } + let latest_intent = release_intents + .iter() + .filter(|ri| ri.artifact_id == artifact.artifact_id && !ri.stages.is_empty()) + .max_by_key(|ri| &ri.created_at); + + if let Some(ri) = latest_intent { + let sorted = topo_sort_run_stages(&ri.stages); + for rs in sorted { + let base_status = deploy_stage_display_status(rs, &matching_states); + let display_status = if rs.stage_type == "plan" && rs.approval_status.as_deref() == Some("AWAITING_APPROVAL") { + "AWAITING_APPROVAL" + } else { + base_status + }; + pipeline_stages.push(context! { + id => rs.stage_id, + stage_type => rs.stage_type, + environment => rs.environment, + duration_seconds => rs.duration_seconds, + status => display_status, + started_at => rs.started_at, + completed_at => rs.completed_at, + error_message => rs.error_message, + wait_until => rs.wait_until, + approval_status => rs.approval_status, + }); } } let has_pipeline = !pipeline_stages.is_empty() || project_has_pipeline; // Fetch policy evaluations for active release intents. - let mut policy_evaluations: Vec = Vec::new(); - let mut release_intent_id_str = String::new(); + struct PolicyEvalEntry { + policy_name: String, + policy_type: String, + passed: bool, + reason: String, + target_environment: String, + approval_state: Option, + } + + let mut raw_evals: Vec = Vec::new(); + let release_intent_id_str = latest_intent + .map(|ri| ri.release_intent_id.clone()) + .unwrap_or_default(); let is_release_author = false; - for ri in &release_intents { - if ri.artifact_id == artifact.artifact_id && !ri.stages.is_empty() { - release_intent_id_str = ri.release_intent_id.clone(); - // Collect unique environments from the pipeline stages. + if let Some(ri) = latest_intent { + { + let mut seen = std::collections::BTreeSet::new(); let environments: Vec = ri .stages .iter() .filter_map(|s| s.environment.clone()) - .collect::>() - .into_iter() + .filter(|e| seen.insert(e.clone())) .collect(); for env in &environments { @@ -1007,40 +1046,55 @@ async fn artifact_detail( .await { for eval in evals { - let approval_state_ctx = eval.approval_state.as_ref().map(|s| { - let decisions: Vec = s - .decisions - .iter() - .map(|d| { - context! { - username => d.username, - decision => d.decision, - comment => d.comment, - decided_at => d.decided_at, - } - }) - .collect(); - context! { - required_approvals => s.required_approvals, - current_approvals => s.current_approvals, - decisions => decisions, - } - }); - policy_evaluations.push(context! { - policy_name => eval.policy_name, - policy_type => eval.policy_type, - passed => eval.passed, - reason => eval.reason, - target_environment => env, - approval_state => approval_state_ctx, + raw_evals.push(PolicyEvalEntry { + policy_name: eval.policy_name, + policy_type: eval.policy_type, + passed: eval.passed, + reason: eval.reason, + target_environment: env.clone(), + approval_state: eval.approval_state, }); } } } - break; // Only one active intent per artifact. } } + raw_evals.sort_by(|a, b| a.policy_type.cmp(&b.policy_type).then(a.policy_name.cmp(&b.policy_name))); + + let policy_evaluations: Vec = raw_evals + .iter() + .map(|eval| { + let approval_state_ctx = eval.approval_state.as_ref().map(|s| { + let decisions: Vec = s + .decisions + .iter() + .map(|d| { + context! { + username => d.username, + decision => d.decision, + comment => d.comment, + decided_at => d.decided_at, + } + }) + .collect(); + context! { + required_approvals => s.required_approvals, + current_approvals => s.current_approvals, + decisions => decisions, + } + }); + context! { + policy_name => eval.policy_name, + policy_type => eval.policy_type, + passed => eval.passed, + reason => eval.reason, + target_environment => eval.target_environment, + approval_state => approval_state_ctx, + } + }) + .collect(); + let current_org_entry = orgs.iter().find(|o| o.name == org); let is_admin = current_org_entry .map(|o| o.role == "owner" || o.role == "admin") @@ -1066,6 +1120,8 @@ async fn artifact_detail( }) .collect(); + let artifact_id_val = artifact.artifact_id.clone(); + let html = state .templates .render( @@ -1127,6 +1183,12 @@ async fn artifact_detail( release_intent_id => &release_intent_id_str, is_release_author => is_release_author, is_admin => is_admin, + artifact_id => &artifact_id_val, + has_active_pipeline => has_pipeline, + environments => warn_default("list_environments", environments) + .iter() + .map(|e| context! { name => e.name }) + .collect::>(), }, ) .map_err(|e| { @@ -2102,6 +2164,10 @@ pub struct ApiPipelineStage { pub wait_until: Option, #[serde(skip_serializing_if = "Option::is_none")] pub blocked_by: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub approval_status: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub auto_approve: Option, } #[derive(Debug, Serialize)] @@ -2287,6 +2353,14 @@ fn build_timeline_json( } else { None }; + // For plan stages, use AWAITING_APPROVAL as display status when appropriate + let display_status = if rs.stage_type == "plan" + && rs.approval_status.as_deref() == Some("AWAITING_APPROVAL") + { + "AWAITING_APPROVAL".to_string() + } else { + display_status + }; stages.push(ApiPipelineStage { id: rs.stage_id.clone(), stage_type: rs.stage_type.clone(), @@ -2298,6 +2372,8 @@ fn build_timeline_json( error_message: rs.error_message.clone(), wait_until: rs.wait_until.clone(), blocked_by, + approval_status: rs.approval_status.clone(), + auto_approve: rs.auto_approve, }); } } @@ -2411,7 +2487,10 @@ fn build_timeline_json( let mut seen_deployed = false; for raw in raw_releases { - let needs_action = raw.release.pipeline_stages.iter().any(|s| s.blocked_by.is_some()); + let needs_action = raw.release.pipeline_stages.iter().any(|s| { + s.blocked_by.is_some() + || (s.stage_type == "plan" && s.status == "AWAITING_APPROVAL") + }); if raw.has_dests || needs_action { if !hidden_buf.is_empty() { let count = hidden_buf.len(); @@ -4758,3 +4837,155 @@ async fn reject_release_submit( .into_response()) } +// ── Plan stage approve / reject / output ───────────────────────────── + +#[derive(Deserialize)] +struct PlanStageForm { + csrf_token: String, + release_intent_id: String, + #[serde(default)] + reason: Option, + #[serde(default)] + redirect_to: Option, +} + +async fn approve_plan_stage_submit( + State(state): State, + session: Session, + headers: axum::http::HeaderMap, + Path((org, _project, stage_id)): Path<(String, String, String)>, + Form(form): Form, +) -> Result { + let orgs = &session.user.orgs; + require_org_membership(&state, orgs, &org)?; + + if form.csrf_token != session.csrf_token { + return Err(approval_error( + &state, + &headers, + StatusCode::FORBIDDEN, + "CSRF validation failed. Please try again.", + )); + } + + state + .platform_client + .approve_plan_stage( + &session.access_token, + &form.release_intent_id, + &stage_id, + ) + .await + .map_err(|e| match e { + forage_core::platform::PlatformError::NotAuthenticated => { + axum::response::Redirect::to("/login").into_response() + } + other => approval_error( + &state, + &headers, + StatusCode::INTERNAL_SERVER_ERROR, + &format!("{other}"), + ), + })?; + + if let Some(redirect) = &form.redirect_to { + Ok(Redirect::to(redirect).into_response()) + } else { + Ok(Json(serde_json::json!({ "ok": true })).into_response()) + } +} + +async fn reject_plan_stage_submit( + State(state): State, + session: Session, + headers: axum::http::HeaderMap, + Path((org, _project, stage_id)): Path<(String, String, String)>, + Form(form): Form, +) -> Result { + let orgs = &session.user.orgs; + require_org_membership(&state, orgs, &org)?; + + if form.csrf_token != session.csrf_token { + return Err(approval_error( + &state, + &headers, + StatusCode::FORBIDDEN, + "CSRF validation failed. Please try again.", + )); + } + + let reason = form.reason.as_deref().and_then(|s| { + let t = s.trim(); + if t.is_empty() { None } else { Some(t.to_string()) } + }); + + state + .platform_client + .reject_plan_stage( + &session.access_token, + &form.release_intent_id, + &stage_id, + reason.as_deref(), + ) + .await + .map_err(|e| match e { + forage_core::platform::PlatformError::NotAuthenticated => { + axum::response::Redirect::to("/login").into_response() + } + other => approval_error( + &state, + &headers, + StatusCode::INTERNAL_SERVER_ERROR, + &format!("{other}"), + ), + })?; + + if let Some(redirect) = &form.redirect_to { + Ok(Redirect::to(redirect).into_response()) + } else { + Ok(Json(serde_json::json!({ "ok": true })).into_response()) + } +} + +#[derive(Deserialize)] +struct PlanOutputQuery { + release_intent_id: String, +} + +async fn get_plan_output_api( + State(state): State, + session: Session, + Path((org, _project, stage_id)): Path<(String, String, String)>, + Query(query): Query, +) -> Result { + let orgs = &session.user.orgs; + require_org_membership(&state, orgs, &org)?; + + let output = state + .platform_client + .get_plan_output( + &session.access_token, + &query.release_intent_id, + &stage_id, + ) + .await + .map_err(|e| { + internal_error(&state, "get plan output", &e) + })?; + + let outputs: Vec = output.outputs.iter().map(|o| { + serde_json::json!({ + "destination_id": o.destination_id, + "destination_name": o.destination_name, + "plan_output": o.plan_output, + "status": o.status, + }) + }).collect(); + + Ok(Json(serde_json::json!({ + "plan_output": output.plan_output, + "status": output.status, + "outputs": outputs, + })) + .into_response()) +} diff --git a/crates/forage-server/src/serve_http.rs b/crates/forage-server/src/serve_http.rs index 077b615..447372a 100644 --- a/crates/forage-server/src/serve_http.rs +++ b/crates/forage-server/src/serve_http.rs @@ -1,5 +1,6 @@ use std::net::SocketAddr; +use anyhow::Context; use notmad::{Component, ComponentInfo, MadError}; use tokio_util::sync::CancellationToken; @@ -20,7 +21,7 @@ impl Component for ServeHttp { let listener = tokio::net::TcpListener::bind(self.addr) .await - .map_err(|e| MadError::Inner(e.into()))?; + .context("failed to listen on port")?; tracing::info!("listening on {}", self.addr); @@ -29,7 +30,7 @@ impl Component for ServeHttp { cancellation_token.cancelled().await; }) .await - .map_err(|e| MadError::Inner(e.into()))?; + .context("failed to run axum server")?; Ok(()) } diff --git a/crates/forage-server/src/test_support.rs b/crates/forage-server/src/test_support.rs index 075599a..6c56643 100644 --- a/crates/forage-server/src/test_support.rs +++ b/crates/forage-server/src/test_support.rs @@ -773,6 +773,38 @@ impl ForestPlatform for MockPlatformClient { decisions: vec![], }) } + + async fn approve_plan_stage( + &self, + _access_token: &str, + _release_intent_id: &str, + _stage_id: &str, + ) -> Result<(), PlatformError> { + Ok(()) + } + + async fn reject_plan_stage( + &self, + _access_token: &str, + _release_intent_id: &str, + _stage_id: &str, + _reason: Option<&str>, + ) -> Result<(), PlatformError> { + Ok(()) + } + + async fn get_plan_output( + &self, + _access_token: &str, + _release_intent_id: &str, + _stage_id: &str, + ) -> Result { + Ok(forage_core::platform::PlanOutput { + plan_output: String::new(), + status: "RUNNING".into(), + outputs: vec![], + }) + } } pub(crate) fn make_templates() -> TemplateEngine { diff --git a/dashboard-after-fix.png b/dashboard-after-fix.png deleted file mode 100644 index 750eb2a..0000000 Binary files a/dashboard-after-fix.png and /dev/null differ diff --git a/frontend/src/ReleaseTimeline.svelte b/frontend/src/ReleaseTimeline.svelte index e4e2728..e4170b0 100644 --- a/frontend/src/ReleaseTimeline.svelte +++ b/frontend/src/ReleaseTimeline.svelte @@ -4,7 +4,7 @@ import { onMount, onDestroy, tick } from "svelte"; import { fetchTimeline, connectSSE, formatElapsed, timeAgo } from "./lib/api.js"; import { envColors, envLaneColor, envBadgeClasses, statusDotColor } from "./lib/colors.js"; - import { pipelineSummary, deployStageLabel, waitStageLabel, STATUS_CONFIG } from "./lib/status.js"; + import { pipelineSummary, deployStageLabel, waitStageLabel, planStageLabel, STATUS_CONFIG } from "./lib/status.js"; // Props from attributes export let org = ""; @@ -96,6 +96,88 @@ } } + // ── Plan stage actions ────────────────────────────────────────── + + let planOutputs = {}; // keyed by "intentId:stageId" + let planOutputLoading = new Set(); + + async function approvePlanStage(release, stage, reject = false) { + const key = `plan:${release.release_intent_id}:${stage.id}`; + if (approving.has(key)) return; + approving.add(key); + approving = approving; + approvalError = null; + + try { + const action = reject ? "reject" : "approve"; + const formData = new URLSearchParams(); + formData.set("csrf_token", csrf); + formData.set("release_intent_id", release.release_intent_id); + + const res = await fetch( + `/api/orgs/${org}/projects/${release.project_name || project}/plan-stages/${stage.id}/${action}`, + { + method: "POST", + body: formData, + credentials: "same-origin", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + "Accept": "application/json", + }, + } + ); + if (res.ok) { + await refreshData(); + } else { + const text = await res.text().catch(() => ""); + let msg; + try { msg = JSON.parse(text).error; } catch {} + approvalError = msg || `Plan ${action} failed (${res.status})`; + setTimeout(() => { approvalError = null; }, 8000); + } + } catch (err) { + approvalError = err.message || "Plan action failed"; + setTimeout(() => { approvalError = null; }, 8000); + } finally { + approving.delete(key); + approving = approving; + } + } + + async function viewPlanOutput(release, stage) { + const key = `${release.release_intent_id}:${stage.id}`; + if (planOutputLoading.has(key)) return; + if (planOutputs[key]) { + // Toggle off + delete planOutputs[key]; + planOutputs = planOutputs; + return; + } + planOutputLoading.add(key); + planOutputLoading = planOutputLoading; + + try { + const res = await fetch( + `/api/orgs/${org}/projects/${release.project_name || project}/plan-stages/${stage.id}/output?release_intent_id=${encodeURIComponent(release.release_intent_id)}`, + { credentials: "same-origin", headers: { "Accept": "application/json" } } + ); + if (res.ok) { + const data = await res.json(); + planOutputs[key] = data; + planOutputs = planOutputs; + } else { + approvalError = `Failed to load plan output (${res.status})`; + setTimeout(() => { approvalError = null; }, 8000); + } + } catch (err) { + approvalError = err.message || "Failed to load plan output"; + setTimeout(() => { approvalError = null; }, 8000); + } finally { + planOutputLoading.delete(key); + planOutputLoading = planOutputLoading; + } + } + // ── Data fetching ──────────────────────────────────────────────── // Debounce re-fetches: multiple SSE events within 300ms only trigger one fetch @@ -428,6 +510,21 @@ } } + // Normalize plan stage status: the API returns status="RUNNING" with + // approval_status="AWAITINGAPPROVAL" (no underscore, Debug format from Rust). + // Map this to a single effective status for template rendering. + function effectiveStatus(stage) { + if (stage.stage_type === "plan" && stage.approval_status && + (stage.approval_status === "AWAITINGAPPROVAL" || stage.approval_status === "AWAITING_APPROVAL")) { + return "AWAITING_APPROVAL"; + } + return stage.status; + } + + function isPlanAwaiting(stage) { + return stage.stage_type === "plan" && effectiveStatus(stage) === "AWAITING_APPROVAL"; + } + $: laneCount = lanes.length; $: gutterWidth = laneCount * (BAR_WIDTH + BAR_GAP) + 8; @@ -559,6 +656,18 @@ {/if} + {#if stage.stage_type === "plan" && isPlanAwaiting(stage) && release.release_intent_id && csrf} + {@const planBadge = envBadgeClasses(stage.environment || "")} + + {stage.environment} plan + + + + {/if} {#if stage.blocked_by && release.release_intent_id && csrf} {#if isAuthor(release) && isAdmin()} + + {/if} + {#if (stageStatus === "AWAITING_APPROVAL" || stageStatus === "SUCCEEDED" || stageStatus === "FAILED") && release.release_intent_id} + + {/if} {/if} - {#if stage.started_at && (stage.status === "RUNNING" || stage.status === "QUEUED" || stage.completed_at)} + {#if stage.started_at && (stageStatus === "RUNNING" || stageStatus === "QUEUED" || stageStatus === "AWAITING_APPROVAL" || stage.completed_at)} {elapsedStr(stage.started_at, stage.completed_at, stage.status)} {/if} @@ -667,6 +807,28 @@ pipeline + {#if stage.stage_type === "plan" && planOutputs[`${release.release_intent_id}:${stage.id}`]} + {@const planData = planOutputs[`${release.release_intent_id}:${stage.id}`]} +
+
+ Plan output + {planData.status} +
+ {#if planData.outputs && planData.outputs.length > 0} + {#each planData.outputs as destOutput (destOutput.destination_id)} +
+
+ {destOutput.destination_name} + {destOutput.status} +
+
{destOutput.plan_output || "(no output)"}
+
+ {/each} + {:else} +
{planData.plan_output || "(no output)"}
+ {/if} +
+ {/if} {/each} {/if} diff --git a/frontend/src/lib/status.js b/frontend/src/lib/status.js index fdedf85..1a773c4 100644 --- a/frontend/src/lib/status.js +++ b/frontend/src/lib/status.js @@ -25,9 +25,11 @@ export function pipelineSummary(stages) { } let anyApprovalBlocked = stages.some(s => s.blocked_by); + let anyPlanAwaiting = stages.some(s => s.stage_type === "plan" && (s.status === "AWAITING_APPROVAL" || s.approval_status === "AWAITINGAPPROVAL" || s.approval_status === "AWAITING_APPROVAL")); if (allDone) return { label: "Pipeline complete", color: "text-gray-600", icon: "check-circle", iconColor: "text-green-500", done, total }; if (anyFailed) return { label: "Pipeline failed", color: "text-red-600", icon: "x-circle", iconColor: "text-red-500", done, total }; + if (anyPlanAwaiting) return { label: "Awaiting plan approval", color: "text-purple-700", icon: "shield", iconColor: "text-purple-500", done, total }; if (anyApprovalBlocked) return { label: "Awaiting approval", color: "text-emerald-700", icon: "shield", iconColor: "text-emerald-500", done, total }; if (anyWaiting) return { label: "Waiting for time window", color: "text-yellow-700", icon: "clock", iconColor: "text-yellow-500", done, total }; if (anyRunning) return { label: "Deploying to", color: "text-yellow-700", icon: "pulse", iconColor: "text-yellow-500", done, total }; @@ -64,3 +66,14 @@ export function deployStageLabel(status) { default: return "Deploy to"; } } + +export function planStageLabel(status) { + switch (status) { + case "SUCCEEDED": return "Plan approved"; + case "RUNNING": return "Planning"; + case "AWAITING_APPROVAL": return "Awaiting plan approval"; + case "FAILED": return "Plan failed"; + case "CANCELLED": return "Plan cancelled"; + default: return "Plan"; + } +} diff --git a/interface/proto/forest/v1/policies.proto b/interface/proto/forest/v1/policies.proto index 509ad5e..90f105b 100644 --- a/interface/proto/forest/v1/policies.proto +++ b/interface/proto/forest/v1/policies.proto @@ -76,7 +76,7 @@ message PolicyEvaluation { bool passed = 3; // Human-readable explanation when blocked string reason = 4; - optional ExternalApprovalState approval_state = 10; + optional ExternalApprovalState external_approval_state = 10; } // ── CRUD messages ─────────────────────────────────────────────────── diff --git a/interface/proto/forest/v1/releases.proto b/interface/proto/forest/v1/releases.proto index 9f372b1..4ac58f9 100644 --- a/interface/proto/forest/v1/releases.proto +++ b/interface/proto/forest/v1/releases.proto @@ -297,8 +297,16 @@ message GetPlanOutputRequest { string stage_id = 2; } message GetPlanOutputResponse { - string plan_output = 1; - string status = 2; // RUNNING, AWAITING_APPROVAL, APPROVED, REJECTED + string plan_output = 1; // deprecated: use outputs + string status = 2; // RUNNING, AWAITING_APPROVAL, APPROVED, REJECTED + repeated PlanDestinationOutput outputs = 3; +} + +message PlanDestinationOutput { + string destination_id = 1; + string destination_name = 2; + string plan_output = 3; + string status = 4; // SUCCEEDED, FAILED, RUNNING, etc. } service ReleaseService { diff --git a/interface/proto/forest/v1/runner.proto b/interface/proto/forest/v1/runner.proto index ac9a275..6859962 100644 --- a/interface/proto/forest/v1/runner.proto +++ b/interface/proto/forest/v1/runner.proto @@ -99,6 +99,16 @@ message RegisterAck { string reason = 3; } +// Execution mode for a work assignment. +enum ReleaseMode { + RELEASE_MODE_UNSPECIFIED = 0; + // Normal deployment execution. + RELEASE_MODE_DEPLOY = 1; + // Dry-run / plan only (e.g. terraform plan). Runner should capture + // plan output and include it in CompleteRelease.plan_output. + RELEASE_MODE_PLAN = 2; +} + // Work assignment pushed to a runner when a matching release is available. message WorkAssignment { // Scoped opaque auth token. Use this for GetReleaseFiles, PushLogs, @@ -111,6 +121,8 @@ message WorkAssignment { string destination_id = 5; // Full destination configuration including metadata. DestinationInfo destination = 6; + // Execution mode. Defaults to DEPLOY if unset. + ReleaseMode mode = 7; } // Destination configuration sent with the work assignment. @@ -201,6 +213,9 @@ message CompleteReleaseRequest { ReleaseOutcome outcome = 2; // Error description when outcome is FAILURE. string error_message = 3; + // Plan output text when mode was "plan" and outcome is SUCCESS. + // Stored in release_states.plan_output for UI review. + optional string plan_output = 4; } enum ReleaseOutcome { diff --git a/policies-with-approval.png b/policies-with-approval.png deleted file mode 100644 index 8946458..0000000 Binary files a/policies-with-approval.png and /dev/null differ diff --git a/project-overview-hidden.png b/project-overview-hidden.png deleted file mode 100644 index af9ed80..0000000 Binary files a/project-overview-hidden.png and /dev/null differ diff --git a/project-overview.png b/project-overview.png deleted file mode 100644 index cc4fd5b..0000000 Binary files a/project-overview.png and /dev/null differ diff --git a/static/css/style.css b/static/css/style.css index f756af8..eeffcca 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -1,2 +1,2 @@ /*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */ -@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-200:oklch(88.5% .062 18.334);--color-red-300:oklch(80.8% .114 19.571);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-red-800:oklch(44.4% .177 26.899);--color-orange-100:oklch(95.4% .038 75.164);--color-orange-400:oklch(75% .183 55.934);--color-orange-500:oklch(70.5% .213 47.604);--color-orange-600:oklch(64.6% .222 41.116);--color-orange-700:oklch(55.3% .195 38.402);--color-orange-800:oklch(47% .157 37.304);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-100:oklch(96.2% .059 95.617);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-300:oklch(87.9% .169 91.605);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-600:oklch(66.6% .179 58.318);--color-amber-700:oklch(55.5% .163 48.998);--color-amber-800:oklch(47.3% .137 46.201);--color-yellow-50:oklch(98.7% .026 102.212);--color-yellow-100:oklch(97.3% .071 103.193);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-500:oklch(79.5% .184 86.047);--color-yellow-600:oklch(68.1% .162 75.834);--color-yellow-700:oklch(55.4% .135 66.442);--color-yellow-800:oklch(47.6% .114 61.907);--color-green-50:oklch(98.2% .018 155.826);--color-green-100:oklch(96.2% .044 156.743);--color-green-200:oklch(92.5% .084 155.995);--color-green-300:oklch(87.1% .15 154.449);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-green-600:oklch(62.7% .194 149.214);--color-green-700:oklch(52.7% .154 150.069);--color-green-800:oklch(44.8% .119 151.328);--color-emerald-100:oklch(95% .052 163.051);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-700:oklch(50.8% .118 165.612);--color-blue-50:oklch(97% .014 254.604);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-200:oklch(88.2% .059 254.128);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-blue-800:oklch(42.4% .199 265.638);--color-indigo-100:oklch(93% .034 272.788);--color-indigo-700:oklch(45.7% .24 277.023);--color-violet-100:oklch(94.3% .029 294.588);--color-violet-500:oklch(60.6% .25 292.717);--color-violet-600:oklch(54.1% .281 293.009);--color-violet-700:oklch(49.1% .27 292.581);--color-violet-800:oklch(43.2% .232 292.759);--color-purple-50:oklch(97.7% .014 308.299);--color-purple-100:oklch(94.6% .033 307.174);--color-purple-200:oklch(90.2% .063 306.703);--color-purple-400:oklch(71.4% .203 305.504);--color-purple-700:oklch(49.6% .265 301.924);--color-purple-800:oklch(43.8% .218 303.724);--color-pink-100:oklch(94.8% .028 342.258);--color-pink-500:oklch(65.6% .241 354.308);--color-pink-800:oklch(45.9% .187 3.815);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-gray-950:oklch(13% .028 261.692);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-md:28rem;--container-lg:32rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--container-5xl:64rem;--container-6xl:72rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5 / 2.25);--text-5xl:3rem;--text-5xl--line-height:1;--text-6xl:3.75rem;--text-6xl--line-height:1;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wide:.025em;--leading-tight:1.25;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.end\!{inset-inline-end:var(--spacing)!important}.-top-3{top:calc(var(--spacing) * -3)}.top-0\.5{top:calc(var(--spacing) * .5)}.top-1\.5{top:calc(var(--spacing) * 1.5)}.top-\[3px\]{top:3px}.right-1\.5{right:calc(var(--spacing) * 1.5)}.left-0{left:calc(var(--spacing) * 0)}.left-0\.5{left:calc(var(--spacing) * .5)}.left-4{left:calc(var(--spacing) * 4)}.left-\[3px\]{left:3px}.left-\[calc\(100\%-1\.125rem\)\]{left:calc(100% - 1.125rem)}.z-20{z-index:20}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.my-8{margin-block:calc(var(--spacing) * 8)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mt-8{margin-top:calc(var(--spacing) * 8)}.mt-10{margin-top:calc(var(--spacing) * 10)}.mt-12{margin-top:calc(var(--spacing) * 12)}.mt-auto{margin-top:auto}.mr-1\.5{margin-right:calc(var(--spacing) * 1.5)}.-mb-px{margin-bottom:-1px}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.mb-8{margin-bottom:calc(var(--spacing) * 8)}.mb-12{margin-bottom:calc(var(--spacing) * 12)}.ml-0\.5{margin-left:calc(var(--spacing) * .5)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-4{margin-left:calc(var(--spacing) * 4)}.ml-6{margin-left:calc(var(--spacing) * 6)}.ml-7{margin-left:calc(var(--spacing) * 7)}.ml-auto{margin-left:auto}.scrollbar-none{-ms-overflow-style:none;scrollbar-width:none}.scrollbar-none::-webkit-scrollbar{display:none}.mobile-only{display:none}@media (max-width:39.999rem){.mobile-only{display:block}}.block{display:block}@media (max-width:39.999rem){.desktop-only{display:none}}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-2\.5{height:calc(var(--spacing) * 2.5)}.h-3{height:calc(var(--spacing) * 3)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-10{height:calc(var(--spacing) * 10)}.h-12{height:calc(var(--spacing) * 12)}.h-14{height:calc(var(--spacing) * 14)}.h-16{height:calc(var(--spacing) * 16)}.h-20{height:calc(var(--spacing) * 20)}.min-h-screen{min-height:100vh}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-2\.5{width:calc(var(--spacing) * 2.5)}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-10{width:calc(var(--spacing) * 10)}.w-12{width:calc(var(--spacing) * 12)}.w-14{width:calc(var(--spacing) * 14)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-24{width:calc(var(--spacing) * 24)}.w-32{width:calc(var(--spacing) * 32)}.w-48{width:calc(var(--spacing) * 48)}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-\[200px\]{max-width:200px}.max-w-\[250px\]{max-width:250px}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-\[140px\]{min-width:140px}.min-w-full{min-width:100%}.flex-1{flex:1}.flex-shrink{flex-shrink:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.grow{flex-grow:1}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize{resize:both}.resize-y{resize:vertical}.list-none{list-style-type:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-8{gap:calc(var(--spacing) * 8)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-6{column-gap:calc(var(--spacing) * 6)}.gap-y-2{row-gap:calc(var(--spacing) * 2)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-gray-100>:not(:last-child)){border-color:var(--color-gray-100)}:where(.divide-gray-200>:not(:last-child)){border-color:var(--color-gray-200)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-amber-200{border-color:var(--color-amber-200)}.border-amber-300{border-color:var(--color-amber-300)}.border-blue-200{border-color:var(--color-blue-200)}.border-gray-50{border-color:var(--color-gray-50)}.border-gray-100{border-color:var(--color-gray-100)}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-300{border-color:var(--color-gray-300)}.border-gray-900{border-color:var(--color-gray-900)}.border-green-200{border-color:var(--color-green-200)}.border-green-300{border-color:var(--color-green-300)}.border-purple-200{border-color:var(--color-purple-200)}.border-red-200{border-color:var(--color-red-200)}.border-red-300{border-color:var(--color-red-300)}.border-transparent{border-color:#0000}.border-t-gray-600{border-top-color:var(--color-gray-600)}.bg-\[\#4A154B\]{background-color:#4a154b}.bg-amber-50{background-color:var(--color-amber-50)}.bg-amber-100{background-color:var(--color-amber-100)}.bg-blue-50{background-color:var(--color-blue-50)}.bg-blue-100{background-color:var(--color-blue-100)}.bg-blue-400{background-color:var(--color-blue-400)}.bg-emerald-100{background-color:var(--color-emerald-100)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-50\/50{background-color:#f9fafb80}@supports (color:color-mix(in lab, red, red)){.bg-gray-50\/50{background-color:color-mix(in oklab, var(--color-gray-50) 50%, transparent)}}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-200{background-color:var(--color-gray-200)}.bg-gray-300{background-color:var(--color-gray-300)}.bg-gray-400{background-color:var(--color-gray-400)}.bg-gray-900{background-color:var(--color-gray-900)}.bg-gray-950{background-color:var(--color-gray-950)}.bg-green-50{background-color:var(--color-green-50)}.bg-green-100{background-color:var(--color-green-100)}.bg-green-500{background-color:var(--color-green-500)}.bg-green-600{background-color:var(--color-green-600)}.bg-indigo-100{background-color:var(--color-indigo-100)}.bg-orange-100{background-color:var(--color-orange-100)}.bg-orange-400{background-color:var(--color-orange-400)}.bg-orange-500{background-color:var(--color-orange-500)}.bg-pink-100{background-color:var(--color-pink-100)}.bg-pink-500{background-color:var(--color-pink-500)}.bg-purple-50{background-color:var(--color-purple-50)}.bg-purple-100{background-color:var(--color-purple-100)}.bg-red-50{background-color:var(--color-red-50)}.bg-red-500{background-color:var(--color-red-500)}.bg-red-600{background-color:var(--color-red-600)}.bg-violet-100{background-color:var(--color-violet-100)}.bg-violet-500{background-color:var(--color-violet-500)}.bg-white{background-color:var(--color-white)}.bg-yellow-50{background-color:var(--color-yellow-50)}.bg-yellow-100{background-color:var(--color-yellow-100)}.bg-yellow-400{background-color:var(--color-yellow-400)}.bg-yellow-500{background-color:var(--color-yellow-500)}.p-1{padding:calc(var(--spacing) * 1)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.p-12{padding:calc(var(--spacing) * 12)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-10{padding-block:calc(var(--spacing) * 10)}.py-12{padding-block:calc(var(--spacing) * 12)}.py-16{padding-block:calc(var(--spacing) * 16)}.pt-0{padding-top:calc(var(--spacing) * 0)}.pt-1{padding-top:calc(var(--spacing) * 1)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-6{padding-top:calc(var(--spacing) * 6)}.pt-8{padding-top:calc(var(--spacing) * 8)}.pt-12{padding-top:calc(var(--spacing) * 12)}.pt-16{padding-top:calc(var(--spacing) * 16)}.pt-24{padding-top:calc(var(--spacing) * 24)}.pr-1{padding-right:calc(var(--spacing) * 1)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-8{padding-bottom:calc(var(--spacing) * 8)}.pb-12{padding-bottom:calc(var(--spacing) * 12)}.pb-16{padding-bottom:calc(var(--spacing) * 16)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}.text-6xl{font-size:var(--text-6xl);line-height:var(--tw-leading,var(--text-6xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-amber-400{color:var(--color-amber-400)}.text-amber-500{color:var(--color-amber-500)}.text-amber-600{color:var(--color-amber-600)}.text-amber-700{color:var(--color-amber-700)}.text-amber-800{color:var(--color-amber-800)}.text-blue-400{color:var(--color-blue-400)}.text-blue-600{color:var(--color-blue-600)}.text-blue-700{color:var(--color-blue-700)}.text-blue-800{color:var(--color-blue-800)}.text-emerald-500{color:var(--color-emerald-500)}.text-emerald-700{color:var(--color-emerald-700)}.text-gray-300{color:var(--color-gray-300)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-gray-800{color:var(--color-gray-800)}.text-gray-900{color:var(--color-gray-900)}.text-green-400{color:var(--color-green-400)}.text-green-500{color:var(--color-green-500)}.text-green-600{color:var(--color-green-600)}.text-green-700{color:var(--color-green-700)}.text-green-800{color:var(--color-green-800)}.text-indigo-700{color:var(--color-indigo-700)}.text-orange-500{color:var(--color-orange-500)}.text-orange-600{color:var(--color-orange-600)}.text-orange-700{color:var(--color-orange-700)}.text-orange-800{color:var(--color-orange-800)}.text-pink-800{color:var(--color-pink-800)}.text-purple-400{color:var(--color-purple-400)}.text-purple-700{color:var(--color-purple-700)}.text-purple-800{color:var(--color-purple-800)}.text-red-400{color:var(--color-red-400)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-red-700{color:var(--color-red-700)}.text-violet-600{color:var(--color-violet-600)}.text-violet-700{color:var(--color-violet-700)}.text-violet-800{color:var(--color-violet-800)}.text-white{color:var(--color-white)}.text-yellow-500{color:var(--color-yellow-500)}.text-yellow-600{color:var(--color-yellow-600)}.text-yellow-700{color:var(--color-yellow-700)}.text-yellow-800{color:var(--color-yellow-800)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.underline{text-decoration-line:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-75{opacity:.75}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.select-all{-webkit-user-select:all;user-select:all}.select-none{-webkit-user-select:none;user-select:none}.group-open\:hidden:is(:where(.group):is([open],:popover-open,:open) *){display:none}.group-open\:inline:is(:where(.group):is([open],:popover-open,:open) *){display:inline}.group-open\:rotate-90:is(:where(.group):is([open],:popover-open,:open) *){rotate:90deg}@media (hover:hover){.group-hover\:border-gray-300:is(:where(.group):hover *){border-color:var(--color-gray-300)}.group-hover\:text-gray-500:is(:where(.group):hover *){color:var(--color-gray-500)}.group-hover\:text-violet-700:is(:where(.group):hover *){color:var(--color-violet-700)}}.first\:rounded-t-lg:first-child{border-top-left-radius:var(--radius-lg);border-top-right-radius:var(--radius-lg)}.last\:rounded-b-lg:last-child{border-bottom-right-radius:var(--radius-lg);border-bottom-left-radius:var(--radius-lg)}@media (hover:hover){.hover\:border-gray-300:hover{border-color:var(--color-gray-300)}.hover\:border-gray-400:hover{border-color:var(--color-gray-400)}.hover\:bg-amber-100:hover{background-color:var(--color-amber-100)}.hover\:bg-amber-200:hover{background-color:var(--color-amber-200)}.hover\:bg-gray-50:hover{background-color:var(--color-gray-50)}.hover\:bg-gray-800:hover{background-color:var(--color-gray-800)}.hover\:bg-green-50:hover{background-color:var(--color-green-50)}.hover\:bg-green-700:hover{background-color:var(--color-green-700)}.hover\:bg-red-50:hover{background-color:var(--color-red-50)}.hover\:bg-red-700:hover{background-color:var(--color-red-700)}.hover\:text-black:hover{color:var(--color-black)}.hover\:text-gray-600:hover{color:var(--color-gray-600)}.hover\:text-gray-700:hover{color:var(--color-gray-700)}.hover\:text-gray-900:hover{color:var(--color-gray-900)}.hover\:text-green-700:hover{color:var(--color-green-700)}.hover\:text-red-500:hover{color:var(--color-red-500)}.hover\:text-red-600:hover{color:var(--color-red-600)}.hover\:text-red-800:hover{color:var(--color-red-800)}.hover\:underline:hover{text-decoration-line:underline}.hover\:shadow-sm:hover{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}}.focus\:border-transparent:focus{border-color:#0000}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-gray-400:focus{--tw-ring-color:var(--color-gray-400)}.focus\:ring-gray-900:focus{--tw-ring-color:var(--color-gray-900)}.focus\:ring-green-500:focus{--tw-ring-color:var(--color-green-500)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.disabled\:opacity-50:disabled{opacity:.5}.has-\[\:checked\]\:border-blue-500:has(:checked){border-color:var(--color-blue-500)}.has-\[\:checked\]\:bg-blue-50:has(:checked){background-color:var(--color-blue-50)}@media (min-width:40rem){.sm\:flex{display:flex}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}.sm\:items-end{align-items:flex-end}}@media (min-width:48rem){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}}@media (prefers-color-scheme:dark){:root,:host{--color-white:oklch(14.5% .015 260);--color-black:oklch(98% .002 248);--color-gray-50:oklch(17.5% .02 260);--color-gray-100:oklch(21% .024 265);--color-gray-200:oklch(27.8% .025 257);--color-gray-300:oklch(37.3% .025 260);--color-gray-400:oklch(55.1% .02 264);--color-gray-500:oklch(60% .02 264);--color-gray-600:oklch(70.7% .017 261);--color-gray-700:oklch(80% .012 258);--color-gray-800:oklch(87.2% .008 258);--color-gray-900:oklch(93% .005 265);--color-gray-950:oklch(96.7% .003 265);--color-green-50:oklch(20% .04 155);--color-green-100:oklch(25% .06 155);--color-green-200:oklch(30% .08 155);--color-green-300:oklch(42% .12 154);--color-green-700:oklch(75% .15 150);--color-green-800:oklch(80% .12 150);--color-red-50:oklch(22% .04 17);--color-red-200:oklch(32% .06 18);--color-red-600:oklch(65% .2 27);--color-red-700:oklch(72% .18 27);--color-red-800:oklch(77% .15 27);--color-blue-100:oklch(22% .04 255);--color-blue-600:oklch(62% .2 263);--color-blue-700:oklch(72% .17 264);--color-blue-800:oklch(77% .15 265);--color-orange-100:oklch(25% .05 75);--color-orange-800:oklch(78% .13 37);--color-yellow-100:oklch(25% .06 103);--color-yellow-700:oklch(72% .12 66);--color-yellow-800:oklch(77% .1 62);--color-violet-100:oklch(22% .04 295);--color-violet-200:oklch(28% .06 294);--color-violet-400:oklch(45% .14 293);--color-violet-600:oklch(60% .2 293);--color-violet-800:oklch(75% .18 293);--color-purple-100:oklch(22% .04 307);--color-purple-800:oklch(75% .17 304);--color-pink-100:oklch(22% .04 342);--color-pink-800:oklch(75% .15 4);--color-amber-400:oklch(80% .17 84)}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}} \ No newline at end of file +@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-200:oklch(88.5% .062 18.334);--color-red-300:oklch(80.8% .114 19.571);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-red-800:oklch(44.4% .177 26.899);--color-orange-100:oklch(95.4% .038 75.164);--color-orange-400:oklch(75% .183 55.934);--color-orange-500:oklch(70.5% .213 47.604);--color-orange-600:oklch(64.6% .222 41.116);--color-orange-700:oklch(55.3% .195 38.402);--color-orange-800:oklch(47% .157 37.304);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-100:oklch(96.2% .059 95.617);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-300:oklch(87.9% .169 91.605);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-600:oklch(66.6% .179 58.318);--color-amber-700:oklch(55.5% .163 48.998);--color-amber-800:oklch(47.3% .137 46.201);--color-yellow-50:oklch(98.7% .026 102.212);--color-yellow-100:oklch(97.3% .071 103.193);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-500:oklch(79.5% .184 86.047);--color-yellow-600:oklch(68.1% .162 75.834);--color-yellow-700:oklch(55.4% .135 66.442);--color-yellow-800:oklch(47.6% .114 61.907);--color-green-50:oklch(98.2% .018 155.826);--color-green-100:oklch(96.2% .044 156.743);--color-green-200:oklch(92.5% .084 155.995);--color-green-300:oklch(87.1% .15 154.449);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-green-600:oklch(62.7% .194 149.214);--color-green-700:oklch(52.7% .154 150.069);--color-green-800:oklch(44.8% .119 151.328);--color-emerald-100:oklch(95% .052 163.051);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-700:oklch(50.8% .118 165.612);--color-blue-50:oklch(97% .014 254.604);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-200:oklch(88.2% .059 254.128);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-blue-800:oklch(42.4% .199 265.638);--color-indigo-100:oklch(93% .034 272.788);--color-indigo-700:oklch(45.7% .24 277.023);--color-violet-100:oklch(94.3% .029 294.588);--color-violet-500:oklch(60.6% .25 292.717);--color-violet-600:oklch(54.1% .281 293.009);--color-violet-700:oklch(49.1% .27 292.581);--color-violet-800:oklch(43.2% .232 292.759);--color-purple-50:oklch(97.7% .014 308.299);--color-purple-100:oklch(94.6% .033 307.174);--color-purple-200:oklch(90.2% .063 306.703);--color-purple-400:oklch(71.4% .203 305.504);--color-purple-500:oklch(62.7% .265 303.9);--color-purple-600:oklch(55.8% .288 302.321);--color-purple-700:oklch(49.6% .265 301.924);--color-purple-800:oklch(43.8% .218 303.724);--color-pink-100:oklch(94.8% .028 342.258);--color-pink-500:oklch(65.6% .241 354.308);--color-pink-800:oklch(45.9% .187 3.815);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-gray-950:oklch(13% .028 261.692);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-md:28rem;--container-lg:32rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--container-5xl:64rem;--container-6xl:72rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5 / 2.25);--text-5xl:3rem;--text-5xl--line-height:1;--text-6xl:3.75rem;--text-6xl--line-height:1;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wide:.025em;--leading-tight:1.25;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.end\!{inset-inline-end:var(--spacing)!important}.-top-3{top:calc(var(--spacing) * -3)}.top-0\.5{top:calc(var(--spacing) * .5)}.top-1\.5{top:calc(var(--spacing) * 1.5)}.top-\[3px\]{top:3px}.right-1\.5{right:calc(var(--spacing) * 1.5)}.left-0{left:calc(var(--spacing) * 0)}.left-0\.5{left:calc(var(--spacing) * .5)}.left-4{left:calc(var(--spacing) * 4)}.left-\[3px\]{left:3px}.left-\[calc\(100\%-1\.125rem\)\]{left:calc(100% - 1.125rem)}.z-20{z-index:20}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.my-8{margin-block:calc(var(--spacing) * 8)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mt-8{margin-top:calc(var(--spacing) * 8)}.mt-10{margin-top:calc(var(--spacing) * 10)}.mt-12{margin-top:calc(var(--spacing) * 12)}.mt-auto{margin-top:auto}.mr-1\.5{margin-right:calc(var(--spacing) * 1.5)}.-mb-px{margin-bottom:-1px}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.mb-8{margin-bottom:calc(var(--spacing) * 8)}.mb-12{margin-bottom:calc(var(--spacing) * 12)}.ml-0\.5{margin-left:calc(var(--spacing) * .5)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-4{margin-left:calc(var(--spacing) * 4)}.ml-6{margin-left:calc(var(--spacing) * 6)}.ml-7{margin-left:calc(var(--spacing) * 7)}.ml-auto{margin-left:auto}.scrollbar-none{-ms-overflow-style:none;scrollbar-width:none}.scrollbar-none::-webkit-scrollbar{display:none}.mobile-only{display:none}@media (max-width:39.999rem){.mobile-only{display:block}}.block{display:block}@media (max-width:39.999rem){.desktop-only{display:none}}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-2\.5{height:calc(var(--spacing) * 2.5)}.h-3{height:calc(var(--spacing) * 3)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-10{height:calc(var(--spacing) * 10)}.h-12{height:calc(var(--spacing) * 12)}.h-14{height:calc(var(--spacing) * 14)}.h-16{height:calc(var(--spacing) * 16)}.h-20{height:calc(var(--spacing) * 20)}.max-h-48{max-height:calc(var(--spacing) * 48)}.max-h-64{max-height:calc(var(--spacing) * 64)}.min-h-screen{min-height:100vh}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-2\.5{width:calc(var(--spacing) * 2.5)}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-10{width:calc(var(--spacing) * 10)}.w-12{width:calc(var(--spacing) * 12)}.w-14{width:calc(var(--spacing) * 14)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-24{width:calc(var(--spacing) * 24)}.w-32{width:calc(var(--spacing) * 32)}.w-48{width:calc(var(--spacing) * 48)}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-\[200px\]{max-width:200px}.max-w-\[250px\]{max-width:250px}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-\[140px\]{min-width:140px}.min-w-full{min-width:100%}.flex-1{flex:1}.flex-shrink{flex-shrink:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.grow{flex-grow:1}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize{resize:both}.resize-y{resize:vertical}.list-none{list-style-type:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-8{gap:calc(var(--spacing) * 8)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-6{column-gap:calc(var(--spacing) * 6)}.gap-y-2{row-gap:calc(var(--spacing) * 2)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-gray-100>:not(:last-child)){border-color:var(--color-gray-100)}:where(.divide-gray-200>:not(:last-child)){border-color:var(--color-gray-200)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-amber-200{border-color:var(--color-amber-200)}.border-amber-300{border-color:var(--color-amber-300)}.border-blue-200{border-color:var(--color-blue-200)}.border-gray-50{border-color:var(--color-gray-50)}.border-gray-100{border-color:var(--color-gray-100)}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-300{border-color:var(--color-gray-300)}.border-gray-900{border-color:var(--color-gray-900)}.border-green-200{border-color:var(--color-green-200)}.border-green-300{border-color:var(--color-green-300)}.border-purple-200{border-color:var(--color-purple-200)}.border-red-200{border-color:var(--color-red-200)}.border-red-300{border-color:var(--color-red-300)}.border-transparent{border-color:#0000}.border-t-gray-600{border-top-color:var(--color-gray-600)}.bg-\[\#4A154B\]{background-color:#4a154b}.bg-amber-50{background-color:var(--color-amber-50)}.bg-amber-100{background-color:var(--color-amber-100)}.bg-blue-50{background-color:var(--color-blue-50)}.bg-blue-100{background-color:var(--color-blue-100)}.bg-blue-400{background-color:var(--color-blue-400)}.bg-emerald-100{background-color:var(--color-emerald-100)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-50\/50{background-color:#f9fafb80}@supports (color:color-mix(in lab, red, red)){.bg-gray-50\/50{background-color:color-mix(in oklab, var(--color-gray-50) 50%, transparent)}}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-200{background-color:var(--color-gray-200)}.bg-gray-300{background-color:var(--color-gray-300)}.bg-gray-400{background-color:var(--color-gray-400)}.bg-gray-900{background-color:var(--color-gray-900)}.bg-gray-950{background-color:var(--color-gray-950)}.bg-green-50{background-color:var(--color-green-50)}.bg-green-100{background-color:var(--color-green-100)}.bg-green-500{background-color:var(--color-green-500)}.bg-green-600{background-color:var(--color-green-600)}.bg-indigo-100{background-color:var(--color-indigo-100)}.bg-orange-100{background-color:var(--color-orange-100)}.bg-orange-400{background-color:var(--color-orange-400)}.bg-orange-500{background-color:var(--color-orange-500)}.bg-pink-100{background-color:var(--color-pink-100)}.bg-pink-500{background-color:var(--color-pink-500)}.bg-purple-50{background-color:var(--color-purple-50)}.bg-purple-100{background-color:var(--color-purple-100)}.bg-purple-400{background-color:var(--color-purple-400)}.bg-red-50{background-color:var(--color-red-50)}.bg-red-500{background-color:var(--color-red-500)}.bg-red-600{background-color:var(--color-red-600)}.bg-violet-100{background-color:var(--color-violet-100)}.bg-violet-500{background-color:var(--color-violet-500)}.bg-white{background-color:var(--color-white)}.bg-yellow-50{background-color:var(--color-yellow-50)}.bg-yellow-100{background-color:var(--color-yellow-100)}.bg-yellow-400{background-color:var(--color-yellow-400)}.bg-yellow-500{background-color:var(--color-yellow-500)}.p-1{padding:calc(var(--spacing) * 1)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.p-12{padding:calc(var(--spacing) * 12)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-10{padding-block:calc(var(--spacing) * 10)}.py-12{padding-block:calc(var(--spacing) * 12)}.py-16{padding-block:calc(var(--spacing) * 16)}.pt-0{padding-top:calc(var(--spacing) * 0)}.pt-1{padding-top:calc(var(--spacing) * 1)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-6{padding-top:calc(var(--spacing) * 6)}.pt-8{padding-top:calc(var(--spacing) * 8)}.pt-12{padding-top:calc(var(--spacing) * 12)}.pt-16{padding-top:calc(var(--spacing) * 16)}.pt-24{padding-top:calc(var(--spacing) * 24)}.pr-1{padding-right:calc(var(--spacing) * 1)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-8{padding-bottom:calc(var(--spacing) * 8)}.pb-12{padding-bottom:calc(var(--spacing) * 12)}.pb-16{padding-bottom:calc(var(--spacing) * 16)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}.text-6xl{font-size:var(--text-6xl);line-height:var(--tw-leading,var(--text-6xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-amber-400{color:var(--color-amber-400)}.text-amber-500{color:var(--color-amber-500)}.text-amber-600{color:var(--color-amber-600)}.text-amber-700{color:var(--color-amber-700)}.text-amber-800{color:var(--color-amber-800)}.text-blue-400{color:var(--color-blue-400)}.text-blue-600{color:var(--color-blue-600)}.text-blue-700{color:var(--color-blue-700)}.text-blue-800{color:var(--color-blue-800)}.text-emerald-500{color:var(--color-emerald-500)}.text-emerald-700{color:var(--color-emerald-700)}.text-gray-300{color:var(--color-gray-300)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-gray-800{color:var(--color-gray-800)}.text-gray-900{color:var(--color-gray-900)}.text-green-400{color:var(--color-green-400)}.text-green-500{color:var(--color-green-500)}.text-green-600{color:var(--color-green-600)}.text-green-700{color:var(--color-green-700)}.text-green-800{color:var(--color-green-800)}.text-indigo-700{color:var(--color-indigo-700)}.text-orange-500{color:var(--color-orange-500)}.text-orange-600{color:var(--color-orange-600)}.text-orange-700{color:var(--color-orange-700)}.text-orange-800{color:var(--color-orange-800)}.text-pink-800{color:var(--color-pink-800)}.text-purple-400{color:var(--color-purple-400)}.text-purple-500{color:var(--color-purple-500)}.text-purple-600{color:var(--color-purple-600)}.text-purple-700{color:var(--color-purple-700)}.text-purple-800{color:var(--color-purple-800)}.text-red-400{color:var(--color-red-400)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-red-700{color:var(--color-red-700)}.text-violet-600{color:var(--color-violet-600)}.text-violet-700{color:var(--color-violet-700)}.text-violet-800{color:var(--color-violet-800)}.text-white{color:var(--color-white)}.text-yellow-500{color:var(--color-yellow-500)}.text-yellow-600{color:var(--color-yellow-600)}.text-yellow-700{color:var(--color-yellow-700)}.text-yellow-800{color:var(--color-yellow-800)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.underline{text-decoration-line:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-75{opacity:.75}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.select-all{-webkit-user-select:all;user-select:all}.select-none{-webkit-user-select:none;user-select:none}.group-open\:hidden:is(:where(.group):is([open],:popover-open,:open) *){display:none}.group-open\:inline:is(:where(.group):is([open],:popover-open,:open) *){display:inline}.group-open\:rotate-90:is(:where(.group):is([open],:popover-open,:open) *){rotate:90deg}@media (hover:hover){.group-hover\:border-gray-300:is(:where(.group):hover *){border-color:var(--color-gray-300)}.group-hover\:text-gray-500:is(:where(.group):hover *){color:var(--color-gray-500)}.group-hover\:text-violet-700:is(:where(.group):hover *){color:var(--color-violet-700)}}.first\:rounded-t-lg:first-child{border-top-left-radius:var(--radius-lg);border-top-right-radius:var(--radius-lg)}.last\:rounded-b-lg:last-child{border-bottom-right-radius:var(--radius-lg);border-bottom-left-radius:var(--radius-lg)}@media (hover:hover){.hover\:border-gray-300:hover{border-color:var(--color-gray-300)}.hover\:border-gray-400:hover{border-color:var(--color-gray-400)}.hover\:bg-amber-100:hover{background-color:var(--color-amber-100)}.hover\:bg-amber-200:hover{background-color:var(--color-amber-200)}.hover\:bg-gray-50:hover{background-color:var(--color-gray-50)}.hover\:bg-gray-800:hover{background-color:var(--color-gray-800)}.hover\:bg-green-50:hover{background-color:var(--color-green-50)}.hover\:bg-green-700:hover{background-color:var(--color-green-700)}.hover\:bg-red-50:hover{background-color:var(--color-red-50)}.hover\:bg-red-700:hover{background-color:var(--color-red-700)}.hover\:text-black:hover{color:var(--color-black)}.hover\:text-gray-600:hover{color:var(--color-gray-600)}.hover\:text-gray-700:hover{color:var(--color-gray-700)}.hover\:text-gray-900:hover{color:var(--color-gray-900)}.hover\:text-green-700:hover{color:var(--color-green-700)}.hover\:text-red-500:hover{color:var(--color-red-500)}.hover\:text-red-600:hover{color:var(--color-red-600)}.hover\:text-red-800:hover{color:var(--color-red-800)}.hover\:underline:hover{text-decoration-line:underline}.hover\:shadow-sm:hover{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}}.focus\:border-transparent:focus{border-color:#0000}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-gray-400:focus{--tw-ring-color:var(--color-gray-400)}.focus\:ring-gray-900:focus{--tw-ring-color:var(--color-gray-900)}.focus\:ring-green-500:focus{--tw-ring-color:var(--color-green-500)}.focus\:ring-purple-500:focus{--tw-ring-color:var(--color-purple-500)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.disabled\:opacity-50:disabled{opacity:.5}.has-\[\:checked\]\:border-blue-500:has(:checked){border-color:var(--color-blue-500)}.has-\[\:checked\]\:bg-blue-50:has(:checked){background-color:var(--color-blue-50)}@media (min-width:40rem){.sm\:flex{display:flex}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}.sm\:items-end{align-items:flex-end}}@media (min-width:48rem){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}}@media (prefers-color-scheme:dark){:root,:host{--color-white:oklch(14.5% .015 260);--color-black:oklch(98% .002 248);--color-gray-50:oklch(17.5% .02 260);--color-gray-100:oklch(21% .024 265);--color-gray-200:oklch(27.8% .025 257);--color-gray-300:oklch(37.3% .025 260);--color-gray-400:oklch(55.1% .02 264);--color-gray-500:oklch(60% .02 264);--color-gray-600:oklch(70.7% .017 261);--color-gray-700:oklch(80% .012 258);--color-gray-800:oklch(87.2% .008 258);--color-gray-900:oklch(93% .005 265);--color-gray-950:oklch(96.7% .003 265);--color-green-50:oklch(20% .04 155);--color-green-100:oklch(25% .06 155);--color-green-200:oklch(30% .08 155);--color-green-300:oklch(42% .12 154);--color-green-700:oklch(75% .15 150);--color-green-800:oklch(80% .12 150);--color-red-50:oklch(22% .04 17);--color-red-200:oklch(32% .06 18);--color-red-600:oklch(65% .2 27);--color-red-700:oklch(72% .18 27);--color-red-800:oklch(77% .15 27);--color-blue-100:oklch(22% .04 255);--color-blue-600:oklch(62% .2 263);--color-blue-700:oklch(72% .17 264);--color-blue-800:oklch(77% .15 265);--color-orange-100:oklch(25% .05 75);--color-orange-800:oklch(78% .13 37);--color-yellow-100:oklch(25% .06 103);--color-yellow-700:oklch(72% .12 66);--color-yellow-800:oklch(77% .1 62);--color-violet-100:oklch(22% .04 295);--color-violet-200:oklch(28% .06 294);--color-violet-400:oklch(45% .14 293);--color-violet-600:oklch(60% .2 293);--color-violet-800:oklch(75% .18 293);--color-purple-100:oklch(22% .04 307);--color-purple-800:oklch(75% .17 304);--color-pink-100:oklch(22% .04 342);--color-pink-800:oklch(75% .15 4);--color-amber-400:oklch(80% .17 84)}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}} \ No newline at end of file diff --git a/static/js/components/forage-components.js b/static/js/components/forage-components.js index 4dcf256..f279791 100644 --- a/static/js/components/forage-components.js +++ b/static/js/components/forage-components.js @@ -1,11 +1,11 @@ -var gc=Object.defineProperty;var Gl=_e=>{throw TypeError(_e)};var mc=(_e,de,Me)=>de in _e?gc(_e,de,{enumerable:!0,configurable:!0,writable:!0,value:Me}):_e[de]=Me;var ke=(_e,de,Me)=>mc(_e,typeof de!="symbol"?de+"":de,Me),po=(_e,de,Me)=>de.has(_e)||Gl("Cannot "+Me);var u=(_e,de,Me)=>(po(_e,de,"read from private field"),Me?Me.call(_e):de.get(_e)),W=(_e,de,Me)=>de.has(_e)?Gl("Cannot add the same private member more than once"):de instanceof WeakSet?de.add(_e):de.set(_e,Me),G=(_e,de,Me,Jn)=>(po(_e,de,"write to private field"),Jn?Jn.call(_e,Me):de.set(_e,Me),Me),ye=(_e,de,Me)=>(po(_e,de,"access private method"),Me);(function(){"use strict";var jl,Bl,br,_n,Gr,gn,mn,xn,wr,Yt,bn,nt,ho,_o,go,mo,dt,Hn,Qt,Vr,st,Kt,vt,Ot,nr,Wr,kr,wn,kn,yn,sr,vs,we,Vl,Wl,Yl,xo,xs,bs,bo,Fl,Ut,Jt,pt,Yr,Gn,Vn,ps,or,St;typeof window<"u"&&((jl=window.__svelte??(window.__svelte={})).v??(jl.v=new Set)).add("5");let de=!1,Me=!1;function Jn(){de=!0}Jn();const Ql=1,Kl=2,wo=4,Jl=8,Xl=16,Zl=1,ei=2,ti=4,ri=8,ni=16,ko=1,si=2,yo="[",ws="[!",Eo="[?",ks="]",Sr={},Ue=Symbol(),$o="http://www.w3.org/1999/xhtml",oi="http://www.w3.org/2000/svg",li="http://www.w3.org/1998/Math/MathML",ys=!1;var Co=Array.isArray,ii=Array.prototype.indexOf,sn=Array.prototype.includes,Xn=Array.from,Zn=Object.keys,es=Object.defineProperty,Dr=Object.getOwnPropertyDescriptor,So=Object.getOwnPropertyDescriptors,ai=Object.prototype,fi=Array.prototype,Es=Object.getPrototypeOf,Do=Object.isExtensible;const ci=()=>{};function ui(e){return e()}function $s(e){for(var t=0;t{e=s,t=o});return{promise:r,resolve:e,reject:t}}const je=2,on=4,Nr=8,Cs=1<<24,fr=16,Mt=32,cr=64,Ss=128,bt=512,Re=1024,Be=2048,wt=4096,Ge=8192,Pt=16384,Tr=32768,ln=65536,To=1<<17,di=1<<18,Ar=1<<19,Ao=1<<20,zt=1<<25,Mr=65536,Ds=1<<21,Ns=1<<22,ur=1<<23,Rr=Symbol("$state"),Mo=Symbol("legacy props"),vi=Symbol(""),Ir=new class extends Error{constructor(){super(...arguments);ke(this,"name","StaleReactionError");ke(this,"message","The reaction that called `getAbortSignal()` was re-run or destroyed")}},pi=!!((Bl=globalThis.document)!=null&&Bl.contentType)&&globalThis.document.contentType.includes("xml"),An=3,an=8;function Ro(e){throw new Error("https://svelte.dev/e/lifecycle_outside_component")}function hi(){throw new Error("https://svelte.dev/e/async_derived_orphan")}function _i(e,t,r){throw new Error("https://svelte.dev/e/each_key_duplicate")}function gi(e){throw new Error("https://svelte.dev/e/effect_in_teardown")}function mi(){throw new Error("https://svelte.dev/e/effect_in_unowned_derived")}function xi(e){throw new Error("https://svelte.dev/e/effect_orphan")}function bi(){throw new Error("https://svelte.dev/e/effect_update_depth_exceeded")}function wi(){throw new Error("https://svelte.dev/e/hydration_failed")}function ki(e){throw new Error("https://svelte.dev/e/props_invalid_value")}function yi(){throw new Error("https://svelte.dev/e/state_descriptors_fixed")}function Ei(){throw new Error("https://svelte.dev/e/state_prototype_fixed")}function $i(){throw new Error("https://svelte.dev/e/state_unsafe_mutation")}function Ci(){throw new Error("https://svelte.dev/e/svelte_boundary_reset_onerror")}function Mn(e){console.warn("https://svelte.dev/e/hydration_mismatch")}function Si(){console.warn("https://svelte.dev/e/svelte_boundary_reset_noop")}let X=!1;function er(e){X=e}let F;function He(e){if(e===null)throw Mn(),Sr;return F=e}function fn(){return He(It(F))}function y(e){if(X){if(It(F)!==null)throw Mn(),Sr;F=e}}function dr(e=1){if(X){for(var t=e,r=F;t--;)r=It(r);F=r}}function ts(e=!0){for(var t=0,r=F;;){if(r.nodeType===an){var s=r.data;if(s===ks){if(t===0)return r;t-=1}else(s===yo||s===ws||s[0]==="["&&!isNaN(Number(s.slice(1))))&&(t+=1)}var o=It(r);e&&r.remove(),r=o}}function Io(e){if(!e||e.nodeType!==an)throw Mn(),Sr;return e.data}function Lo(e){return e===this.v}function Di(e,t){return e!=e?t==t:e!==t||e!==null&&typeof e=="object"||typeof e=="function"}function qo(e){return!Di(e,this.v)}let ge=null;function cn(e){ge=e}function rs(e,t=!1,r){ge={p:ge,i:!1,c:null,e:null,s:e,x:null,l:de&&!t?{s:null,u:null,$:[]}:null}}function ns(e){var t=ge,r=t.e;if(r!==null){t.e=null;for(var s of r)nl(s)}return e!==void 0&&(t.x=e),t.i=!0,ge=t.p,e??{}}function Rn(){return!de||ge!==null&&ge.l===null}let Lr=[];function Oo(){var e=Lr;Lr=[],$s(e)}function tr(e){if(Lr.length===0&&!In){var t=Lr;queueMicrotask(()=>{t===Lr&&Oo()})}Lr.push(e)}function Ni(){for(;Lr.length>0;)Oo()}function Uo(e){var t=Z;if(t===null)return Y.f|=ur,e;if((t.f&Tr)===0&&(t.f&on)===0)throw e;vr(e,t)}function vr(e,t){for(;t!==null;){if((t.f&Ss)!==0){if((t.f&Tr)===0)throw e;try{t.b.error(e);return}catch(r){e=r}}t=t.parent}throw e}const Ti=-7169;function be(e,t){e.f=e.f&Ti|t}function Ts(e){(e.f&bt)!==0||e.deps===null?be(e,Re):be(e,wt)}function jo(e){if(e!==null)for(const t of e)(t.f&je)===0||(t.f&Mr)===0||(t.f^=Mr,jo(t.deps))}function Bo(e,t,r){(e.f&Be)!==0?t.add(e):(e.f&wt)!==0&&r.add(e),jo(e.deps),be(e,Re)}const ss=new Set;let ie=null,Fe=null,et=[],os=null,In=!1,un=null,Ai=1;const Zs=class Zs{constructor(){W(this,nt);ke(this,"id",Ai++);ke(this,"current",new Map);ke(this,"previous",new Map);W(this,br,new Set);W(this,_n,new Set);W(this,Gr,0);W(this,gn,0);W(this,mn,null);W(this,xn,new Set);W(this,wr,new Set);W(this,Yt,new Map);ke(this,"is_fork",!1);W(this,bn,!1)}skip_effect(t){u(this,Yt).has(t)||u(this,Yt).set(t,{d:[],m:[]})}unskip_effect(t){var r=u(this,Yt).get(t);if(r){u(this,Yt).delete(t);for(var s of r.d)be(s,Be),Gt(s);for(s of r.m)be(s,wt),Gt(s)}}process(t){var o;et=[],this.apply();var r=un=[],s=[];for(const l of t)ye(this,nt,_o).call(this,l,r,s);if(un=null,ye(this,nt,ho).call(this)){ye(this,nt,go).call(this,s),ye(this,nt,go).call(this,r);for(const[l,i]of u(this,Yt))Go(l,i)}else{ie=null;for(const l of u(this,br))l(this);u(this,br).clear(),u(this,Gr)===0&&ye(this,nt,mo).call(this),Po(s),Po(r),u(this,xn).clear(),u(this,wr).clear(),(o=u(this,mn))==null||o.resolve()}Fe=null}capture(t,r){r!==Ue&&!this.previous.has(t)&&this.previous.set(t,r),(t.f&ur)===0&&(this.current.set(t,t.v),Fe==null||Fe.set(t,t.v))}activate(){ie=this,this.apply()}deactivate(){ie===this&&(ie=null,Fe=null)}flush(){var t;if(et.length>0)ie=this,Fo();else if(u(this,Gr)===0&&!this.is_fork){for(const r of u(this,br))r(this);u(this,br).clear(),ye(this,nt,mo).call(this),(t=u(this,mn))==null||t.resolve()}this.deactivate()}discard(){for(const t of u(this,_n))t(this);u(this,_n).clear()}increment(t){G(this,Gr,u(this,Gr)+1),t&&G(this,gn,u(this,gn)+1)}decrement(t){G(this,Gr,u(this,Gr)-1),t&&G(this,gn,u(this,gn)-1),!u(this,bn)&&(G(this,bn,!0),tr(()=>{G(this,bn,!1),ye(this,nt,ho).call(this)?et.length>0&&this.flush():this.revive()}))}revive(){for(const t of u(this,xn))u(this,wr).delete(t),be(t,Be),Gt(t);for(const t of u(this,wr))be(t,wt),Gt(t);this.flush()}oncommit(t){u(this,br).add(t)}ondiscard(t){u(this,_n).add(t)}settled(){return(u(this,mn)??G(this,mn,No())).promise}static ensure(){if(ie===null){const t=ie=new Zs;ss.add(ie),In||tr(()=>{ie===t&&t.flush()})}return ie}apply(){}};br=new WeakMap,_n=new WeakMap,Gr=new WeakMap,gn=new WeakMap,mn=new WeakMap,xn=new WeakMap,wr=new WeakMap,Yt=new WeakMap,bn=new WeakMap,nt=new WeakSet,ho=function(){return this.is_fork||u(this,gn)>0},_o=function(t,r,s){t.f^=Re;for(var o=t.first;o!==null;){var l=o.f,i=(l&(Mt|cr))!==0,a=i&&(l&Re)!==0,f=(l&Ge)!==0,c=a||u(this,Yt).has(o);if(!c&&o.fn!==null){i?f||(o.f^=Re):(l&on)!==0?r.push(o):(l&(Nr|Cs))!==0&&f?s.push(o):vn(o)&&(Fr(o),(l&fr)!==0&&(u(this,wr).add(o),f&&be(o,Be)));var v=o.first;if(v!==null){o=v;continue}}for(;o!==null;){var m=o.next;if(m!==null){o=m;break}o=o.parent}}},go=function(t){for(var r=0;r1){this.previous.clear();var t=ie,r=Fe,s=!0;for(const i of ss){if(i===this){s=!1;continue}const a=[];for(const[c,v]of this.current){if(i.current.has(c))if(s&&v!==i.current.get(c))i.current.set(c,v);else continue;a.push(c)}if(a.length===0)continue;const f=[...i.current.keys()].filter(c=>!this.current.has(c));if(f.length>0){var o=et;et=[];const c=new Set,v=new Map;for(const m of a)zo(m,f,c,v);if(et.length>0){ie=i,i.apply();for(const m of et)ye(l=i,nt,_o).call(l,m,[],[]);i.deactivate()}et=o}}ie=t,Fe=r}u(this,Yt).clear(),ss.delete(this)};let rr=Zs;function Ht(e){var t=In;In=!0;try{for(var r;;){if(Ni(),et.length===0&&(ie==null||ie.flush(),et.length===0))return os=null,r;Fo()}}finally{In=t}}function Fo(){var e=null;try{for(var t=0;et.length>0;){var r=rr.ensure();if(t++>1e3){var s,o;Mi()}r.process(et),pr.clear()}}finally{et=[],os=null,un=null}}function Mi(){try{bi()}catch(e){vr(e,os)}}let Rt=null;function Po(e){var t=e.length;if(t!==0){for(var r=0;r0)){pr.clear();for(const o of Rt){if((o.f&(Pt|Ge))!==0)continue;const l=[o];let i=o.parent;for(;i!==null;)Rt.has(i)&&(Rt.delete(i),l.push(i)),i=i.parent;for(let a=l.length-1;a>=0;a--){const f=l[a];(f.f&(Pt|Ge))===0&&Fr(f)}}Rt.clear()}}Rt=null}}function zo(e,t,r,s){if(!r.has(e)&&(r.add(e),e.reactions!==null))for(const o of e.reactions){const l=o.f;(l&je)!==0?zo(o,t,r,s):(l&(Ns|fr))!==0&&(l&Be)===0&&Ho(o,t,s)&&(be(o,Be),Gt(o))}}function Ho(e,t,r){const s=r.get(e);if(s!==void 0)return s;if(e.deps!==null)for(const o of e.deps){if(sn.call(t,o))return!0;if((o.f&je)!==0&&Ho(o,t,r))return r.set(o,!0),!0}return r.set(e,!1),!1}function Gt(e){var t=os=e,r=t.b;if(r!=null&&r.is_pending&&(e.f&(on|Nr|Cs))!==0&&(e.f&Tr)===0){r.defer_effect(e);return}for(;t.parent!==null;){t=t.parent;var s=t.f;if(un!==null&&t===Z&&(e.f&Nr)===0)return;if((s&(cr|Mt))!==0){if((s&Re)===0)return;t.f^=Re}}et.push(t)}function Go(e,t){if(!((e.f&Mt)!==0&&(e.f&Re)!==0)){(e.f&Be)!==0?t.d.push(e):(e.f&wt)!==0&&t.m.push(e),be(e,Re);for(var r=e.first;r!==null;)Go(r,t),r=r.next}}function Ri(e){let t=0,r=qr(0),s;return()=>{Os()&&(n(r),Un(()=>(t===0&&(s=d(()=>e(()=>qn(r)))),t+=1,()=>{tr(()=>{t-=1,t===0&&(s==null||s(),s=void 0,qn(r))})})))}}var Ii=ln|Ar;function Li(e,t,r,s){new qi(e,t,r,s)}class qi{constructor(t,r,s,o){W(this,we);ke(this,"parent");ke(this,"is_pending",!1);ke(this,"transform_error");W(this,dt);W(this,Hn,X?F:null);W(this,Qt);W(this,Vr);W(this,st);W(this,Kt,null);W(this,vt,null);W(this,Ot,null);W(this,nr,null);W(this,Wr,0);W(this,kr,0);W(this,wn,!1);W(this,kn,new Set);W(this,yn,new Set);W(this,sr,null);W(this,vs,Ri(()=>(G(this,sr,qr(u(this,Wr))),()=>{G(this,sr,null)})));var l;G(this,dt,t),G(this,Qt,r),G(this,Vr,i=>{var a=Z;a.b=this,a.f|=Ss,s(i)}),this.parent=Z.b,this.transform_error=o??((l=this.parent)==null?void 0:l.transform_error)??(i=>i),G(this,st,js(()=>{if(X){const i=u(this,Hn);fn();const a=i.data===ws;if(i.data.startsWith(Eo)){const c=JSON.parse(i.data.slice(Eo.length));ye(this,we,Wl).call(this,c)}else a?ye(this,we,Yl).call(this):ye(this,we,Vl).call(this)}else ye(this,we,xo).call(this)},Ii)),X&&G(this,dt,F)}defer_effect(t){Bo(t,u(this,kn),u(this,yn))}is_rendered(){return!this.is_pending&&(!this.parent||this.parent.is_rendered())}has_pending_snippet(){return!!u(this,Qt).pending}update_pending_count(t){ye(this,we,bo).call(this,t),G(this,Wr,u(this,Wr)+t),!(!u(this,sr)||u(this,wn))&&(G(this,wn,!0),tr(()=>{G(this,wn,!1),u(this,sr)&&dn(u(this,sr),u(this,Wr))}))}get_effect_pending(){return u(this,vs).call(this),n(u(this,sr))}error(t){var r=u(this,Qt).onerror;let s=u(this,Qt).failed;if(!r&&!s)throw t;u(this,Kt)&&(Ye(u(this,Kt)),G(this,Kt,null)),u(this,vt)&&(Ye(u(this,vt)),G(this,vt,null)),u(this,Ot)&&(Ye(u(this,Ot)),G(this,Ot,null)),X&&(He(u(this,Hn)),dr(),He(ts()));var o=!1,l=!1;const i=()=>{if(o){Si();return}o=!0,l&&Ci(),u(this,Ot)!==null&&Ur(u(this,Ot),()=>{G(this,Ot,null)}),ye(this,we,bs).call(this,()=>{rr.ensure(),ye(this,we,xo).call(this)})},a=f=>{try{l=!0,r==null||r(f,i),l=!1}catch(c){vr(c,u(this,st)&&u(this,st).parent)}s&&G(this,Ot,ye(this,we,bs).call(this,()=>{rr.ensure();try{return kt(()=>{var c=Z;c.b=this,c.f|=Ss,s(u(this,dt),()=>f,()=>i)})}catch(c){return vr(c,u(this,st).parent),null}}))};tr(()=>{var f;try{f=this.transform_error(t)}catch(c){vr(c,u(this,st)&&u(this,st).parent);return}f!==null&&typeof f=="object"&&typeof f.then=="function"?f.then(a,c=>vr(c,u(this,st)&&u(this,st).parent)):a(f)})}}dt=new WeakMap,Hn=new WeakMap,Qt=new WeakMap,Vr=new WeakMap,st=new WeakMap,Kt=new WeakMap,vt=new WeakMap,Ot=new WeakMap,nr=new WeakMap,Wr=new WeakMap,kr=new WeakMap,wn=new WeakMap,kn=new WeakMap,yn=new WeakMap,sr=new WeakMap,vs=new WeakMap,we=new WeakSet,Vl=function(){try{G(this,Kt,kt(()=>u(this,Vr).call(this,u(this,dt))))}catch(t){this.error(t)}},Wl=function(t){const r=u(this,Qt).failed;r&&G(this,Ot,kt(()=>{r(u(this,dt),()=>t,()=>()=>{})}))},Yl=function(){const t=u(this,Qt).pending;t&&(this.is_pending=!0,G(this,vt,kt(()=>t(u(this,dt)))),tr(()=>{var r=G(this,nr,document.createDocumentFragment()),s=tt();r.append(s),G(this,Kt,ye(this,we,bs).call(this,()=>(rr.ensure(),kt(()=>u(this,Vr).call(this,s))))),u(this,kr)===0&&(u(this,dt).before(r),G(this,nr,null),Ur(u(this,vt),()=>{G(this,vt,null)}),ye(this,we,xs).call(this))}))},xo=function(){try{if(this.is_pending=this.has_pending_snippet(),G(this,kr,0),G(this,Wr,0),G(this,Kt,kt(()=>{u(this,Vr).call(this,u(this,dt))})),u(this,kr)>0){var t=G(this,nr,document.createDocumentFragment());Ps(u(this,Kt),t);const r=u(this,Qt).pending;G(this,vt,kt(()=>r(u(this,dt))))}else ye(this,we,xs).call(this)}catch(r){this.error(r)}},xs=function(){this.is_pending=!1;for(const t of u(this,kn))be(t,Be),Gt(t);for(const t of u(this,yn))be(t,wt),Gt(t);u(this,kn).clear(),u(this,yn).clear()},bs=function(t){var r=Z,s=Y,o=ge;Wt(u(this,st)),yt(u(this,st)),cn(u(this,st).ctx);try{return t()}catch(l){return Uo(l),null}finally{Wt(r),yt(s),cn(o)}},bo=function(t){var r;if(!this.has_pending_snippet()){this.parent&&ye(r=this.parent,we,bo).call(r,t);return}G(this,kr,u(this,kr)+t),u(this,kr)===0&&(ye(this,we,xs).call(this),u(this,vt)&&Ur(u(this,vt),()=>{G(this,vt,null)}),u(this,nr)&&(u(this,dt).before(u(this,nr)),G(this,nr,null)))};function Oi(e,t,r,s){const o=Rn()?Ln:Ve;var l=e.filter(m=>!m.settled);if(r.length===0&&l.length===0){s(t.map(o));return}var i=Z,a=Ui(),f=l.length===1?l[0].promise:l.length>1?Promise.all(l.map(m=>m.promise)):null;function c(m){a();try{s(m)}catch(b){(i.f&Pt)===0&&vr(b,i)}As()}if(r.length===0){f.then(()=>c(t.map(o)));return}function v(){a(),Promise.all(r.map(m=>Bi(m))).then(m=>c([...t.map(o),...m])).catch(m=>vr(m,i))}f?f.then(v):v()}function Ui(){var e=Z,t=Y,r=ge,s=ie;return function(l=!0){Wt(e),yt(t),cn(r),l&&(s==null||s.activate())}}function As(e=!0){Wt(null),yt(null),cn(null),e&&(ie==null||ie.deactivate())}function ji(){var e=Z.b,t=ie,r=e.is_rendered();return e.update_pending_count(1),t.increment(r),()=>{e.update_pending_count(-1),t.decrement(r)}}function Ln(e){var t=je|Be,r=Y!==null&&(Y.f&je)!==0?Y:null;return Z!==null&&(Z.f|=Ar),{ctx:ge,deps:null,effects:null,equals:Lo,f:t,fn:e,reactions:null,rv:0,v:Ue,wv:0,parent:r??Z,ac:null}}function Bi(e,t,r){Z===null&&hi();var o=void 0,l=qr(Ue),i=!Y,a=new Map;return Ki(()=>{var b;var f=No();o=f.promise;try{Promise.resolve(e()).then(f.resolve,f.reject).finally(As)}catch(S){f.reject(S),As()}var c=ie;if(i){var v=ji();(b=a.get(c))==null||b.reject(Ir),a.delete(c),a.set(c,f)}const m=(S,$=void 0)=>{if(c.activate(),$)$!==Ir&&(l.f|=ur,dn(l,$));else{(l.f&ur)!==0&&(l.f^=ur),dn(l,S);for(const[B,x]of a){if(a.delete(B),B===c)break;x.reject(Ir)}}v&&v()};f.promise.then(m,S=>m(null,S||"unknown"))}),rl(()=>{for(const f of a.values())f.reject(Ir)}),new Promise(f=>{function c(v){function m(){v===o?f(l):c(o)}v.then(m,m)}c(o)})}function Vt(e){const t=Ln(e);return ul(t),t}function Ve(e){const t=Ln(e);return t.equals=qo,t}function Fi(e){var t=e.effects;if(t!==null){e.effects=null;for(var r=0;r0&&!Yo&&Hi()}return t}function Hi(){Yo=!1;for(const e of Rs)(e.f&Re)!==0&&be(e,wt),vn(e)&&Fr(e);Rs.clear()}function qn(e){U(e,e.v+1)}function Qo(e,t){var r=e.reactions;if(r!==null)for(var s=Rn(),o=r.length,l=0;l{if(Br===l)return a();var f=Y,c=Br;yt(null),vl(l);var v=a();return yt(f),vl(c),v};return s&&r.set("length",Ie(e.length)),new Proxy(e,{defineProperty(a,f,c){(!("value"in c)||c.configurable===!1||c.enumerable===!1||c.writable===!1)&&yi();var v=r.get(f);return v===void 0?i(()=>{var m=Ie(c.value);return r.set(f,m),m}):U(v,c.value,!0),!0},deleteProperty(a,f){var c=r.get(f);if(c===void 0){if(f in a){const v=i(()=>Ie(Ue));r.set(f,v),qn(o)}}else U(c,Ue),qn(o);return!0},get(a,f,c){var S;if(f===Rr)return e;var v=r.get(f),m=f in a;if(v===void 0&&(!m||(S=Dr(a,f))!=null&&S.writable)&&(v=i(()=>{var $=Or(m?a[f]:Ue),B=Ie($);return B}),r.set(f,v)),v!==void 0){var b=n(v);return b===Ue?void 0:b}return Reflect.get(a,f,c)},getOwnPropertyDescriptor(a,f){var c=Reflect.getOwnPropertyDescriptor(a,f);if(c&&"value"in c){var v=r.get(f);v&&(c.value=n(v))}else if(c===void 0){var m=r.get(f),b=m==null?void 0:m.v;if(m!==void 0&&b!==Ue)return{enumerable:!0,configurable:!0,value:b,writable:!0}}return c},has(a,f){var b;if(f===Rr)return!0;var c=r.get(f),v=c!==void 0&&c.v!==Ue||Reflect.has(a,f);if(c!==void 0||Z!==null&&(!v||(b=Dr(a,f))!=null&&b.writable)){c===void 0&&(c=i(()=>{var S=v?Or(a[f]):Ue,$=Ie(S);return $}),r.set(f,c));var m=n(c);if(m===Ue)return!1}return v},set(a,f,c,v){var ee;var m=r.get(f),b=f in a;if(s&&f==="length")for(var S=c;SIe(Ue)),r.set(S+"",$))}if(m===void 0)(!b||(ee=Dr(a,f))!=null&&ee.writable)&&(m=i(()=>Ie(void 0)),U(m,Or(c)),r.set(f,m));else{b=m.v!==Ue;var B=i(()=>Or(c));U(m,B)}var x=Reflect.getOwnPropertyDescriptor(a,f);if(x!=null&&x.set&&x.set.call(v,c),!b){if(s&&typeof f=="string"){var A=r.get("length"),ae=Number(f);Number.isInteger(ae)&&ae>=A.v&&U(A,ae+1)}qn(o)}return!0},ownKeys(a){n(o);var f=Reflect.ownKeys(a).filter(m=>{var b=r.get(m);return b===void 0||b.v!==Ue});for(var[c,v]of r)v.v!==Ue&&!(c in a)&&f.push(c);return f},setPrototypeOf(){Ei()}})}var Is,Ko,Jo,Xo;function Ls(){if(Is===void 0){Is=window,Ko=/Firefox/.test(navigator.userAgent);var e=Element.prototype,t=Node.prototype,r=Text.prototype;Jo=Dr(t,"firstChild").get,Xo=Dr(t,"nextSibling").get,Do(e)&&(e.__click=void 0,e.__className=void 0,e.__attributes=null,e.__style=void 0,e.__e=void 0),Do(r)&&(r.__t=void 0)}}function tt(e=""){return document.createTextNode(e)}function We(e){return Jo.call(e)}function It(e){return Xo.call(e)}function E(e,t){if(!X)return We(e);var r=We(F);if(r===null)r=F.appendChild(tt());else if(t&&r.nodeType!==An){var s=tt();return r==null||r.before(s),He(s),s}return t&&is(r),He(r),r}function ft(e,t=!1){if(!X){var r=We(e);return r instanceof Comment&&r.data===""?It(r):r}if(t){if((F==null?void 0:F.nodeType)!==An){var s=tt();return F==null||F.before(s),He(s),s}is(F)}return F}function D(e,t=1,r=!1){let s=X?F:e;for(var o;t--;)o=s,s=It(s);if(!X)return s;if(r){if((s==null?void 0:s.nodeType)!==An){var l=tt();return s===null?o==null||o.after(l):s.before(l),He(l),l}is(s)}return He(s),s}function Zo(e){e.textContent=""}function el(){return!1}function ls(e,t,r){return document.createElementNS(t??$o,e,void 0)}function is(e){if(e.nodeValue.length<65536)return;let t=e.nextSibling;for(;t!==null&&t.nodeType===An;)t.remove(),e.nodeValue+=t.nodeValue,t=e.nextSibling}function qs(e){var t=Y,r=Z;yt(null),Wt(null);try{return e()}finally{yt(t),Wt(r)}}function tl(e){Z===null&&(Y===null&&xi(),mi()),hr&&gi()}function Gi(e,t){var r=t.last;r===null?t.last=t.first=e:(r.next=e,e.prev=r,t.last=e)}function Lt(e,t){var r=Z;r!==null&&(r.f&Ge)!==0&&(e|=Ge);var s={ctx:ge,deps:null,nodes:null,f:e|Be|bt,first:null,fn:t,last:null,next:null,parent:r,b:r&&r.b,prev:null,teardown:null,wv:0,ac:null},o=s;if((e&on)!==0)un!==null?un.push(s):Gt(s);else if(t!==null){try{Fr(s)}catch(i){throw Ye(s),i}o.deps===null&&o.teardown===null&&o.nodes===null&&o.first===o.last&&(o.f&Ar)===0&&(o=o.first,(e&fr)!==0&&(e&ln)!==0&&o!==null&&(o.f|=ln))}if(o!==null&&(o.parent=r,r!==null&&Gi(o,r),Y!==null&&(Y.f&je)!==0&&(e&cr)===0)){var l=Y;(l.effects??(l.effects=[])).push(o)}return s}function Os(){return Y!==null&&!qt}function rl(e){const t=Lt(Nr,null);return be(t,Re),t.teardown=e,t}function On(e){tl();var t=Z.f,r=!Y&&(t&Mt)!==0&&(t&Tr)===0;if(r){var s=ge;(s.e??(s.e=[])).push(e)}else return nl(e)}function nl(e){return Lt(on|Ao,e)}function Vi(e){return tl(),Lt(Nr|Ao,e)}function Wi(e){rr.ensure();const t=Lt(cr|Ar,e);return()=>{Ye(t)}}function Yi(e){rr.ensure();const t=Lt(cr|Ar,e);return(r={})=>new Promise(s=>{r.outro?Ur(t,()=>{Ye(t),s(void 0)}):(Ye(t),s(void 0))})}function sl(e){return Lt(on,e)}function Us(e,t){var r=ge,s={effect:null,ran:!1,deps:e};r.l.$.push(s),s.effect=Un(()=>{e(),!s.ran&&(s.ran=!0,d(t))})}function Qi(){var e=ge;Un(()=>{for(var t of e.l.$){t.deps();var r=t.effect;(r.f&Re)!==0&&r.deps!==null&&be(r,wt),vn(r)&&Fr(r),t.ran=!1}})}function Ki(e){return Lt(Ns|Ar,e)}function Un(e,t=0){return Lt(Nr|t,e)}function j(e,t=[],r=[],s=[]){Oi(s,t,r,o=>{Lt(Nr,()=>e(...o.map(n)))})}function js(e,t=0){var r=Lt(fr|t,e);return r}function kt(e){return Lt(Mt|Ar,e)}function ol(e){var t=e.teardown;if(t!==null){const r=hr,s=Y;cl(!0),yt(null);try{t.call(null)}finally{cl(r),yt(s)}}}function Bs(e,t=!1){var r=e.first;for(e.first=e.last=null;r!==null;){const o=r.ac;o!==null&&qs(()=>{o.abort(Ir)});var s=r.next;(r.f&cr)!==0?r.parent=null:Ye(r,t),r=s}}function Ji(e){for(var t=e.first;t!==null;){var r=t.next;(t.f&Mt)===0&&Ye(t),t=r}}function Ye(e,t=!0){var r=!1;(t||(e.f&di)!==0)&&e.nodes!==null&&e.nodes.end!==null&&(ll(e.nodes.start,e.nodes.end),r=!0),Bs(e,t&&!r),jn(e,0),be(e,Pt);var s=e.nodes&&e.nodes.t;if(s!==null)for(const l of s)l.stop();ol(e);var o=e.parent;o!==null&&o.first!==null&&il(e),e.next=e.prev=e.teardown=e.ctx=e.deps=e.fn=e.nodes=e.ac=null}function ll(e,t){for(;e!==null;){var r=e===t?null:It(e);e.remove(),e=r}}function il(e){var t=e.parent,r=e.prev,s=e.next;r!==null&&(r.next=s),s!==null&&(s.prev=r),t!==null&&(t.first===e&&(t.first=s),t.last===e&&(t.last=r))}function Ur(e,t,r=!0){var s=[];al(e,s,!0);var o=()=>{r&&Ye(e),t&&t()},l=s.length;if(l>0){var i=()=>--l||o();for(var a of s)a.out(i)}else o()}function al(e,t,r){if((e.f&Ge)===0){e.f^=Ge;var s=e.nodes&&e.nodes.t;if(s!==null)for(const a of s)(a.is_global||r)&&t.push(a);for(var o=e.first;o!==null;){var l=o.next,i=(o.f&ln)!==0||(o.f&Mt)!==0&&(e.f&fr)!==0;al(o,t,i?r:!1),o=l}}}function Fs(e){fl(e,!0)}function fl(e,t){if((e.f&Ge)!==0){e.f^=Ge;for(var r=e.first;r!==null;){var s=r.next,o=(r.f&ln)!==0||(r.f&Mt)!==0;fl(r,o?t:!1),r=s}var l=e.nodes&&e.nodes.t;if(l!==null)for(const i of l)(i.is_global||t)&&i.in()}}function Ps(e,t){if(e.nodes)for(var r=e.nodes.start,s=e.nodes.end;r!==null;){var o=r===s?null:It(r);t.append(r),r=o}}let as=!1,hr=!1;function cl(e){hr=e}let Y=null,qt=!1;function yt(e){Y=e}let Z=null;function Wt(e){Z=e}let Et=null;function ul(e){Y!==null&&(Et===null?Et=[e]:Et.push(e))}let rt=null,ct=0,$t=null;function Xi(e){$t=e}let dl=1,jr=0,Br=jr;function vl(e){Br=e}function pl(){return++dl}function vn(e){var t=e.f;if((t&Be)!==0)return!0;if(t&je&&(e.f&=~Mr),(t&wt)!==0){for(var r=e.deps,s=r.length,o=0;oe.wv)return!0}(t&bt)!==0&&Fe===null&&be(e,Re)}return!1}function hl(e,t,r=!0){var s=e.reactions;if(s!==null&&!(Et!==null&&sn.call(Et,e)))for(var o=0;o{e.ac.abort(Ir)}),e.ac=null);try{e.f|=Ds;var v=e.fn,m=v();e.f|=Tr;var b=e.deps,S=ie==null?void 0:ie.is_fork;if(rt!==null){var $;if(S||jn(e,ct),b!==null&&ct>0)for(b.length=ct+rt.length,$=0;$r==null?void 0:r.call(this,l))}return e.startsWith("pointer")||e.startsWith("touch")||e==="wheel"?tr(()=>{t.addEventListener(e,o,s)}):t.addEventListener(e,o,s),o}function _r(e,t,r,s,o){var l={capture:s,passive:o},i=ta(e,t,r,l);(t===document.body||t===window||t===document||t instanceof HTMLMediaElement)&&rl(()=>{t.removeEventListener(e,i,l)})}function Bn(e,t,r){(t[Pr]??(t[Pr]={}))[e]=r}function bl(e){for(var t=0;t{throw ae});throw b}}finally{e[Pr]=t,delete e.currentTarget,yt(v),Wt(m)}}}const Vs=((Fl=globalThis==null?void 0:globalThis.window)==null?void 0:Fl.trustedTypes)&&globalThis.window.trustedTypes.createPolicy("svelte-trusted-html",{createHTML:e=>e});function ra(e){return(Vs==null?void 0:Vs.createHTML(e))??e}function kl(e){var t=ls("template");return t.innerHTML=ra(e.replaceAll("","")),t.content}function ut(e,t){var r=Z;r.nodes===null&&(r.nodes={start:e,end:t,a:null,t:null})}function C(e,t){var r=(t&ko)!==0,s=(t&si)!==0,o,l=!e.startsWith("");return()=>{if(X)return ut(F,null),F;o===void 0&&(o=kl(l?e:""+e),r||(o=We(o)));var i=s||Ko?document.importNode(o,!0):o.cloneNode(!0);if(r){var a=We(i),f=i.lastChild;ut(a,f)}else ut(i,i);return i}}function na(e,t,r="svg"){var s=!e.startsWith(""),o=(t&ko)!==0,l=`<${r}>${s?e:""+e}`,i;return()=>{if(X)return ut(F,null),F;if(!i){var a=kl(l),f=We(a);if(o)for(i=document.createDocumentFragment();We(f);)i.appendChild(We(f));else i=We(f)}var c=i.cloneNode(!0);if(o){var v=We(c),m=c.lastChild;ut(v,m)}else ut(c,c);return c}}function Le(e,t){return na(e,t,"svg")}function sa(e=""){if(!X){var t=tt(e+"");return ut(t,t),t}var r=F;return r.nodeType!==An?(r.before(r=tt()),He(r)):is(r),ut(r,r),r}function Fn(){if(X)return ut(F,null),F;var e=document.createDocumentFragment(),t=document.createComment(""),r=tt();return e.append(t,r),ut(t,r),e}function w(e,t){if(X){var r=Z;((r.f&Tr)===0||r.nodes.end===null)&&(r.nodes.end=F),fn();return}e!==null&&e.before(t)}const oa=["touchstart","touchmove"];function la(e){return oa.includes(e)}function V(e,t){var r=t==null?"":typeof t=="object"?`${t}`:t;r!==(e.__t??(e.__t=e.nodeValue))&&(e.__t=r,e.nodeValue=`${r}`)}function yl(e,t){return El(e,t)}function ia(e,t){Ls(),t.intro=t.intro??!1;const r=t.target,s=X,o=F;try{for(var l=We(r);l&&(l.nodeType!==an||l.data!==yo);)l=It(l);if(!l)throw Sr;er(!0),He(l);const i=El(e,{...t,anchor:l});return er(!1),i}catch(i){if(i instanceof Error&&i.message.split(` -`).some(a=>a.startsWith("https://svelte.dev/e/")))throw i;return i!==Sr&&console.warn("Failed to hydrate: ",i),t.recover===!1&&wi(),Ls(),Zo(r),er(!1),yl(e,t)}finally{er(s),He(o)}}const fs=new Map;function El(e,{target:t,anchor:r,props:s={},events:o,context:l,intro:i=!0,transformError:a}){Ls();var f=void 0,c=Yi(()=>{var v=r??t.appendChild(tt());Li(v,{pending:()=>{}},S=>{rs({});var $=ge;if(l&&($.c=l),o&&(s.$$events=o),X&&ut(S,null),f=e(S,s)||{},X&&(Z.nodes.end=F,F===null||F.nodeType!==an||F.data!==ks))throw Mn(),Sr;ns()},a);var m=new Set,b=S=>{for(var $=0;${var x;for(var S of m)for(const A of[t,document]){var $=fs.get(A),B=$.get(S);--B==0?(A.removeEventListener(S,Gs),$.delete(S),$.size===0&&fs.delete(A)):$.set(S,B)}Hs.delete(b),v!==r&&((x=v.parentNode)==null||x.removeChild(v))}});return Ws.set(f,c),f}let Ws=new WeakMap;function aa(e,t){const r=Ws.get(e);return r?(Ws.delete(e),r(t)):Promise.resolve()}class fa{constructor(t,r=!0){ke(this,"anchor");W(this,Ut,new Map);W(this,Jt,new Map);W(this,pt,new Map);W(this,Yr,new Set);W(this,Gn,!0);W(this,Vn,t=>{if(u(this,Ut).has(t)){var r=u(this,Ut).get(t),s=u(this,Jt).get(r);if(s)Fs(s),u(this,Yr).delete(r);else{var o=u(this,pt).get(r);o&&(o.effect.f&Ge)===0&&(u(this,Jt).set(r,o.effect),u(this,pt).delete(r),o.fragment.lastChild.remove(),this.anchor.before(o.fragment),s=o.effect)}for(const[l,i]of u(this,Ut)){if(u(this,Ut).delete(l),l===t)break;const a=u(this,pt).get(i);a&&(Ye(a.effect),u(this,pt).delete(i))}for(const[l,i]of u(this,Jt)){if(l===r||u(this,Yr).has(l)||(i.f&Ge)!==0)continue;const a=()=>{if(Array.from(u(this,Ut).values()).includes(l)){var c=document.createDocumentFragment();Ps(i,c),c.append(tt()),u(this,pt).set(l,{effect:i,fragment:c})}else Ye(i);u(this,Yr).delete(l),u(this,Jt).delete(l)};u(this,Gn)||!s?(u(this,Yr).add(l),Ur(i,a,!1)):a()}}});W(this,ps,t=>{u(this,Ut).delete(t);const r=Array.from(u(this,Ut).values());for(const[s,o]of u(this,pt))r.includes(s)||(Ye(o.effect),u(this,pt).delete(s))});this.anchor=t,G(this,Gn,r)}ensure(t,r){var s=ie,o=el();if(r&&!u(this,Jt).has(t)&&!u(this,pt).has(t))if(o){var l=document.createDocumentFragment(),i=tt();l.append(i),u(this,pt).set(t,{effect:kt(()=>r(i)),fragment:l})}else u(this,Jt).set(t,kt(()=>r(this.anchor)));if(u(this,Ut).set(s,t),o){for(const[a,f]of u(this,Jt))a===t?s.unskip_effect(f):s.skip_effect(f);for(const[a,f]of u(this,pt))a===t?s.unskip_effect(f.effect):s.skip_effect(f.effect);s.oncommit(u(this,Vn)),s.ondiscard(u(this,ps))}else X&&(this.anchor=F),u(this,Vn).call(this,s)}}Ut=new WeakMap,Jt=new WeakMap,pt=new WeakMap,Yr=new WeakMap,Gn=new WeakMap,Vn=new WeakMap,ps=new WeakMap;function $l(e){ge===null&&Ro(),de&&ge.l!==null?ua(ge).m.push(e):On(()=>{const t=d(e);if(typeof t=="function")return t})}function ca(e){ge===null&&Ro(),$l(()=>()=>d(e))}function ua(e){var t=e.l;return t.u??(t.u={a:[],b:[],m:[]})}function Q(e,t,r=!1){var s;X&&(s=F,fn());var o=new fa(e),l=r?ln:0;function i(a,f){if(X){var c=Io(s);if(a!==parseInt(c.substring(1))){var v=ts();He(v),o.anchor=v,er(!1),o.ensure(a,f),er(!0);return}}o.ensure(a,f)}js(()=>{var a=!1;t((f,c=0)=>{a=!0,i(c,f)}),a||i(-1,null)},l)}function cs(e,t){return t}function da(e,t,r){for(var s=[],o=t.length,l,i=t.length,a=0;a{if(l){if(l.pending.delete(m),l.done.add(m),l.pending.size===0){var b=e.outrogroups;Ys(e,Xn(l.done)),b.delete(l),b.size===0&&(e.outrogroups=null)}}else i-=1},!1)}if(i===0){var f=s.length===0&&r!==null;if(f){var c=r,v=c.parentNode;Zo(v),v.append(c),e.items.clear()}Ys(e,t,!f)}else l={pending:new Set(t),done:new Set},(e.outrogroups??(e.outrogroups=new Set)).add(l)}function Ys(e,t,r=!0){var s;if(e.pending.size>0){s=new Set;for(const i of e.pending.values())for(const a of i)s.add(e.items.get(a).e)}for(var o=0;o{var ee=r();return Co(ee)?ee:ee==null?[]:Xn(ee)}),b,S=new Map,$=!0;function B(ee){(ae.effect.f&Pt)===0&&(ae.pending.delete(ee),ae.fallback=v,va(ae,b,i,t,s),v!==null&&(b.length===0?(v.f&zt)===0?Fs(v):(v.f^=zt,zn(v,null,i)):Ur(v,()=>{v=null})))}function x(ee){ae.pending.delete(ee)}var A=js(()=>{b=n(m);var ee=b.length;let ne=!1;if(X){var Qe=Io(i)===ws;Qe!==(ee===0)&&(i=ts(),He(i),er(!1),ne=!0)}for(var pe=new Set,K=ie,Ne=el(),Ke=0;Kel(i)):(v=kt(()=>l(Cl??(Cl=tt()))),v.f|=zt)),ee>pe.size&&_i(),X&&ee>0&&He(ts()),!$)if(S.set(K,pe),Ne){for(const[se,J]of a)pe.has(se)||K.skip_effect(J.e);K.oncommit(B),K.ondiscard(x)}else B(K);ne&&er(!0),n(m)}),ae={effect:A,items:a,pending:S,outrogroups:null,fallback:v};$=!1,X&&(i=F)}function Pn(e){for(;e!==null&&(e.f&Mt)===0;)e=e.next;return e}function va(e,t,r,s,o){var ht,Dt,M,se,J,fe,Pe,qe,ot;var l=(s&Jl)!==0,i=t.length,a=e.items,f=Pn(e.effect.first),c,v=null,m,b=[],S=[],$,B,x,A;if(l)for(A=0;A0){var Ke=(s&wo)!==0&&i===0?r:null;if(l){for(A=0;A{var Je,yr;if(m!==void 0)for(x of m)(yr=(Je=x.nodes)==null?void 0:Je.a)==null||yr.apply()})}function pa(e,t,r,s,o,l,i,a){var f=(i&Ql)!==0?(i&Xl)===0?at(r,!1,!1):qr(r):null,c=(i&Kl)!==0?qr(o):null;return{v:f,i:c,e:kt(()=>(l(t,f??r,c??o,a),()=>{e.delete(s)}))}}function zn(e,t,r){if(e.nodes)for(var s=e.nodes.start,o=e.nodes.end,l=t&&(t.f&zt)===0?t.nodes.start:r;s!==null;){var i=It(s);if(l.before(s),s===o)return;s=i}}function gr(e,t,r){t===null?e.effect.first=r:t.next=r,r===null?e.effect.last=t:r.prev=t}function ha(e,t,r=!1,s=!1,o=!1){var l=e,i="";j(()=>{var a=Z;if(i===(i=t()??"")){X&&fn();return}if(a.nodes!==null&&(ll(a.nodes.start,a.nodes.end),a.nodes=null),i!==""){if(X){F.data;for(var f=fn(),c=f;f!==null&&(f.nodeType!==an||f.data!=="");)c=f,f=It(f);if(f===null)throw Mn(),Sr;ut(F,c),l=He(f);return}var v=r?oi:s?li:void 0,m=ls(r?"svg":s?"math":"template",v);m.innerHTML=i;var b=r||s?m:m.content;if(ut(We(b),b.lastChild),r||s)for(;We(b);)l.before(We(b));else l.before(b)}})}function Qs(e,t){sl(()=>{var r=e.getRootNode(),s=r.host?r:r.head??r.ownerDocument.head;if(!s.querySelector("#"+t.hash)){const o=ls("style");o.id=t.hash,o.textContent=t.code,s.appendChild(o)}})}const Sl=[...` -\r\f \v\uFEFF`];function _a(e,t,r){var s=e==null?"":""+e;if(t&&(s=s?s+" "+t:t),r){for(var o of Object.keys(r))if(r[o])s=s?s+" "+o:o;else if(s.length)for(var l=o.length,i=0;(i=s.indexOf(o,i))>=0;){var a=i+l;(i===0||Sl.includes(s[i-1]))&&(a===s.length||Sl.includes(s[a]))?s=(i===0?"":s.substring(0,i))+s.substring(a+1):i=a}}return s===""?null:s}function ga(e,t){return e==null?null:String(e)}function he(e,t,r,s,o,l){var i=e.__className;if(X||i!==r||i===void 0){var a=_a(r,s,l);(!X||a!==e.getAttribute("class"))&&(a==null?e.removeAttribute("class"):t?e.className=a:e.setAttribute("class",a)),e.__className=r}else if(l&&o!==l)for(var f in l){var c=!!l[f];(o==null||c!==!!o[f])&&e.classList.toggle(f,c)}return l}function zr(e,t,r,s){var o=e.__style;if(X||o!==t){var l=ga(t);(!X||l!==e.getAttribute("style"))&&(l==null?e.removeAttribute("style"):e.style.cssText=l),e.__style=t}return s}const ma=Symbol("is custom element"),xa=Symbol("is html"),ba=pi?"link":"LINK";function Hr(e,t,r,s){var o=wa(e);X&&(o[t]=e.getAttribute(t),t==="src"||t==="srcset"||t==="href"&&e.nodeName===ba)||o[t]!==(o[t]=r)&&(t==="loading"&&(e[vi]=r),r==null?e.removeAttribute(t):typeof r!="string"&&ka(e).includes(t)?e[t]=r:e.setAttribute(t,r))}function wa(e){return e.__attributes??(e.__attributes={[ma]:e.nodeName.includes("-"),[xa]:e.namespaceURI===$o})}var Dl=new Map;function ka(e){var t=e.getAttribute("is")||e.nodeName,r=Dl.get(t);if(r)return r;Dl.set(t,r=[]);for(var s,o=e,l=Element.prototype;l!==o;){s=So(o);for(var i in s)s[i].set&&r.push(i);o=Es(o)}return r}function Nl(e,t){return e===t||(e==null?void 0:e[Rr])===t}function Tl(e={},t,r,s){return sl(()=>{var o,l;return Un(()=>{o=l,l=[],d(()=>{e!==r(...l)&&(t(e,...l),o&&Nl(r(...o),e)&&t(null,...o))})}),()=>{tr(()=>{l&&Nl(r(...l),e)&&t(null,...l)})}}),e}function Al(e){return function(...t){var r=t[0];return r.stopPropagation(),e==null?void 0:e.apply(this,t)}}function ya(e=!1){const t=ge,r=t.l.u;if(!r)return;let s=()=>_(t.s);if(e){let o=0,l={};const i=Ln(()=>{let a=!1;const f=t.s;for(const c in f)f[c]!==l[c]&&(l[c]=f[c],a=!0);return a&&o++,o});s=()=>n(i)}r.b.length&&Vi(()=>{Ml(t,s),$s(r.b)}),On(()=>{const o=d(()=>r.m.map(ui));return()=>{for(const l of o)typeof l=="function"&&l()}}),r.a.length&&On(()=>{Ml(t,s),$s(r.a)})}function Ml(e,t){if(e.l.s)for(const r of e.l.s)n(r);t()}let us=!1;function Ea(e){var t=us;try{return us=!1,[e(),us]}finally{us=t}}function mr(e,t,r,s){var ee;var o=!de||(r&ei)!==0,l=(r&ri)!==0,i=(r&ni)!==0,a=s,f=!0,c=()=>(f&&(f=!1,a=i?d(s):s),a),v;if(l){var m=Rr in e||Mo in e;v=((ee=Dr(e,t))==null?void 0:ee.set)??(m&&t in e?ne=>e[t]=ne:void 0)}var b,S=!1;l?[b,S]=Ea(()=>e[t]):b=e[t],b===void 0&&s!==void 0&&(b=c(),v&&(o&&ki(),v(b)));var $;if(o?$=()=>{var ne=e[t];return ne===void 0?c():(f=!0,ne)}:$=()=>{var ne=e[t];return ne!==void 0&&(a=void 0),ne===void 0?a:ne},o&&(r&ti)===0)return $;if(v){var B=e.$$legacy;return(function(ne,Qe){return arguments.length>0?((!o||!Qe||B||S)&&v(Qe?$():ne),ne):$()})}var x=!1,A=((r&Zl)!==0?Ln:Ve)(()=>(x=!1,$()));l&&n(A);var ae=Z;return(function(ne,Qe){if(arguments.length>0){const pe=Qe?n(A):o&&l?Or(ne):ne;return U(A,pe),x=!0,a!==void 0&&(a=pe),ne}return hr&&x||(ae.f&Pt)!==0?A.v:n(A)})}function $a(e){return new Ca(e)}class Ca{constructor(t){W(this,or);W(this,St);var l;var r=new Map,s=(i,a)=>{var f=at(a,!1,!1);return r.set(i,f),f};const o=new Proxy({...t.props||{},$$events:{}},{get(i,a){return n(r.get(a)??s(a,Reflect.get(i,a)))},has(i,a){return a===Mo?!0:(n(r.get(a)??s(a,Reflect.get(i,a))),Reflect.has(i,a))},set(i,a,f){return U(r.get(a)??s(a,f),f),Reflect.set(i,a,f)}});G(this,St,(t.hydrate?ia:yl)(t.component,{target:t.target,anchor:t.anchor,props:o,context:t.context,intro:t.intro??!1,recover:t.recover,transformError:t.transformError})),(!((l=t==null?void 0:t.props)!=null&&l.$$host)||t.sync===!1)&&Ht(),G(this,or,o.$$events);for(const i of Object.keys(u(this,St)))i==="$set"||i==="$destroy"||i==="$on"||es(this,i,{get(){return u(this,St)[i]},set(a){u(this,St)[i]=a},enumerable:!0});u(this,St).$set=i=>{Object.assign(o,i)},u(this,St).$destroy=()=>{aa(u(this,St))}}$set(t){u(this,St).$set(t)}$on(t,r){u(this,or)[t]=u(this,or)[t]||[];const s=(...o)=>r.call(this,...o);return u(this,or)[t].push(s),()=>{u(this,or)[t]=u(this,or)[t].filter(o=>o!==s)}}$destroy(){u(this,St).$destroy()}}or=new WeakMap,St=new WeakMap;let Rl;typeof HTMLElement=="function"&&(Rl=class extends HTMLElement{constructor(t,r,s){super();ke(this,"$$ctor");ke(this,"$$s");ke(this,"$$c");ke(this,"$$cn",!1);ke(this,"$$d",{});ke(this,"$$r",!1);ke(this,"$$p_d",{});ke(this,"$$l",{});ke(this,"$$l_u",new Map);ke(this,"$$me");ke(this,"$$shadowRoot",null);this.$$ctor=t,this.$$s=r,s&&(this.$$shadowRoot=this.attachShadow(s))}addEventListener(t,r,s){if(this.$$l[t]=this.$$l[t]||[],this.$$l[t].push(r),this.$$c){const o=this.$$c.$on(t,r);this.$$l_u.set(r,o)}super.addEventListener(t,r,s)}removeEventListener(t,r,s){if(super.removeEventListener(t,r,s),this.$$c){const o=this.$$l_u.get(r);o&&(o(),this.$$l_u.delete(r))}}async connectedCallback(){if(this.$$cn=!0,!this.$$c){let t=function(o){return l=>{const i=ls("slot");o!=="default"&&(i.name=o),w(l,i)}};if(await Promise.resolve(),!this.$$cn||this.$$c)return;const r={},s=Sa(this);for(const o of this.$$s)o in s&&(o==="default"&&!this.$$d.children?(this.$$d.children=t(o),r.default=!0):r[o]=t(o));for(const o of this.attributes){const l=this.$$g_p(o.name);l in this.$$d||(this.$$d[l]=ds(l,o.value,this.$$p_d,"toProp"))}for(const o in this.$$p_d)!(o in this.$$d)&&this[o]!==void 0&&(this.$$d[o]=this[o],delete this[o]);this.$$c=$a({component:this.$$ctor,target:this.$$shadowRoot||this,props:{...this.$$d,$$slots:r,$$host:this}}),this.$$me=Wi(()=>{Un(()=>{var o;this.$$r=!0;for(const l of Zn(this.$$c)){if(!((o=this.$$p_d[l])!=null&&o.reflect))continue;this.$$d[l]=this.$$c[l];const i=ds(l,this.$$d[l],this.$$p_d,"toAttribute");i==null?this.removeAttribute(this.$$p_d[l].attribute||l):this.setAttribute(this.$$p_d[l].attribute||l,i)}this.$$r=!1})});for(const o in this.$$l)for(const l of this.$$l[o]){const i=this.$$c.$on(o,l);this.$$l_u.set(l,i)}this.$$l={}}}attributeChangedCallback(t,r,s){var o;this.$$r||(t=this.$$g_p(t),this.$$d[t]=ds(t,s,this.$$p_d,"toProp"),(o=this.$$c)==null||o.$set({[t]:this.$$d[t]}))}disconnectedCallback(){this.$$cn=!1,Promise.resolve().then(()=>{!this.$$cn&&this.$$c&&(this.$$c.$destroy(),this.$$me(),this.$$c=void 0)})}$$g_p(t){return Zn(this.$$p_d).find(r=>this.$$p_d[r].attribute===t||!this.$$p_d[r].attribute&&r.toLowerCase()===t)||t}});function ds(e,t,r,s){var l;const o=(l=r[e])==null?void 0:l.type;if(t=o==="Boolean"&&typeof t!="boolean"?t!=null:t,!s||!r[e])return t;if(s==="toAttribute")switch(o){case"Object":case"Array":return t==null?null:JSON.stringify(t);case"Boolean":return t?"":null;case"Number":return t??null;default:return t}else switch(o){case"Object":case"Array":return t&&JSON.parse(t);case"Boolean":return t;case"Number":return t!=null?+t:t;default:return t}}function Sa(e){const t={};return e.childNodes.forEach(r=>{t[r.slot||"default"]=!0}),t}function Ks(e,t,r,s,o,l){let i=class extends Rl{constructor(){super(e,r,o),this.$$p_d=t}static get observedAttributes(){return Zn(t).map(a=>(t[a].attribute||a).toLowerCase())}};return Zn(t).forEach(a=>{es(i.prototype,a,{get(){return this.$$c&&a in this.$$c?this.$$c[a]:this.$$d[a]},set(f){var m;f=ds(a,f,t),this.$$d[a]=f;var c=this.$$c;if(c){var v=(m=Dr(c,a))==null?void 0:m.get;v?c[a]=f:c.$set({[a]:f})}}})}),s.forEach(a=>{es(i.prototype,a,{get(){var f;return(f=this.$$c)==null?void 0:f[a]}})}),e.element=i,i}async function Il(e,t){const r=t?`/api/orgs/${e}/projects/${t}/timeline`:`/api/orgs/${e}/timeline`,s=await fetch(r,{credentials:"same-origin"});if(!s.ok)throw new Error(`Timeline fetch failed: ${s.status}`);return s.json()}function Da(e,t,r){const s=t?`/orgs/${e}/projects/${t}/events`:`/orgs/${e}/events`;let o=1e3,l=null,i=!1;function a(){if(!i){l=new EventSource(s),l.addEventListener("open",()=>{o=1e3});for(const f of["destination","release","artifact","pipeline"])l.addEventListener(f,c=>{try{const v=JSON.parse(c.data);r(f,v)}catch(v){console.warn(`[release-timeline] bad ${f} event:`,v)}});l.addEventListener("error",()=>{l.close(),i||(setTimeout(a,o),o=Math.min(o*2,3e4))})}}return a(),()=>{i=!0,l&&l.close()}}function Ll(e){if(e<0&&(e=0),e<60)return`${e}s`;const t=Math.floor(e/60),r=e%60;return t<60?`${t}m ${r}s`:`${Math.floor(t/60)}h ${t%60}m`}function pn(e){if(!e)return"";const t=new Date(e),r=Date.now(),s=Math.floor((r-t.getTime())/1e3);return s<10?"just now":s<60?`${s}s ago`:s<3600?`${Math.floor(s/60)}m ago`:s<86400?`${Math.floor(s/3600)}h ago`:`${Math.floor(s/86400)}d ago`}const Js={prod:["#ec4899","#fce7f3"],production:["#ec4899","#fce7f3"],preprod:["#f97316","#ffedd5"],"pre-prod":["#f97316","#ffedd5"],staging:["#eab308","#fef9c3"],stage:["#eab308","#fef9c3"],dev:["#8b5cf6","#ede9fe"],development:["#8b5cf6","#ede9fe"],test:["#06b6d4","#cffafe"]},Na=["#6b7280","#e5e7eb"];function Ta(e){const t=e.toLowerCase();if(Js[t])return Js[t];for(const[r,s]of Object.entries(Js))if(t.includes(r))return s;return Na}function xr(e){const t=e.toLowerCase();return t.includes("prod")&&!t.includes("preprod")&&!t.includes("pre-prod")?{bg:"bg-pink-100 text-pink-800",dot:"bg-pink-500"}:t.includes("preprod")||t.includes("pre-prod")?{bg:"bg-orange-100 text-orange-800",dot:"bg-orange-500"}:t.includes("stag")?{bg:"bg-yellow-100 text-yellow-800",dot:"bg-yellow-500"}:t.includes("dev")?{bg:"bg-violet-100 text-violet-800",dot:"bg-violet-500"}:{bg:"bg-gray-100 text-gray-700",dot:"bg-gray-400"}}function ql(e){switch(e){case"SUCCEEDED":return"bg-green-500";case"RUNNING":return"bg-yellow-500";case"FAILED":return"bg-red-500";default:return null}}const Xs={SUCCEEDED:{label:"Deployed to",stageLabel:"Deployed to",color:"text-green-600",icon:"check-circle",iconColor:"text-green-500"},RUNNING:{label:"Deploying to",stageLabel:"Deploying to",color:"text-yellow-700",icon:"pulse",iconColor:"text-yellow-500"},ASSIGNED:{label:"Deploying to",stageLabel:"Deploying to",color:"text-yellow-700",icon:"pulse",iconColor:"text-yellow-500"},QUEUED:{label:"Queued for",stageLabel:"Queued for",color:"text-blue-600",icon:"clock",iconColor:"text-blue-400"},FAILED:{label:"Failed on",stageLabel:"Failed on",color:"text-red-600",icon:"x-circle",iconColor:"text-red-500"},TIMED_OUT:{label:"Timed out on",stageLabel:"Timed out on",color:"text-orange-600",icon:"clock",iconColor:"text-orange-500"},CANCELLED:{label:"Cancelled",stageLabel:"Cancelled",color:"text-gray-500",icon:"ban",iconColor:"text-gray-400"}};function hn(e){if(!e||e.length===0)return null;let t=!0,r=!1,s=!1,o=!1,l=!1,i=0;const a=e.length;for(const c of e)c.status==="SUCCEEDED"&&i++,c.status!=="SUCCEEDED"&&(t=!1),c.status==="FAILED"&&(r=!0),c.status==="RUNNING"&&(s=!0),c.status==="QUEUED"&&(l=!0),c.stage_type==="wait"&&c.status==="RUNNING"&&(o=!0);let f=e.some(c=>c.blocked_by);return t?{label:"Pipeline complete",color:"text-gray-600",icon:"check-circle",iconColor:"text-green-500",done:i,total:a}:r?{label:"Pipeline failed",color:"text-red-600",icon:"x-circle",iconColor:"text-red-500",done:i,total:a}:f?{label:"Awaiting approval",color:"text-emerald-700",icon:"shield",iconColor:"text-emerald-500",done:i,total:a}:o?{label:"Waiting for time window",color:"text-yellow-700",icon:"clock",iconColor:"text-yellow-500",done:i,total:a}:s?{label:"Deploying to",color:"text-yellow-700",icon:"pulse",iconColor:"text-yellow-500",done:i,total:a}:l?{label:"Queued",color:"text-blue-600",icon:"clock",iconColor:"text-blue-400",done:i,total:a}:{label:"Pipeline pending",color:"text-gray-400",icon:"pending",iconColor:"text-gray-300",done:i,total:a}}function Ol(e){switch(e){case"SUCCEEDED":return"Waited";case"RUNNING":return"Waiting";case"FAILED":return"Wait failed";case"CANCELLED":return"Wait cancelled";default:return"Wait"}}function Ul(e){switch(e){case"SUCCEEDED":return"Deployed to";case"RUNNING":return"Deploying to";case"QUEUED":return"Queued for";case"FAILED":return"Failed on";case"TIMED_OUT":return"Timed out on";case"CANCELLED":return"Cancelled";default:return"Deploy to"}}var Aa=C('
'),Ma=C('

Loading releases...

'),Ra=C('

'),Ia=C('

No releases yet.

Create a release with forest release create

'),La=C('
'),qa=C('
'),Oa=C('
'),Ua=C(" ",1),ja=C('
'),Ba=C(' '),Fa=C(' '),Pa=C(' '),za=C(' '),Ha=C(' Deployed',1),Ga=C(' Queued',1),Va=Le('',1),Wa=C(''),Ya=Le(''),Qa=Le(''),Ka=Le(''),Ja=Le(''),Xa=Le(''),Za=C(" "),ef=C(''),tf=C(''),rf=C(" ",1),nf=C(' ',1),sf=C(' Deployed',1),of=C(''),lf=Le(''),af=Le(''),ff=C(" "),cf=C(" ",1),uf=C(' Pending',1),df=C('

'),vf=C(' '),pf=Le(''),hf=C(''),_f=Le(''),gf=Le(''),mf=Le(''),xf=C(" ",1),bf=C(" "),wf=C(' '),kf=C('
pipeline
'),yf=C('
'),Ef=Le(''),$f=C(''),Cf=Le(''),Sf=Le(''),Df=Le(''),Nf=C('Deployed'),Tf=C('Deploying'),Af=C(' '),Mf=C('Failed'),Rf=C(''),If=C('
'),Lf=C(''),qf=C(' '),Of=C(''),Uf=C('
·
'),jf=C('
'),Bf=C('
'),Ff=C(" ",1);const Pf={hash:"svelte-4kxpm1",code:` +var Hc=Object.defineProperty;var nl=be=>{throw TypeError(be)};var Vc=(be,ve,Pe)=>ve in be?Hc(be,ve,{enumerable:!0,configurable:!0,writable:!0,value:Pe}):be[ve]=Pe;var Ce=(be,ve,Pe)=>Vc(be,typeof ve!="symbol"?ve+"":ve,Pe),yo=(be,ve,Pe)=>ve.has(be)||nl("Cannot "+Pe);var d=(be,ve,Pe)=>(yo(be,ve,"read from private field"),Pe?Pe.call(be):ve.get(be)),ee=(be,ve,Pe)=>ve.has(be)?nl("Cannot add the same private member more than once"):ve instanceof WeakSet?ve.add(be):ve.set(be,Pe),Q=(be,ve,Pe,as)=>(yo(be,ve,"write to private field"),as?as.call(be,Pe):ve.set(be,Pe),Pe),Ae=(be,ve,Pe)=>(yo(be,ve,"access private method"),Pe);(function(){"use strict";var Ya,Qa,$r,Cn,tn,An,Sn,Nn,Cr,tr,Dn,vt,Eo,$o,Co,Ao,gt,Xn,rr,rn,pt,nr,xt,zt,cr,nn,Ar,Tn,In,Mn,ur,ks,Ee,sl,ol,al,So,Ns,Ds,No,Ja,Gt,sr,bt,sn,Zn,es,ys,dr,It;typeof window<"u"&&((Ya=window.__svelte??(window.__svelte={})).v??(Ya.v=new Set)).add("5");let ve=!1,Pe=!1;function as(){ve=!0}as();const ll=1,il=2,Do=4,fl=8,cl=16,ul=1,dl=2,vl=4,pl=8,hl=16,To=1,_l=2,Io="[",Ts="[!",Mo="[?",Is="]",Or={},Ge=Symbol(),Ro="http://www.w3.org/1999/xhtml",ml="http://www.w3.org/2000/svg",gl="http://www.w3.org/1998/Math/MathML",Ms=!1;var Lo=Array.isArray,xl=Array.prototype.indexOf,vn=Array.prototype.includes,ls=Array.from,is=Object.keys,fs=Object.defineProperty,jr=Object.getOwnPropertyDescriptor,Po=Object.getOwnPropertyDescriptors,bl=Object.prototype,wl=Array.prototype,Rs=Object.getPrototypeOf,Oo=Object.isExtensible;const kl=()=>{};function yl(e){return e()}function Ls(e){for(var t=0;t{e=s,t=o});return{promise:n,resolve:e,reject:t}}const He=2,pn=4,qr=8,Ps=1<<24,mr=16,Ot=32,gr=64,Os=128,$t=512,je=1024,Ve=2048,Ct=4096,Ze=8192,Qt=16384,Ur=32768,hn=65536,qo=1<<17,El=1<<18,Fr=1<<19,Uo=1<<20,Jt=1<<25,Br=65536,js=1<<21,qs=1<<22,xr=1<<23,zr=Symbol("$state"),Fo=Symbol("legacy props"),$l=Symbol(""),Gr=new class extends Error{constructor(){super(...arguments);Ce(this,"name","StaleReactionError");Ce(this,"message","The reaction that called `getAbortSignal()` was re-run or destroyed")}},Cl=!!((Qa=globalThis.document)!=null&&Qa.contentType)&&globalThis.document.contentType.includes("xml"),Un=3,_n=8;function Bo(e){throw new Error("https://svelte.dev/e/lifecycle_outside_component")}function Al(){throw new Error("https://svelte.dev/e/async_derived_orphan")}function Sl(e,t,n){throw new Error("https://svelte.dev/e/each_key_duplicate")}function Nl(e){throw new Error("https://svelte.dev/e/effect_in_teardown")}function Dl(){throw new Error("https://svelte.dev/e/effect_in_unowned_derived")}function Tl(e){throw new Error("https://svelte.dev/e/effect_orphan")}function Il(){throw new Error("https://svelte.dev/e/effect_update_depth_exceeded")}function Ml(){throw new Error("https://svelte.dev/e/hydration_failed")}function Rl(e){throw new Error("https://svelte.dev/e/props_invalid_value")}function Ll(){throw new Error("https://svelte.dev/e/state_descriptors_fixed")}function Pl(){throw new Error("https://svelte.dev/e/state_prototype_fixed")}function Ol(){throw new Error("https://svelte.dev/e/state_unsafe_mutation")}function jl(){throw new Error("https://svelte.dev/e/svelte_boundary_reset_onerror")}function Fn(e){console.warn("https://svelte.dev/e/hydration_mismatch")}function ql(){console.warn("https://svelte.dev/e/svelte_boundary_reset_noop")}let ne=!1;function ar(e){ne=e}let W;function Xe(e){if(e===null)throw Fn(),Or;return W=e}function mn(){return Xe(Ut(W))}function w(e){if(ne){if(Ut(W)!==null)throw Fn(),Or;W=e}}function lr(e=1){if(ne){for(var t=e,n=W;t--;)n=Ut(n);W=n}}function cs(e=!0){for(var t=0,n=W;;){if(n.nodeType===_n){var s=n.data;if(s===Is){if(t===0)return n;t-=1}else(s===Io||s===Ts||s[0]==="["&&!isNaN(Number(s.slice(1))))&&(t+=1)}var o=Ut(n);e&&n.remove(),n=o}}function zo(e){if(!e||e.nodeType!==_n)throw Fn(),Or;return e.data}function Go(e){return e===this.v}function Ul(e,t){return e!=e?t==t:e!==t||e!==null&&typeof e=="object"||typeof e=="function"}function Ho(e){return!Ul(e,this.v)}let we=null;function gn(e){we=e}function us(e,t=!1,n){we={p:we,i:!1,c:null,e:null,s:e,x:null,l:ve&&!t?{s:null,u:null,$:[]}:null}}function ds(e){var t=we,n=t.e;if(n!==null){t.e=null;for(var s of n)da(s)}return e!==void 0&&(t.x=e),t.i=!0,we=t.p,e??{}}function Bn(){return!ve||we!==null&&we.l===null}let Hr=[];function Vo(){var e=Hr;Hr=[],Ls(e)}function ir(e){if(Hr.length===0&&!zn){var t=Hr;queueMicrotask(()=>{t===Hr&&Vo()})}Hr.push(e)}function Fl(){for(;Hr.length>0;)Vo()}function Wo(e){var t=se;if(t===null)return te.f|=xr,e;if((t.f&Ur)===0&&(t.f&pn)===0)throw e;br(e,t)}function br(e,t){for(;t!==null;){if((t.f&Os)!==0){if((t.f&Ur)===0)throw e;try{t.b.error(e);return}catch(n){e=n}}t=t.parent}throw e}const Bl=-7169;function ye(e,t){e.f=e.f&Bl|t}function Us(e){(e.f&$t)!==0||e.deps===null?ye(e,je):ye(e,Ct)}function Yo(e){if(e!==null)for(const t of e)(t.f&He)===0||(t.f&Br)===0||(t.f^=Br,Yo(t.deps))}function Qo(e,t,n){(e.f&Ve)!==0?t.add(e):(e.f&Ct)!==0&&n.add(e),Yo(e.deps),ye(e,je)}const vs=new Set;let le=null,We=null,ct=[],ps=null,zn=!1,xn=null,zl=1;const fo=class fo{constructor(){ee(this,vt);Ce(this,"id",zl++);Ce(this,"current",new Map);Ce(this,"previous",new Map);ee(this,$r,new Set);ee(this,Cn,new Set);ee(this,tn,0);ee(this,An,0);ee(this,Sn,null);ee(this,Nn,new Set);ee(this,Cr,new Set);ee(this,tr,new Map);Ce(this,"is_fork",!1);ee(this,Dn,!1)}skip_effect(t){d(this,tr).has(t)||d(this,tr).set(t,{d:[],m:[]})}unskip_effect(t){var n=d(this,tr).get(t);if(n){d(this,tr).delete(t);for(var s of n.d)ye(s,Ve),Xt(s);for(s of n.m)ye(s,Ct),Xt(s)}}process(t){var o;ct=[],this.apply();var n=xn=[],s=[];for(const a of t)Ae(this,vt,$o).call(this,a,n,s);if(xn=null,Ae(this,vt,Eo).call(this)){Ae(this,vt,Co).call(this,s),Ae(this,vt,Co).call(this,n);for(const[a,l]of d(this,tr))ea(a,l)}else{le=null;for(const a of d(this,$r))a(this);d(this,$r).clear(),d(this,tn)===0&&Ae(this,vt,Ao).call(this),Ko(s),Ko(n),d(this,Nn).clear(),d(this,Cr).clear(),(o=d(this,Sn))==null||o.resolve()}We=null}capture(t,n){n!==Ge&&!this.previous.has(t)&&this.previous.set(t,n),(t.f&xr)===0&&(this.current.set(t,t.v),We==null||We.set(t,t.v))}activate(){le=this,this.apply()}deactivate(){le===this&&(le=null,We=null)}flush(){var t;if(ct.length>0)le=this,Jo();else if(d(this,tn)===0&&!this.is_fork){for(const n of d(this,$r))n(this);d(this,$r).clear(),Ae(this,vt,Ao).call(this),(t=d(this,Sn))==null||t.resolve()}this.deactivate()}discard(){for(const t of d(this,Cn))t(this);d(this,Cn).clear()}increment(t){Q(this,tn,d(this,tn)+1),t&&Q(this,An,d(this,An)+1)}decrement(t){Q(this,tn,d(this,tn)-1),t&&Q(this,An,d(this,An)-1),!d(this,Dn)&&(Q(this,Dn,!0),ir(()=>{Q(this,Dn,!1),Ae(this,vt,Eo).call(this)?ct.length>0&&this.flush():this.revive()}))}revive(){for(const t of d(this,Nn))d(this,Cr).delete(t),ye(t,Ve),Xt(t);for(const t of d(this,Cr))ye(t,Ct),Xt(t);this.flush()}oncommit(t){d(this,$r).add(t)}ondiscard(t){d(this,Cn).add(t)}settled(){return(d(this,Sn)??Q(this,Sn,jo())).promise}static ensure(){if(le===null){const t=le=new fo;vs.add(le),zn||ir(()=>{le===t&&t.flush()})}return le}apply(){}};$r=new WeakMap,Cn=new WeakMap,tn=new WeakMap,An=new WeakMap,Sn=new WeakMap,Nn=new WeakMap,Cr=new WeakMap,tr=new WeakMap,Dn=new WeakMap,vt=new WeakSet,Eo=function(){return this.is_fork||d(this,An)>0},$o=function(t,n,s){t.f^=je;for(var o=t.first;o!==null;){var a=o.f,l=(a&(Ot|gr))!==0,i=l&&(a&je)!==0,f=(a&Ze)!==0,u=i||d(this,tr).has(o);if(!u&&o.fn!==null){l?f||(o.f^=je):(a&pn)!==0?n.push(o):(a&(qr|Ps))!==0&&f?s.push(o):wn(o)&&(Kr(o),(a&mr)!==0&&(d(this,Cr).add(o),f&&ye(o,Ve)));var v=o.first;if(v!==null){o=v;continue}}for(;o!==null;){var x=o.next;if(x!==null){o=x;break}o=o.parent}}},Co=function(t){for(var n=0;n1){this.previous.clear();var t=le,n=We,s=!0;for(const l of vs){if(l===this){s=!1;continue}const i=[];for(const[u,v]of this.current){if(l.current.has(u))if(s&&v!==l.current.get(u))l.current.set(u,v);else continue;i.push(u)}if(i.length===0)continue;const f=[...l.current.keys()].filter(u=>!this.current.has(u));if(f.length>0){var o=ct;ct=[];const u=new Set,v=new Map;for(const x of i)Xo(x,f,u,v);if(ct.length>0){le=l,l.apply();for(const x of ct)Ae(a=l,vt,$o).call(a,x,[],[]);l.deactivate()}ct=o}}le=t,We=n}d(this,tr).clear(),vs.delete(this)};let fr=fo;function Kt(e){var t=zn;zn=!0;try{for(var n;;){if(Fl(),ct.length===0&&(le==null||le.flush(),ct.length===0))return ps=null,n;Jo()}}finally{zn=t}}function Jo(){var e=null;try{for(var t=0;ct.length>0;){var n=fr.ensure();if(t++>1e3){var s,o;Gl()}n.process(ct),wr.clear()}}finally{ct=[],ps=null,xn=null}}function Gl(){try{Il()}catch(e){br(e,ps)}}let jt=null;function Ko(e){var t=e.length;if(t!==0){for(var n=0;n0)){wr.clear();for(const o of jt){if((o.f&(Qt|Ze))!==0)continue;const a=[o];let l=o.parent;for(;l!==null;)jt.has(l)&&(jt.delete(l),a.push(l)),l=l.parent;for(let i=a.length-1;i>=0;i--){const f=a[i];(f.f&(Qt|Ze))===0&&Kr(f)}}jt.clear()}}jt=null}}function Xo(e,t,n,s){if(!n.has(e)&&(n.add(e),e.reactions!==null))for(const o of e.reactions){const a=o.f;(a&He)!==0?Xo(o,t,n,s):(a&(qs|mr))!==0&&(a&Ve)===0&&Zo(o,t,s)&&(ye(o,Ve),Xt(o))}}function Zo(e,t,n){const s=n.get(e);if(s!==void 0)return s;if(e.deps!==null)for(const o of e.deps){if(vn.call(t,o))return!0;if((o.f&He)!==0&&Zo(o,t,n))return n.set(o,!0),!0}return n.set(e,!1),!1}function Xt(e){var t=ps=e,n=t.b;if(n!=null&&n.is_pending&&(e.f&(pn|qr|Ps))!==0&&(e.f&Ur)===0){n.defer_effect(e);return}for(;t.parent!==null;){t=t.parent;var s=t.f;if(xn!==null&&t===se&&(e.f&qr)===0)return;if((s&(gr|Ot))!==0){if((s&je)===0)return;t.f^=je}}ct.push(t)}function ea(e,t){if(!((e.f&Ot)!==0&&(e.f&je)!==0)){(e.f&Ve)!==0?t.d.push(e):(e.f&Ct)!==0&&t.m.push(e),ye(e,je);for(var n=e.first;n!==null;)ea(n,t),n=n.next}}function Hl(e){let t=0,n=Vr(0),s;return()=>{Ws()&&(r(n),Wn(()=>(t===0&&(s=c(()=>e(()=>Hn(n)))),t+=1,()=>{ir(()=>{t-=1,t===0&&(s==null||s(),s=void 0,Hn(n))})})))}}var Vl=hn|Fr;function Wl(e,t,n,s){new Yl(e,t,n,s)}class Yl{constructor(t,n,s,o){ee(this,Ee);Ce(this,"parent");Ce(this,"is_pending",!1);Ce(this,"transform_error");ee(this,gt);ee(this,Xn,ne?W:null);ee(this,rr);ee(this,rn);ee(this,pt);ee(this,nr,null);ee(this,xt,null);ee(this,zt,null);ee(this,cr,null);ee(this,nn,0);ee(this,Ar,0);ee(this,Tn,!1);ee(this,In,new Set);ee(this,Mn,new Set);ee(this,ur,null);ee(this,ks,Hl(()=>(Q(this,ur,Vr(d(this,nn))),()=>{Q(this,ur,null)})));var a;Q(this,gt,t),Q(this,rr,n),Q(this,rn,l=>{var i=se;i.b=this,i.f|=Os,s(l)}),this.parent=se.b,this.transform_error=o??((a=this.parent)==null?void 0:a.transform_error)??(l=>l),Q(this,pt,Qs(()=>{if(ne){const l=d(this,Xn);mn();const i=l.data===Ts;if(l.data.startsWith(Mo)){const u=JSON.parse(l.data.slice(Mo.length));Ae(this,Ee,ol).call(this,u)}else i?Ae(this,Ee,al).call(this):Ae(this,Ee,sl).call(this)}else Ae(this,Ee,So).call(this)},Vl)),ne&&Q(this,gt,W)}defer_effect(t){Qo(t,d(this,In),d(this,Mn))}is_rendered(){return!this.is_pending&&(!this.parent||this.parent.is_rendered())}has_pending_snippet(){return!!d(this,rr).pending}update_pending_count(t){Ae(this,Ee,No).call(this,t),Q(this,nn,d(this,nn)+t),!(!d(this,ur)||d(this,Tn))&&(Q(this,Tn,!0),ir(()=>{Q(this,Tn,!1),d(this,ur)&&bn(d(this,ur),d(this,nn))}))}get_effect_pending(){return d(this,ks).call(this),r(d(this,ur))}error(t){var n=d(this,rr).onerror;let s=d(this,rr).failed;if(!n&&!s)throw t;d(this,nr)&&(rt(d(this,nr)),Q(this,nr,null)),d(this,xt)&&(rt(d(this,xt)),Q(this,xt,null)),d(this,zt)&&(rt(d(this,zt)),Q(this,zt,null)),ne&&(Xe(d(this,Xn)),lr(),Xe(cs()));var o=!1,a=!1;const l=()=>{if(o){ql();return}o=!0,a&&jl(),d(this,zt)!==null&&Yr(d(this,zt),()=>{Q(this,zt,null)}),Ae(this,Ee,Ds).call(this,()=>{fr.ensure(),Ae(this,Ee,So).call(this)})},i=f=>{try{a=!0,n==null||n(f,l),a=!1}catch(u){br(u,d(this,pt)&&d(this,pt).parent)}s&&Q(this,zt,Ae(this,Ee,Ds).call(this,()=>{fr.ensure();try{return At(()=>{var u=se;u.b=this,u.f|=Os,s(d(this,gt),()=>f,()=>l)})}catch(u){return br(u,d(this,pt).parent),null}}))};ir(()=>{var f;try{f=this.transform_error(t)}catch(u){br(u,d(this,pt)&&d(this,pt).parent);return}f!==null&&typeof f=="object"&&typeof f.then=="function"?f.then(i,u=>br(u,d(this,pt)&&d(this,pt).parent)):i(f)})}}gt=new WeakMap,Xn=new WeakMap,rr=new WeakMap,rn=new WeakMap,pt=new WeakMap,nr=new WeakMap,xt=new WeakMap,zt=new WeakMap,cr=new WeakMap,nn=new WeakMap,Ar=new WeakMap,Tn=new WeakMap,In=new WeakMap,Mn=new WeakMap,ur=new WeakMap,ks=new WeakMap,Ee=new WeakSet,sl=function(){try{Q(this,nr,At(()=>d(this,rn).call(this,d(this,gt))))}catch(t){this.error(t)}},ol=function(t){const n=d(this,rr).failed;n&&Q(this,zt,At(()=>{n(d(this,gt),()=>t,()=>()=>{})}))},al=function(){const t=d(this,rr).pending;t&&(this.is_pending=!0,Q(this,xt,At(()=>t(d(this,gt)))),ir(()=>{var n=Q(this,cr,document.createDocumentFragment()),s=ut();n.append(s),Q(this,nr,Ae(this,Ee,Ds).call(this,()=>(fr.ensure(),At(()=>d(this,rn).call(this,s))))),d(this,Ar)===0&&(d(this,gt).before(n),Q(this,cr,null),Yr(d(this,xt),()=>{Q(this,xt,null)}),Ae(this,Ee,Ns).call(this))}))},So=function(){try{if(this.is_pending=this.has_pending_snippet(),Q(this,Ar,0),Q(this,nn,0),Q(this,nr,At(()=>{d(this,rn).call(this,d(this,gt))})),d(this,Ar)>0){var t=Q(this,cr,document.createDocumentFragment());Xs(d(this,nr),t);const n=d(this,rr).pending;Q(this,xt,At(()=>n(d(this,gt))))}else Ae(this,Ee,Ns).call(this)}catch(n){this.error(n)}},Ns=function(){this.is_pending=!1;for(const t of d(this,In))ye(t,Ve),Xt(t);for(const t of d(this,Mn))ye(t,Ct),Xt(t);d(this,In).clear(),d(this,Mn).clear()},Ds=function(t){var n=se,s=te,o=we;Zt(d(this,pt)),St(d(this,pt)),gn(d(this,pt).ctx);try{return t()}catch(a){return Wo(a),null}finally{Zt(n),St(s),gn(o)}},No=function(t){var n;if(!this.has_pending_snippet()){this.parent&&Ae(n=this.parent,Ee,No).call(n,t);return}Q(this,Ar,d(this,Ar)+t),d(this,Ar)===0&&(Ae(this,Ee,Ns).call(this),d(this,xt)&&Yr(d(this,xt),()=>{Q(this,xt,null)}),d(this,cr)&&(d(this,gt).before(d(this,cr)),Q(this,cr,null)))};function Ql(e,t,n,s){const o=Bn()?Gn:qe;var a=e.filter(x=>!x.settled);if(n.length===0&&a.length===0){s(t.map(o));return}var l=se,i=Jl(),f=a.length===1?a[0].promise:a.length>1?Promise.all(a.map(x=>x.promise)):null;function u(x){i();try{s(x)}catch(y){(l.f&Qt)===0&&br(y,l)}Fs()}if(n.length===0){f.then(()=>u(t.map(o)));return}function v(){i(),Promise.all(n.map(x=>Xl(x))).then(x=>u([...t.map(o),...x])).catch(x=>br(x,l))}f?f.then(v):v()}function Jl(){var e=se,t=te,n=we,s=le;return function(a=!0){Zt(e),St(t),gn(n),a&&(s==null||s.activate())}}function Fs(e=!0){Zt(null),St(null),gn(null),e&&(le==null||le.deactivate())}function Kl(){var e=se.b,t=le,n=e.is_rendered();return e.update_pending_count(1),t.increment(n),()=>{e.update_pending_count(-1),t.decrement(n)}}function Gn(e){var t=He|Ve,n=te!==null&&(te.f&He)!==0?te:null;return se!==null&&(se.f|=Fr),{ctx:we,deps:null,effects:null,equals:Go,f:t,fn:e,reactions:null,rv:0,v:Ge,wv:0,parent:n??se,ac:null}}function Xl(e,t,n){se===null&&Al();var o=void 0,a=Vr(Ge),l=!te,i=new Map;return fi(()=>{var y;var f=jo();o=f.promise;try{Promise.resolve(e()).then(f.resolve,f.reject).finally(Fs)}catch(M){f.reject(M),Fs()}var u=le;if(l){var v=Kl();(y=i.get(u))==null||y.reject(Gr),i.delete(u),i.set(u,f)}const x=(M,N=void 0)=>{if(u.activate(),N)N!==Gr&&(a.f|=xr,bn(a,N));else{(a.f&xr)!==0&&(a.f^=xr),bn(a,M);for(const[H,k]of i){if(i.delete(H),H===u)break;k.reject(Gr)}}v&&v()};f.promise.then(x,M=>x(null,M||"unknown"))}),ua(()=>{for(const f of i.values())f.reject(Gr)}),new Promise(f=>{function u(v){function x(){v===o?f(a):u(o)}v.then(x,x)}u(o)})}function qt(e){const t=Gn(e);return ba(t),t}function qe(e){const t=Gn(e);return t.equals=Ho,t}function Zl(e){var t=e.effects;if(t!==null){e.effects=null;for(var n=0;nr(e))),t}function I(e,t,n=!1){te!==null&&(!Bt||(te.f&qo)!==0)&&Bn()&&(te.f&(He|mr|qs|qo))!==0&&(Nt===null||!vn.call(Nt,e))&&Ol();let s=n?Wr(t):t;return bn(e,s)}function bn(e,t){if(!e.equals(t)){var n=e.v;kr?wr.set(e,t):wr.set(e,n),e.v=t;var s=fr.ensure();if(s.capture(e,n),(e.f&He)!==0){const o=e;(e.f&Ve)!==0&&Bs(o),Us(o)}e.wv=ya(),sa(e,Ve),Bn()&&se!==null&&(se.f&je)!==0&&(se.f&(Ot|gr))===0&&(Dt===null?ui([e]):Dt.push(e)),!s.is_fork&&zs.size>0&&!na&&ni()}return t}function ni(){na=!1;for(const e of zs)(e.f&je)!==0&&ye(e,Ct),wn(e)&&Kr(e);zs.clear()}function Hn(e){I(e,e.v+1)}function sa(e,t){var n=e.reactions;if(n!==null)for(var s=Bn(),o=n.length,a=0;a{if(Jr===a)return i();var f=te,u=Jr;St(null),ka(a);var v=i();return St(f),ka(u),v};return s&&n.set("length",Ue(e.length)),new Proxy(e,{defineProperty(i,f,u){(!("value"in u)||u.configurable===!1||u.enumerable===!1||u.writable===!1)&&Ll();var v=n.get(f);return v===void 0?l(()=>{var x=Ue(u.value);return n.set(f,x),x}):I(v,u.value,!0),!0},deleteProperty(i,f){var u=n.get(f);if(u===void 0){if(f in i){const v=l(()=>Ue(Ge));n.set(f,v),Hn(o)}}else I(u,Ge),Hn(o);return!0},get(i,f,u){var M;if(f===zr)return e;var v=n.get(f),x=f in i;if(v===void 0&&(!x||(M=jr(i,f))!=null&&M.writable)&&(v=l(()=>{var N=Wr(x?i[f]:Ge),H=Ue(N);return H}),n.set(f,v)),v!==void 0){var y=r(v);return y===Ge?void 0:y}return Reflect.get(i,f,u)},getOwnPropertyDescriptor(i,f){var u=Reflect.getOwnPropertyDescriptor(i,f);if(u&&"value"in u){var v=n.get(f);v&&(u.value=r(v))}else if(u===void 0){var x=n.get(f),y=x==null?void 0:x.v;if(x!==void 0&&y!==Ge)return{enumerable:!0,configurable:!0,value:y,writable:!0}}return u},has(i,f){var y;if(f===zr)return!0;var u=n.get(f),v=u!==void 0&&u.v!==Ge||Reflect.has(i,f);if(u!==void 0||se!==null&&(!v||(y=jr(i,f))!=null&&y.writable)){u===void 0&&(u=l(()=>{var M=v?Wr(i[f]):Ge,N=Ue(M);return N}),n.set(f,u));var x=r(u);if(x===Ge)return!1}return v},set(i,f,u,v){var oe;var x=n.get(f),y=f in i;if(s&&f==="length")for(var M=u;MUe(Ge)),n.set(M+"",N))}if(x===void 0)(!y||(oe=jr(i,f))!=null&&oe.writable)&&(x=l(()=>Ue(void 0)),I(x,Wr(u)),n.set(f,x));else{y=x.v!==Ge;var H=l(()=>Wr(u));I(x,H)}var k=Reflect.getOwnPropertyDescriptor(i,f);if(k!=null&&k.set&&k.set.call(v,u),!y){if(s&&typeof f=="string"){var L=n.get("length"),ie=Number(f);Number.isInteger(ie)&&ie>=L.v&&I(L,ie+1)}Hn(o)}return!0},ownKeys(i){r(o);var f=Reflect.ownKeys(i).filter(x=>{var y=n.get(x);return y===void 0||y.v!==Ge});for(var[u,v]of n)v.v!==Ge&&!(u in i)&&f.push(u);return f},setPrototypeOf(){Pl()}})}var Gs,oa,aa,la;function Hs(){if(Gs===void 0){Gs=window,oa=/Firefox/.test(navigator.userAgent);var e=Element.prototype,t=Node.prototype,n=Text.prototype;aa=jr(t,"firstChild").get,la=jr(t,"nextSibling").get,Oo(e)&&(e.__click=void 0,e.__className=void 0,e.__attributes=null,e.__style=void 0,e.__e=void 0),Oo(n)&&(n.__t=void 0)}}function ut(e=""){return document.createTextNode(e)}function tt(e){return aa.call(e)}function Ut(e){return la.call(e)}function E(e,t){if(!ne)return tt(e);var n=tt(W);if(n===null)n=W.appendChild(ut());else if(t&&n.nodeType!==Un){var s=ut();return n==null||n.before(s),Xe(s),s}return t&&_s(n),Xe(n),n}function Fe(e,t=!1){if(!ne){var n=tt(e);return n instanceof Comment&&n.data===""?Ut(n):n}if(t){if((W==null?void 0:W.nodeType)!==Un){var s=ut();return W==null||W.before(s),Xe(s),s}_s(W)}return W}function A(e,t=1,n=!1){let s=ne?W:e;for(var o;t--;)o=s,s=Ut(s);if(!ne)return s;if(n){if((s==null?void 0:s.nodeType)!==Un){var a=ut();return s===null?o==null||o.after(a):s.before(a),Xe(a),a}_s(s)}return Xe(s),s}function ia(e){e.textContent=""}function fa(){return!1}function hs(e,t,n){return document.createElementNS(t??Ro,e,void 0)}function _s(e){if(e.nodeValue.length<65536)return;let t=e.nextSibling;for(;t!==null&&t.nodeType===Un;)t.remove(),e.nodeValue+=t.nodeValue,t=e.nextSibling}function Vs(e){var t=te,n=se;St(null),Zt(null);try{return e()}finally{St(t),Zt(n)}}function ca(e){se===null&&(te===null&&Tl(),Dl()),kr&&Nl()}function si(e,t){var n=t.last;n===null?t.last=t.first=e:(n.next=e,e.prev=n,t.last=e)}function Ft(e,t){var n=se;n!==null&&(n.f&Ze)!==0&&(e|=Ze);var s={ctx:we,deps:null,nodes:null,f:e|Ve|$t,first:null,fn:t,last:null,next:null,parent:n,b:n&&n.b,prev:null,teardown:null,wv:0,ac:null},o=s;if((e&pn)!==0)xn!==null?xn.push(s):Xt(s);else if(t!==null){try{Kr(s)}catch(l){throw rt(s),l}o.deps===null&&o.teardown===null&&o.nodes===null&&o.first===o.last&&(o.f&Fr)===0&&(o=o.first,(e&mr)!==0&&(e&hn)!==0&&o!==null&&(o.f|=hn))}if(o!==null&&(o.parent=n,n!==null&&si(o,n),te!==null&&(te.f&He)!==0&&(e&gr)===0)){var a=te;(a.effects??(a.effects=[])).push(o)}return s}function Ws(){return te!==null&&!Bt}function ua(e){const t=Ft(qr,null);return ye(t,je),t.teardown=e,t}function Vn(e){ca();var t=se.f,n=!te&&(t&Ot)!==0&&(t&Ur)===0;if(n){var s=we;(s.e??(s.e=[])).push(e)}else return da(e)}function da(e){return Ft(pn|Uo,e)}function oi(e){return ca(),Ft(qr|Uo,e)}function ai(e){fr.ensure();const t=Ft(gr|Fr,e);return()=>{rt(t)}}function li(e){fr.ensure();const t=Ft(gr|Fr,e);return(n={})=>new Promise(s=>{n.outro?Yr(t,()=>{rt(t),s(void 0)}):(rt(t),s(void 0))})}function va(e){return Ft(pn,e)}function Ys(e,t){var n=we,s={effect:null,ran:!1,deps:e};n.l.$.push(s),s.effect=Wn(()=>{e(),!s.ran&&(s.ran=!0,c(t))})}function ii(){var e=we;Wn(()=>{for(var t of e.l.$){t.deps();var n=t.effect;(n.f&je)!==0&&n.deps!==null&&ye(n,Ct),wn(n)&&Kr(n),t.ran=!1}})}function fi(e){return Ft(qs|Fr,e)}function Wn(e,t=0){return Ft(qr|t,e)}function O(e,t=[],n=[],s=[]){Ql(s,t,n,o=>{Ft(qr,()=>e(...o.map(r)))})}function Qs(e,t=0){var n=Ft(mr|t,e);return n}function At(e){return Ft(Ot|Fr,e)}function pa(e){var t=e.teardown;if(t!==null){const n=kr,s=te;xa(!0),St(null);try{t.call(null)}finally{xa(n),St(s)}}}function Js(e,t=!1){var n=e.first;for(e.first=e.last=null;n!==null;){const o=n.ac;o!==null&&Vs(()=>{o.abort(Gr)});var s=n.next;(n.f&gr)!==0?n.parent=null:rt(n,t),n=s}}function ci(e){for(var t=e.first;t!==null;){var n=t.next;(t.f&Ot)===0&&rt(t),t=n}}function rt(e,t=!0){var n=!1;(t||(e.f&El)!==0)&&e.nodes!==null&&e.nodes.end!==null&&(ha(e.nodes.start,e.nodes.end),n=!0),Js(e,t&&!n),Yn(e,0),ye(e,Qt);var s=e.nodes&&e.nodes.t;if(s!==null)for(const a of s)a.stop();pa(e);var o=e.parent;o!==null&&o.first!==null&&_a(e),e.next=e.prev=e.teardown=e.ctx=e.deps=e.fn=e.nodes=e.ac=null}function ha(e,t){for(;e!==null;){var n=e===t?null:Ut(e);e.remove(),e=n}}function _a(e){var t=e.parent,n=e.prev,s=e.next;n!==null&&(n.next=s),s!==null&&(s.prev=n),t!==null&&(t.first===e&&(t.first=s),t.last===e&&(t.last=n))}function Yr(e,t,n=!0){var s=[];ma(e,s,!0);var o=()=>{n&&rt(e),t&&t()},a=s.length;if(a>0){var l=()=>--a||o();for(var i of s)i.out(l)}else o()}function ma(e,t,n){if((e.f&Ze)===0){e.f^=Ze;var s=e.nodes&&e.nodes.t;if(s!==null)for(const i of s)(i.is_global||n)&&t.push(i);for(var o=e.first;o!==null;){var a=o.next,l=(o.f&hn)!==0||(o.f&Ot)!==0&&(e.f&mr)!==0;ma(o,t,l?n:!1),o=a}}}function Ks(e){ga(e,!0)}function ga(e,t){if((e.f&Ze)!==0){e.f^=Ze;for(var n=e.first;n!==null;){var s=n.next,o=(n.f&hn)!==0||(n.f&Ot)!==0;ga(n,o?t:!1),n=s}var a=e.nodes&&e.nodes.t;if(a!==null)for(const l of a)(l.is_global||t)&&l.in()}}function Xs(e,t){if(e.nodes)for(var n=e.nodes.start,s=e.nodes.end;n!==null;){var o=n===s?null:Ut(n);t.append(n),n=o}}let ms=!1,kr=!1;function xa(e){kr=e}let te=null,Bt=!1;function St(e){te=e}let se=null;function Zt(e){se=e}let Nt=null;function ba(e){te!==null&&(Nt===null?Nt=[e]:Nt.push(e))}let dt=null,ht=0,Dt=null;function ui(e){Dt=e}let wa=1,Qr=0,Jr=Qr;function ka(e){Jr=e}function ya(){return++wa}function wn(e){var t=e.f;if((t&Ve)!==0)return!0;if(t&He&&(e.f&=~Br),(t&Ct)!==0){for(var n=e.deps,s=n.length,o=0;oe.wv)return!0}(t&$t)!==0&&We===null&&ye(e,je)}return!1}function Ea(e,t,n=!0){var s=e.reactions;if(s!==null&&!(Nt!==null&&vn.call(Nt,e)))for(var o=0;o{e.ac.abort(Gr)}),e.ac=null);try{e.f|=js;var v=e.fn,x=v();e.f|=Ur;var y=e.deps,M=le==null?void 0:le.is_fork;if(dt!==null){var N;if(M||Yn(e,ht),y!==null&&ht>0)for(y.length=ht+dt.length,N=0;Nn==null?void 0:n.call(this,a))}return e.startsWith("pointer")||e.startsWith("touch")||e==="wheel"?ir(()=>{t.addEventListener(e,o,s)}):t.addEventListener(e,o,s),o}function Tt(e,t,n,s,o){var a={capture:s,passive:o},l=pi(e,t,n,a);(t===document.body||t===window||t===document||t instanceof HTMLMediaElement)&&ua(()=>{t.removeEventListener(e,l,a)})}function Qn(e,t,n){(t[Xr]??(t[Xr]={}))[e]=n}function Na(e){for(var t=0;t{throw ie});throw y}}finally{e[Xr]=t,delete e.currentTarget,St(v),Zt(x)}}}const ro=((Ja=globalThis==null?void 0:globalThis.window)==null?void 0:Ja.trustedTypes)&&globalThis.window.trustedTypes.createPolicy("svelte-trusted-html",{createHTML:e=>e});function hi(e){return(ro==null?void 0:ro.createHTML(e))??e}function Ta(e){var t=hs("template");return t.innerHTML=hi(e.replaceAll("","")),t.content}function _t(e,t){var n=se;n.nodes===null&&(n.nodes={start:e,end:t,a:null,t:null})}function D(e,t){var n=(t&To)!==0,s=(t&_l)!==0,o,a=!e.startsWith("");return()=>{if(ne)return _t(W,null),W;o===void 0&&(o=Ta(a?e:""+e),n||(o=tt(o)));var l=s||oa?document.importNode(o,!0):o.cloneNode(!0);if(n){var i=tt(l),f=l.lastChild;_t(i,f)}else _t(l,l);return l}}function _i(e,t,n="svg"){var s=!e.startsWith(""),o=(t&To)!==0,a=`<${n}>${s?e:""+e}`,l;return()=>{if(ne)return _t(W,null),W;if(!l){var i=Ta(a),f=tt(i);if(o)for(l=document.createDocumentFragment();tt(f);)l.appendChild(tt(f));else l=tt(f)}var u=l.cloneNode(!0);if(o){var v=tt(u),x=u.lastChild;_t(v,x)}else _t(u,u);return u}}function Oe(e,t){return _i(e,t,"svg")}function mi(e=""){if(!ne){var t=ut(e+"");return _t(t,t),t}var n=W;return n.nodeType!==Un?(n.before(n=ut()),Xe(n)):_s(n),_t(n,n),n}function kn(){if(ne)return _t(W,null),W;var e=document.createDocumentFragment(),t=document.createComment(""),n=ut();return e.append(t,n),_t(t,n),e}function m(e,t){if(ne){var n=se;((n.f&Ur)===0||n.nodes.end===null)&&(n.nodes.end=W),mn();return}e!==null&&e.before(t)}const gi=["touchstart","touchmove"];function xi(e){return gi.includes(e)}function B(e,t){var n=t==null?"":typeof t=="object"?`${t}`:t;n!==(e.__t??(e.__t=e.nodeValue))&&(e.__t=n,e.nodeValue=`${n}`)}function Ia(e,t){return Ma(e,t)}function bi(e,t){Hs(),t.intro=t.intro??!1;const n=t.target,s=ne,o=W;try{for(var a=tt(n);a&&(a.nodeType!==_n||a.data!==Io);)a=Ut(a);if(!a)throw Or;ar(!0),Xe(a);const l=Ma(e,{...t,anchor:a});return ar(!1),l}catch(l){if(l instanceof Error&&l.message.split(` +`).some(i=>i.startsWith("https://svelte.dev/e/")))throw l;return l!==Or&&console.warn("Failed to hydrate: ",l),t.recover===!1&&Ml(),Hs(),ia(n),ar(!1),Ia(e,t)}finally{ar(s),Xe(o)}}const gs=new Map;function Ma(e,{target:t,anchor:n,props:s={},events:o,context:a,intro:l=!0,transformError:i}){Hs();var f=void 0,u=li(()=>{var v=n??t.appendChild(ut());Wl(v,{pending:()=>{}},M=>{us({});var N=we;if(a&&(N.c=a),o&&(s.$$events=o),ne&&_t(M,null),f=e(M,s)||{},ne&&(se.nodes.end=W,W===null||W.nodeType!==_n||W.data!==Is))throw Fn(),Or;ds()},i);var x=new Set,y=M=>{for(var N=0;N{var k;for(var M of x)for(const L of[t,document]){var N=gs.get(L),H=N.get(M);--H==0?(L.removeEventListener(M,to),N.delete(M),N.size===0&&gs.delete(L)):N.set(M,H)}eo.delete(y),v!==n&&((k=v.parentNode)==null||k.removeChild(v))}});return no.set(f,u),f}let no=new WeakMap;function wi(e,t){const n=no.get(e);return n?(no.delete(e),n(t)):Promise.resolve()}class ki{constructor(t,n=!0){Ce(this,"anchor");ee(this,Gt,new Map);ee(this,sr,new Map);ee(this,bt,new Map);ee(this,sn,new Set);ee(this,Zn,!0);ee(this,es,t=>{if(d(this,Gt).has(t)){var n=d(this,Gt).get(t),s=d(this,sr).get(n);if(s)Ks(s),d(this,sn).delete(n);else{var o=d(this,bt).get(n);o&&(o.effect.f&Ze)===0&&(d(this,sr).set(n,o.effect),d(this,bt).delete(n),o.fragment.lastChild.remove(),this.anchor.before(o.fragment),s=o.effect)}for(const[a,l]of d(this,Gt)){if(d(this,Gt).delete(a),a===t)break;const i=d(this,bt).get(l);i&&(rt(i.effect),d(this,bt).delete(l))}for(const[a,l]of d(this,sr)){if(a===n||d(this,sn).has(a)||(l.f&Ze)!==0)continue;const i=()=>{if(Array.from(d(this,Gt).values()).includes(a)){var u=document.createDocumentFragment();Xs(l,u),u.append(ut()),d(this,bt).set(a,{effect:l,fragment:u})}else rt(l);d(this,sn).delete(a),d(this,sr).delete(a)};d(this,Zn)||!s?(d(this,sn).add(a),Yr(l,i,!1)):i()}}});ee(this,ys,t=>{d(this,Gt).delete(t);const n=Array.from(d(this,Gt).values());for(const[s,o]of d(this,bt))n.includes(s)||(rt(o.effect),d(this,bt).delete(s))});this.anchor=t,Q(this,Zn,n)}ensure(t,n){var s=le,o=fa();if(n&&!d(this,sr).has(t)&&!d(this,bt).has(t))if(o){var a=document.createDocumentFragment(),l=ut();a.append(l),d(this,bt).set(t,{effect:At(()=>n(l)),fragment:a})}else d(this,sr).set(t,At(()=>n(this.anchor)));if(d(this,Gt).set(s,t),o){for(const[i,f]of d(this,sr))i===t?s.unskip_effect(f):s.skip_effect(f);for(const[i,f]of d(this,bt))i===t?s.unskip_effect(f.effect):s.skip_effect(f.effect);s.oncommit(d(this,es)),s.ondiscard(d(this,ys))}else ne&&(this.anchor=W),d(this,es).call(this,s)}}Gt=new WeakMap,sr=new WeakMap,bt=new WeakMap,sn=new WeakMap,Zn=new WeakMap,es=new WeakMap,ys=new WeakMap;function Ra(e){we===null&&Bo(),ve&&we.l!==null?Ei(we).m.push(e):Vn(()=>{const t=c(e);if(typeof t=="function")return t})}function yi(e){we===null&&Bo(),Ra(()=>()=>c(e))}function Ei(e){var t=e.l;return t.u??(t.u={a:[],b:[],m:[]})}function Y(e,t,n=!1){var s;ne&&(s=W,mn());var o=new ki(e),a=n?hn:0;function l(i,f){if(ne){var u=zo(s);if(i!==parseInt(u.substring(1))){var v=cs();Xe(v),o.anchor=v,ar(!1),o.ensure(i,f),ar(!0);return}}o.ensure(i,f)}Qs(()=>{var i=!1;t((f,u=0)=>{i=!0,l(u,f)}),i||l(-1,null)},a)}function xs(e,t){return t}function $i(e,t,n){for(var s=[],o=t.length,a,l=t.length,i=0;i{if(a){if(a.pending.delete(x),a.done.add(x),a.pending.size===0){var y=e.outrogroups;so(e,ls(a.done)),y.delete(a),y.size===0&&(e.outrogroups=null)}}else l-=1},!1)}if(l===0){var f=s.length===0&&n!==null;if(f){var u=n,v=u.parentNode;ia(v),v.append(u),e.items.clear()}so(e,t,!f)}else a={pending:new Set(t),done:new Set},(e.outrogroups??(e.outrogroups=new Set)).add(a)}function so(e,t,n=!0){var s;if(e.pending.size>0){s=new Set;for(const l of e.pending.values())for(const i of l)s.add(e.items.get(i).e)}for(var o=0;o{var oe=n();return Lo(oe)?oe:oe==null?[]:ls(oe)}),y,M=new Map,N=!0;function H(oe){(ie.effect.f&Qt)===0&&(ie.pending.delete(oe),ie.fallback=v,Ci(ie,y,l,t,s),v!==null&&(y.length===0?(v.f&Jt)===0?Ks(v):(v.f^=Jt,Kn(v,null,l)):Yr(v,()=>{v=null})))}function k(oe){ie.pending.delete(oe)}var L=Qs(()=>{y=r(x);var oe=y.length;let ae=!1;if(ne){var nt=zo(l)===Ts;nt!==(oe===0)&&(l=cs(),Xe(l),ar(!1),ae=!0)}for(var me=new Set,q=le,he=fa(),st=0;sta(l)):(v=At(()=>a(La??(La=ut()))),v.f|=Jt)),oe>me.size&&Sl(),ne&&oe>0&&Xe(cs()),!N)if(M.set(q,me),he){for(const[J,X]of i)me.has(J)||q.skip_effect(X.e);q.oncommit(H),q.ondiscard(k)}else H(q);ae&&ar(!0),r(x)}),ie={effect:L,items:i,pending:M,outrogroups:null,fallback:v};N=!1,ne&&(l=W)}function Jn(e){for(;e!==null&&(e.f&Ot)===0;)e=e.next;return e}function Ci(e,t,n,s,o){var wt,Mt,R,J,X,de,Me,Se,ot;var a=(s&fl)!==0,l=t.length,i=e.items,f=Jn(e.effect.first),u,v=null,x,y=[],M=[],N,H,k,L;if(a)for(L=0;L0){var st=(s&Do)!==0&&l===0?n:null;if(a){for(L=0;L{var Ye,Sr;if(x!==void 0)for(k of x)(Sr=(Ye=k.nodes)==null?void 0:Ye.a)==null||Sr.apply()})}function Ai(e,t,n,s,o,a,l,i){var f=(l&ll)!==0?(l&cl)===0?et(n,!1,!1):Vr(n):null,u=(l&il)!==0?Vr(o):null;return{v:f,i:u,e:At(()=>(a(t,f??n,u??o,i),()=>{e.delete(s)}))}}function Kn(e,t,n){if(e.nodes)for(var s=e.nodes.start,o=e.nodes.end,a=t&&(t.f&Jt)===0?t.nodes.start:n;s!==null;){var l=Ut(s);if(a.before(s),s===o)return;s=l}}function yr(e,t,n){t===null?e.effect.first=n:t.next=n,n===null?e.effect.last=t:n.prev=t}function Si(e,t,n=!1,s=!1,o=!1){var a=e,l="";O(()=>{var i=se;if(l===(l=t()??"")){ne&&mn();return}if(i.nodes!==null&&(ha(i.nodes.start,i.nodes.end),i.nodes=null),l!==""){if(ne){W.data;for(var f=mn(),u=f;f!==null&&(f.nodeType!==_n||f.data!=="");)u=f,f=Ut(f);if(f===null)throw Fn(),Or;_t(W,u),a=Xe(f);return}var v=n?ml:s?gl:void 0,x=hs(n?"svg":s?"math":"template",v);x.innerHTML=l;var y=n||s?x:x.content;if(_t(tt(y),y.lastChild),n||s)for(;tt(y);)a.before(tt(y));else a.before(y)}})}function oo(e,t){va(()=>{var n=e.getRootNode(),s=n.host?n:n.head??n.ownerDocument.head;if(!s.querySelector("#"+t.hash)){const o=hs("style");o.id=t.hash,o.textContent=t.code,s.appendChild(o)}})}const Pa=[...` +\r\f \v\uFEFF`];function Ni(e,t,n){var s=e==null?"":""+e;if(t&&(s=s?s+" "+t:t),n){for(var o of Object.keys(n))if(n[o])s=s?s+" "+o:o;else if(s.length)for(var a=o.length,l=0;(l=s.indexOf(o,l))>=0;){var i=l+a;(l===0||Pa.includes(s[l-1]))&&(i===s.length||Pa.includes(s[i]))?s=(l===0?"":s.substring(0,l))+s.substring(i+1):l=i}}return s===""?null:s}function Di(e,t){return e==null?null:String(e)}function pe(e,t,n,s,o,a){var l=e.__className;if(ne||l!==n||l===void 0){var i=Ni(n,s,a);(!ne||i!==e.getAttribute("class"))&&(i==null?e.removeAttribute("class"):t?e.className=i:e.setAttribute("class",i)),e.__className=n}else if(a&&o!==a)for(var f in a){var u=!!a[f];(o==null||u!==!!o[f])&&e.classList.toggle(f,u)}return a}function Zr(e,t,n,s){var o=e.__style;if(ne||o!==t){var a=Di(t);(!ne||a!==e.getAttribute("style"))&&(a==null?e.removeAttribute("style"):e.style.cssText=a),e.__style=t}return s}const Ti=Symbol("is custom element"),Ii=Symbol("is html"),Mi=Cl?"link":"LINK";function en(e,t,n,s){var o=Ri(e);ne&&(o[t]=e.getAttribute(t),t==="src"||t==="srcset"||t==="href"&&e.nodeName===Mi)||o[t]!==(o[t]=n)&&(t==="loading"&&(e[$l]=n),n==null?e.removeAttribute(t):typeof n!="string"&&Li(e).includes(t)?e[t]=n:e.setAttribute(t,n))}function Ri(e){return e.__attributes??(e.__attributes={[Ti]:e.nodeName.includes("-"),[Ii]:e.namespaceURI===Ro})}var Oa=new Map;function Li(e){var t=e.getAttribute("is")||e.nodeName,n=Oa.get(t);if(n)return n;Oa.set(t,n=[]);for(var s,o=e,a=Element.prototype;a!==o;){s=Po(o);for(var l in s)s[l].set&&n.push(l);o=Rs(o)}return n}function ja(e,t){return e===t||(e==null?void 0:e[zr])===t}function qa(e={},t,n,s){return va(()=>{var o,a;return Wn(()=>{o=a,a=[],c(()=>{e!==n(...a)&&(t(e,...a),o&&ja(n(...o),e)&&t(null,...o))})}),()=>{ir(()=>{a&&ja(n(...a),e)&&t(null,...a)})}}),e}function yn(e){return function(...t){var n=t[0];return n.stopPropagation(),e==null?void 0:e.apply(this,t)}}function Pi(e=!1){const t=we,n=t.l.u;if(!n)return;let s=()=>h(t.s);if(e){let o=0,a={};const l=Gn(()=>{let i=!1;const f=t.s;for(const u in f)f[u]!==a[u]&&(a[u]=f[u],i=!0);return i&&o++,o});s=()=>r(l)}n.b.length&&oi(()=>{Ua(t,s),Ls(n.b)}),Vn(()=>{const o=c(()=>n.m.map(yl));return()=>{for(const a of o)typeof a=="function"&&a()}}),n.a.length&&Vn(()=>{Ua(t,s),Ls(n.a)})}function Ua(e,t){if(e.l.s)for(const n of e.l.s)r(n);t()}let bs=!1;function Oi(e){var t=bs;try{return bs=!1,[e(),bs]}finally{bs=t}}function Er(e,t,n,s){var oe;var o=!ve||(n&dl)!==0,a=(n&pl)!==0,l=(n&hl)!==0,i=s,f=!0,u=()=>(f&&(f=!1,i=l?c(s):s),i),v;if(a){var x=zr in e||Fo in e;v=((oe=jr(e,t))==null?void 0:oe.set)??(x&&t in e?ae=>e[t]=ae:void 0)}var y,M=!1;a?[y,M]=Oi(()=>e[t]):y=e[t],y===void 0&&s!==void 0&&(y=u(),v&&(o&&Rl(),v(y)));var N;if(o?N=()=>{var ae=e[t];return ae===void 0?u():(f=!0,ae)}:N=()=>{var ae=e[t];return ae!==void 0&&(i=void 0),ae===void 0?i:ae},o&&(n&vl)===0)return N;if(v){var H=e.$$legacy;return(function(ae,nt){return arguments.length>0?((!o||!nt||H||M)&&v(nt?N():ae),ae):N()})}var k=!1,L=((n&ul)!==0?Gn:qe)(()=>(k=!1,N()));a&&r(L);var ie=se;return(function(ae,nt){if(arguments.length>0){const me=nt?r(L):o&&a?Wr(ae):ae;return I(L,me),k=!0,i!==void 0&&(i=me),ae}return kr&&k||(ie.f&Qt)!==0?L.v:r(L)})}function ji(e){return new qi(e)}class qi{constructor(t){ee(this,dr);ee(this,It);var a;var n=new Map,s=(l,i)=>{var f=et(i,!1,!1);return n.set(l,f),f};const o=new Proxy({...t.props||{},$$events:{}},{get(l,i){return r(n.get(i)??s(i,Reflect.get(l,i)))},has(l,i){return i===Fo?!0:(r(n.get(i)??s(i,Reflect.get(l,i))),Reflect.has(l,i))},set(l,i,f){return I(n.get(i)??s(i,f),f),Reflect.set(l,i,f)}});Q(this,It,(t.hydrate?bi:Ia)(t.component,{target:t.target,anchor:t.anchor,props:o,context:t.context,intro:t.intro??!1,recover:t.recover,transformError:t.transformError})),(!((a=t==null?void 0:t.props)!=null&&a.$$host)||t.sync===!1)&&Kt(),Q(this,dr,o.$$events);for(const l of Object.keys(d(this,It)))l==="$set"||l==="$destroy"||l==="$on"||fs(this,l,{get(){return d(this,It)[l]},set(i){d(this,It)[l]=i},enumerable:!0});d(this,It).$set=l=>{Object.assign(o,l)},d(this,It).$destroy=()=>{wi(d(this,It))}}$set(t){d(this,It).$set(t)}$on(t,n){d(this,dr)[t]=d(this,dr)[t]||[];const s=(...o)=>n.call(this,...o);return d(this,dr)[t].push(s),()=>{d(this,dr)[t]=d(this,dr)[t].filter(o=>o!==s)}}$destroy(){d(this,It).$destroy()}}dr=new WeakMap,It=new WeakMap;let Fa;typeof HTMLElement=="function"&&(Fa=class extends HTMLElement{constructor(t,n,s){super();Ce(this,"$$ctor");Ce(this,"$$s");Ce(this,"$$c");Ce(this,"$$cn",!1);Ce(this,"$$d",{});Ce(this,"$$r",!1);Ce(this,"$$p_d",{});Ce(this,"$$l",{});Ce(this,"$$l_u",new Map);Ce(this,"$$me");Ce(this,"$$shadowRoot",null);this.$$ctor=t,this.$$s=n,s&&(this.$$shadowRoot=this.attachShadow(s))}addEventListener(t,n,s){if(this.$$l[t]=this.$$l[t]||[],this.$$l[t].push(n),this.$$c){const o=this.$$c.$on(t,n);this.$$l_u.set(n,o)}super.addEventListener(t,n,s)}removeEventListener(t,n,s){if(super.removeEventListener(t,n,s),this.$$c){const o=this.$$l_u.get(n);o&&(o(),this.$$l_u.delete(n))}}async connectedCallback(){if(this.$$cn=!0,!this.$$c){let t=function(o){return a=>{const l=hs("slot");o!=="default"&&(l.name=o),m(a,l)}};if(await Promise.resolve(),!this.$$cn||this.$$c)return;const n={},s=Ui(this);for(const o of this.$$s)o in s&&(o==="default"&&!this.$$d.children?(this.$$d.children=t(o),n.default=!0):n[o]=t(o));for(const o of this.attributes){const a=this.$$g_p(o.name);a in this.$$d||(this.$$d[a]=ws(a,o.value,this.$$p_d,"toProp"))}for(const o in this.$$p_d)!(o in this.$$d)&&this[o]!==void 0&&(this.$$d[o]=this[o],delete this[o]);this.$$c=ji({component:this.$$ctor,target:this.$$shadowRoot||this,props:{...this.$$d,$$slots:n,$$host:this}}),this.$$me=ai(()=>{Wn(()=>{var o;this.$$r=!0;for(const a of is(this.$$c)){if(!((o=this.$$p_d[a])!=null&&o.reflect))continue;this.$$d[a]=this.$$c[a];const l=ws(a,this.$$d[a],this.$$p_d,"toAttribute");l==null?this.removeAttribute(this.$$p_d[a].attribute||a):this.setAttribute(this.$$p_d[a].attribute||a,l)}this.$$r=!1})});for(const o in this.$$l)for(const a of this.$$l[o]){const l=this.$$c.$on(o,a);this.$$l_u.set(a,l)}this.$$l={}}}attributeChangedCallback(t,n,s){var o;this.$$r||(t=this.$$g_p(t),this.$$d[t]=ws(t,s,this.$$p_d,"toProp"),(o=this.$$c)==null||o.$set({[t]:this.$$d[t]}))}disconnectedCallback(){this.$$cn=!1,Promise.resolve().then(()=>{!this.$$cn&&this.$$c&&(this.$$c.$destroy(),this.$$me(),this.$$c=void 0)})}$$g_p(t){return is(this.$$p_d).find(n=>this.$$p_d[n].attribute===t||!this.$$p_d[n].attribute&&n.toLowerCase()===t)||t}});function ws(e,t,n,s){var a;const o=(a=n[e])==null?void 0:a.type;if(t=o==="Boolean"&&typeof t!="boolean"?t!=null:t,!s||!n[e])return t;if(s==="toAttribute")switch(o){case"Object":case"Array":return t==null?null:JSON.stringify(t);case"Boolean":return t?"":null;case"Number":return t??null;default:return t}else switch(o){case"Object":case"Array":return t&&JSON.parse(t);case"Boolean":return t;case"Number":return t!=null?+t:t;default:return t}}function Ui(e){const t={};return e.childNodes.forEach(n=>{t[n.slot||"default"]=!0}),t}function ao(e,t,n,s,o,a){let l=class extends Fa{constructor(){super(e,n,o),this.$$p_d=t}static get observedAttributes(){return is(t).map(i=>(t[i].attribute||i).toLowerCase())}};return is(t).forEach(i=>{fs(l.prototype,i,{get(){return this.$$c&&i in this.$$c?this.$$c[i]:this.$$d[i]},set(f){var x;f=ws(i,f,t),this.$$d[i]=f;var u=this.$$c;if(u){var v=(x=jr(u,i))==null?void 0:x.get;v?u[i]=f:u.$set({[i]:f})}}})}),s.forEach(i=>{fs(l.prototype,i,{get(){var f;return(f=this.$$c)==null?void 0:f[i]}})}),e.element=l,l}async function Ba(e,t){const n=t?`/api/orgs/${e}/projects/${t}/timeline`:`/api/orgs/${e}/timeline`,s=await fetch(n,{credentials:"same-origin"});if(!s.ok)throw new Error(`Timeline fetch failed: ${s.status}`);return s.json()}function Fi(e,t,n){const s=t?`/orgs/${e}/projects/${t}/events`:`/orgs/${e}/events`;let o=1e3,a=null,l=!1;function i(){if(!l){a=new EventSource(s),a.addEventListener("open",()=>{o=1e3});for(const f of["destination","release","artifact","pipeline"])a.addEventListener(f,u=>{try{const v=JSON.parse(u.data);n(f,v)}catch(v){console.warn(`[release-timeline] bad ${f} event:`,v)}});a.addEventListener("error",()=>{a.close(),l||(setTimeout(i,o),o=Math.min(o*2,3e4))})}}return i(),()=>{l=!0,a&&a.close()}}function za(e){if(e<0&&(e=0),e<60)return`${e}s`;const t=Math.floor(e/60),n=e%60;return t<60?`${t}m ${n}s`:`${Math.floor(t/60)}h ${t%60}m`}function En(e){if(!e)return"";const t=new Date(e),n=Date.now(),s=Math.floor((n-t.getTime())/1e3);return s<10?"just now":s<60?`${s}s ago`:s<3600?`${Math.floor(s/60)}m ago`:s<86400?`${Math.floor(s/3600)}h ago`:`${Math.floor(s/86400)}d ago`}const lo={prod:["#ec4899","#fce7f3"],production:["#ec4899","#fce7f3"],preprod:["#f97316","#ffedd5"],"pre-prod":["#f97316","#ffedd5"],staging:["#eab308","#fef9c3"],stage:["#eab308","#fef9c3"],dev:["#8b5cf6","#ede9fe"],development:["#8b5cf6","#ede9fe"],test:["#06b6d4","#cffafe"]},Bi=["#6b7280","#e5e7eb"];function zi(e){const t=e.toLowerCase();if(lo[t])return lo[t];for(const[n,s]of Object.entries(lo))if(t.includes(n))return s;return Bi}function er(e){const t=e.toLowerCase();return t.includes("prod")&&!t.includes("preprod")&&!t.includes("pre-prod")?{bg:"bg-pink-100 text-pink-800",dot:"bg-pink-500"}:t.includes("preprod")||t.includes("pre-prod")?{bg:"bg-orange-100 text-orange-800",dot:"bg-orange-500"}:t.includes("stag")?{bg:"bg-yellow-100 text-yellow-800",dot:"bg-yellow-500"}:t.includes("dev")?{bg:"bg-violet-100 text-violet-800",dot:"bg-violet-500"}:{bg:"bg-gray-100 text-gray-700",dot:"bg-gray-400"}}function Ga(e){switch(e){case"SUCCEEDED":return"bg-green-500";case"RUNNING":return"bg-yellow-500";case"FAILED":return"bg-red-500";default:return null}}const io={SUCCEEDED:{label:"Deployed to",stageLabel:"Deployed to",color:"text-green-600",icon:"check-circle",iconColor:"text-green-500"},RUNNING:{label:"Deploying to",stageLabel:"Deploying to",color:"text-yellow-700",icon:"pulse",iconColor:"text-yellow-500"},ASSIGNED:{label:"Deploying to",stageLabel:"Deploying to",color:"text-yellow-700",icon:"pulse",iconColor:"text-yellow-500"},QUEUED:{label:"Queued for",stageLabel:"Queued for",color:"text-blue-600",icon:"clock",iconColor:"text-blue-400"},FAILED:{label:"Failed on",stageLabel:"Failed on",color:"text-red-600",icon:"x-circle",iconColor:"text-red-500"},TIMED_OUT:{label:"Timed out on",stageLabel:"Timed out on",color:"text-orange-600",icon:"clock",iconColor:"text-orange-500"},CANCELLED:{label:"Cancelled",stageLabel:"Cancelled",color:"text-gray-500",icon:"ban",iconColor:"text-gray-400"}};function $n(e){if(!e||e.length===0)return null;let t=!0,n=!1,s=!1,o=!1,a=!1,l=0;const i=e.length;for(const v of e)v.status==="SUCCEEDED"&&l++,v.status!=="SUCCEEDED"&&(t=!1),v.status==="FAILED"&&(n=!0),v.status==="RUNNING"&&(s=!0),v.status==="QUEUED"&&(a=!0),v.stage_type==="wait"&&v.status==="RUNNING"&&(o=!0);let f=e.some(v=>v.blocked_by),u=e.some(v=>v.stage_type==="plan"&&(v.status==="AWAITING_APPROVAL"||v.approval_status==="AWAITINGAPPROVAL"||v.approval_status==="AWAITING_APPROVAL"));return t?{label:"Pipeline complete",color:"text-gray-600",icon:"check-circle",iconColor:"text-green-500",done:l,total:i}:n?{label:"Pipeline failed",color:"text-red-600",icon:"x-circle",iconColor:"text-red-500",done:l,total:i}:u?{label:"Awaiting plan approval",color:"text-purple-700",icon:"shield",iconColor:"text-purple-500",done:l,total:i}:f?{label:"Awaiting approval",color:"text-emerald-700",icon:"shield",iconColor:"text-emerald-500",done:l,total:i}:o?{label:"Waiting for time window",color:"text-yellow-700",icon:"clock",iconColor:"text-yellow-500",done:l,total:i}:s?{label:"Deploying to",color:"text-yellow-700",icon:"pulse",iconColor:"text-yellow-500",done:l,total:i}:a?{label:"Queued",color:"text-blue-600",icon:"clock",iconColor:"text-blue-400",done:l,total:i}:{label:"Pipeline pending",color:"text-gray-400",icon:"pending",iconColor:"text-gray-300",done:l,total:i}}function Ha(e){switch(e){case"SUCCEEDED":return"Waited";case"RUNNING":return"Waiting";case"FAILED":return"Wait failed";case"CANCELLED":return"Wait cancelled";default:return"Wait"}}function Va(e){switch(e){case"SUCCEEDED":return"Deployed to";case"RUNNING":return"Deploying to";case"QUEUED":return"Queued for";case"FAILED":return"Failed on";case"TIMED_OUT":return"Timed out on";case"CANCELLED":return"Cancelled";default:return"Deploy to"}}function Wa(e){switch(e){case"SUCCEEDED":return"Plan approved";case"RUNNING":return"Planning";case"AWAITING_APPROVAL":return"Awaiting plan approval";case"FAILED":return"Plan failed";case"CANCELLED":return"Plan cancelled";default:return"Plan"}}var Gi=D('
'),Hi=D('

Loading releases...

'),Vi=D('

'),Wi=D('

No releases yet.

Create a release with forest release create

'),Yi=D('
'),Qi=D('
'),Ji=D('
'),Ki=D(" ",1),Xi=D('
'),Zi=D(' '),ef=D(' '),tf=D(' '),rf=D(' '),nf=D(' Deployed',1),sf=D(' Queued',1),of=Oe('',1),af=D(''),lf=Oe(''),ff=Oe(''),cf=Oe(''),uf=Oe(''),df=Oe(''),vf=D(" "),pf=D(' ',1),hf=D(''),_f=D(''),mf=D(" ",1),gf=D(' ',1),xf=D(' Deployed',1),bf=D(''),wf=Oe(''),kf=Oe(''),yf=D(" "),Ef=D(" ",1),$f=D(' Pending',1),Cf=D('

'),Af=D(' '),Sf=Oe(''),Nf=D(''),Df=Oe(''),Tf=Oe(''),If=Oe(''),Mf=Oe(''),Rf=D(" ",1),Lf=D(" "),Pf=D(' ',1),Of=D(''),jf=D(" ",1),qf=D(' '),Uf=D('
 
'),Ff=D('
 
'),Bf=D('
Plan output
'),zf=D('
pipeline
',1),Gf=D('
'),Hf=Oe(''),Vf=D(''),Wf=Oe(''),Yf=Oe(''),Qf=Oe(''),Jf=D('Deployed'),Kf=D('Deploying'),Xf=D(' '),Zf=D('Failed'),ec=D(''),tc=D('
'),rc=D(''),nc=D(' '),sc=D(''),oc=D('
·
'),ac=D('
'),lc=D('
'),ic=D(" ",1);const fc={hash:"svelte-4kxpm1",code:` @keyframes svelte-4kxpm1-lane-pulse { 0%, 100% { opacity: 0.6; } 50% { opacity: 1; } }.lane-pulse { - animation: svelte-4kxpm1-lane-pulse 2s ease-in-out infinite;}`};function zf(e,t){rs(t,!1),Qs(e,Pf);const r=at(),s=at();let o=mr(t,"org",12,""),l=mr(t,"project",12,""),i=mr(t,"csrf",12,""),a=mr(t,"username",12,""),f=mr(t,"role",12,""),c=at([]),v=at([]),m=at(!0),b=at(null),S=at(null),$=Date.now(),B=null,x=at(null),A=at({});const ae=20,ee=4,ne=12,Qe=new Set(["QUEUED","RUNNING","ASSIGNED"]),pe=new Set(["SUCCEEDED"]);let K=at(new Set),Ne=at(null);function Ke(){return f()==="owner"||f()==="admin"}function ht(h){return a()&&h.source_user===a()}async function Dt(h,k,T=!1){const te=`${h.release_intent_id}:${k.environment}`;if(!n(K).has(te)){n(K).add(te),U(K,n(K)),U(Ne,null);try{const P=new URLSearchParams;P.set("csrf_token",i()),P.set("release_intent_id",h.release_intent_id),P.set("target_environment",k.environment),T&&P.set("force_bypass","true");const re=await fetch(`/orgs/${o()}/projects/${h.project_name}/releases/${h.slug}/approve`,{method:"POST",body:P,credentials:"same-origin",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},redirect:"manual"});if(re.ok||re.status===303||re.status===302||re.status===0)await fe();else{const L=await re.text().catch(()=>"");let R;try{R=JSON.parse(L).error}catch{}if(!R){const oe=L.match(/]*>\s*(.*?)\s*<\/p>/);R=oe==null?void 0:oe[1]}U(Ne,R||`Approval failed (${re.status})`),setTimeout(()=>{U(Ne,null)},8e3)}}catch(P){U(Ne,P.message||"Approval request failed"),setTimeout(()=>{U(Ne,null)},8e3)}finally{n(K).delete(te),U(K,n(K))}}}let M=null;function se(){M||(M=setTimeout(()=>{M=null,fe()},300))}async function J(){try{U(b,null);const h=await Il(o(),l());Pe(h.timeline,h.lanes),U(m,!1),_t()}catch(h){U(b,h.message),U(m,!1)}}async function fe(){try{const h=await Il(o(),l());Pe(h.timeline,h.lanes),_t()}catch(h){console.warn("[release-timeline] refresh failed:",h)}}function Pe(h,k){const T=new Map;for(const P of n(c))P.kind==="release"&&P.release&&T.set(P.release.slug,P);const te=h.map(P=>{if(P.kind!=="release"||!P.release)return P;const re=T.get(P.release.slug);if(!re)return P;const L=re.release,R=P.release;return L.dest_envs===R.dest_envs&&L.has_pipeline===R.has_pipeline&&qe(L.pipeline_stages,R.pipeline_stages)&&ot(L.destinations,R.destinations)?re:P});U(c,te),U(v,k)}function qe(h,k){if(h.length!==k.length)return!1;for(let T=0;T{if(oe.kind!=="release"||!oe.release)return oe;const Te=oe.release;if(Te.destinations.findIndex(ve=>ve.name===T)===-1)return oe;P=!0;const Oe=Te.destinations.map(ve=>ve.name===T?{...ve,status:k,...["SUCCEEDED","FAILED","TIMED_OUT","CANCELLED"].includes(k)?{completed_at:new Date().toISOString()}:{}}:ve),p=Oe.map(ve=>`${ve.environment}:${ve.status||"PENDING"}`).join(","),ze=te?Te.pipeline_stages.map(ve=>ve.stage_type==="deploy"&&ve.environment===te?{...ve,status:k==="ASSIGNED"?"RUNNING":k}:ve):Te.pipeline_stages;return{...oe,release:{...Te,destinations:Oe,dest_envs:p,pipeline_stages:ze}}})),P&&_t()}function En(h){var te,P;const k=(te=h.metadata)==null?void 0:te.status,T=(P=h.metadata)==null?void 0:P.environment;k&&T?yr(h):se()}function eo(h){var re,L,R;const k=(re=h.metadata)==null?void 0:re.status,T=(L=h.metadata)==null?void 0:L.environment,te=(R=h.metadata)==null?void 0:R.stage_type;if(!k){(h.action==="created"||h.action==="updated")&&se();return}let P=!1;U(c,n(c).map(oe=>{if(oe.kind!=="release"||!oe.release)return oe;const Te=oe.release;let Xe=!1;const Oe=Te.pipeline_stages.map(p=>T&&p.stage_type==="deploy"&&p.environment===T?(Xe=!0,{...p,status:k,...p.started_at?{}:{started_at:new Date().toISOString()}}):te==="wait"&&p.stage_type==="wait"?(Xe=!0,{...p,status:k}):p);return Xe?(P=!0,{...oe,release:{...Te,pipeline_stages:Oe}}):oe})),P&&_t()}function hs(h){return h?h.split(",").map(k=>k.trim()).filter(Boolean).map(k=>{const T=k.indexOf(":");return T===-1?{env:k,status:"SUCCEEDED"}:{env:k.slice(0,T),status:k.slice(T+1)}}):[]}let Qr=null;function _t(){Qr||(Qr=requestAnimationFrame(()=>{Qr=null,ea().then(to)}))}function to(){if(!n(x))return;const h=n(x).getBoundingClientRect();if(h.height===0)return;const k=h.height,T=Array.from(n(x).querySelectorAll("[data-release]")),te={};for(const P of n(v)){const re=P.name;let L=null,R=null,oe=-1,Te=-1;for(let $e=0;$e$r.env===re))continue;const Er=($e.querySelector("[data-avatar]")||$e).getBoundingClientRect();lr.push(Er.top+Er.height/2-h.top)}te[re]={solidH:p,hasHatch:ze,hatchTop:ve,hatchH:Tt,isForward:jt,dots:lr,color:Ta(re)}}U(A,te)}const _s=new Map;function xe(h,k){const T=`${h}|${k}`;let te=_s.get(T);if(te)return te;const P=``;return te=`url("data:image/svg+xml,${encodeURIComponent(P)}")`,_s.set(T,te),te}$l(()=>{J(),B=setInterval(()=>{$=Date.now()},1e4)}),ca(()=>{n(S)&&n(S)(),B&&clearInterval(B),M&&clearTimeout(M),Qr&&cancelAnimationFrame(Qr)});function Ee(){_t()}function Nt(h,k,T){if(!h)return"";const te=new Date(h).getTime();if(isNaN(te))return"";if(k&&T!=="RUNNING"&&T!=="QUEUED"){const P=new Date(k).getTime();if(!isNaN(P))return Ll(Math.floor((P-te)/1e3))}return Ll(Math.floor(($-te)/1e3))}function Kr(h){var k;return h.kind==="release"&&h.release?`r:${h.release.slug}`:h.kind==="hidden"?`h:${h.count}:${((k=(h.releases||[])[0])==null?void 0:k.slug)||""}`:`u:${Math.random()}`}function Jr(h,k){if(!h)return!1;switch(h.label){case"Pipeline complete":return k==="SUCCEEDED";case"Pipeline failed":return k==="FAILED"||k==="RUNNING"||k==="ASSIGNED";case"Deploying to":return k==="RUNNING"||k==="ASSIGNED";case"Queued":return k==="QUEUED";case"Waiting for time window":return k==="RUNNING"||k==="ASSIGNED";default:return k!=="PENDING"&&k!=="SUCCEEDED"}}Us(()=>(n(m),n(b),_(o()),n(S),_(l())),()=>{!n(m)&&!n(b)&&o()&&!n(S)&&U(S,Da(o(),l(),Je))}),Us(()=>n(v),()=>{U(r,n(v).length)}),Us(()=>n(r),()=>{U(s,n(r)*(ae+ee)+8)}),Qi();var $n={get org(){return o()},set org(h){o(h),Ht()},get project(){return l()},set project(h){l(h),Ht()},get csrf(){return i()},set csrf(h){i(h),Ht()},get username(){return a()},set username(h){a(h),Ht()},get role(){return f()},set role(h){f(h),Ht()}};ya();var Xr=Ff();_r("resize",Is,Ee);var Zr=ft(Xr);{var Wn=h=>{var k=Aa(),T=D(E(k)),te=D(T);y(k),j(()=>V(T,` ${n(Ne)??""} `)),_r("click",te,()=>U(Ne,null)),w(h,k)};Q(Zr,h=>{n(Ne)&&h(Wn)})}var Cn=D(Zr,2);{var ro=h=>{var k=Ma();w(h,k)},no=h=>{var k=Ra(),T=E(k),te=E(T,!0);y(T);var P=D(T,2);y(k),j(()=>V(te,n(b))),_r("click",P,J),w(h,k)},so=h=>{var k=Ia();w(h,k)},ac=h=>{var k=Bf(),T=E(k);Ct(T,5,()=>n(v),re=>re.name,(re,L)=>{const R=Ve(()=>(n(A),n(L),d(()=>n(A)[n(L).name]))),oe=Ve(()=>{const[p,ze]=(_(n(R)),n(L),d(()=>{var ve;return((ve=n(R))==null?void 0:ve.color)||[n(L).color,"#e5e7eb"]}));return{barColor:p,lightColor:ze}});var Te=ja();zr(Te,"width: 20px; margin-right: 4px; position: relative;");var Xe=E(Te);{var Oe=p=>{var ze=Ua(),ve=ft(ze);{var Tt=Ce=>{var Ae=La();j(Se=>zr(Ae,`position: absolute; left: 0; width: 100%; top: ${_(n(R)),d(()=>n(R).hatchTop)??""}px; height: ${_(n(R)),d(()=>n(R).hatchH+(n(R).solidH>0?ae/2:0))??""}px; background-image: ${Se??""}; background-size: 8px 8px; background-repeat: repeat; border-radius: 9999px; z-index: 0;`),[()=>(_(n(R)),_(n(oe).barColor),_(n(oe).lightColor),d(()=>n(R).isForward?xe(n(oe).barColor,n(oe).lightColor):xe("#f59e0b","#fef3c7")))]),w(Ce,Ae)};Q(ve,Ce=>{_(n(R)),d(()=>n(R).hasHatch)&&Ce(Tt)})}var jt=D(ve,2);{var lr=Ce=>{var Ae=qa();j(()=>zr(Ae,`position: absolute; bottom: 0; left: 0; width: 100%; height: ${_(n(R)),d(()=>n(R).solidH+(n(R).hasHatch?ae/2:0))??""}px; background: ${n(oe).barColor??""}; border-radius: 9999px; z-index: 1;`)),w(Ce,Ae)};Q(jt,Ce=>{_(n(R)),d(()=>n(R).solidH>0)&&Ce(lr)})}var $e=D(jt,2);Ct($e,1,()=>(_(n(R)),d(()=>n(R).dots)),cs,(Ce,Ae)=>{var Se=Oa();j(()=>zr(Se,`position: absolute; left: 50%; transform: translateX(-50%); top: ${n(Ae)-ne/2}px; width: 12px; height: 12px; border-radius: 50%; background: #fff; border: 2px solid ${n(oe).barColor??""}; z-index: 2;`)),w(Ce,Se)}),w(p,ze)};Q(Xe,p=>{n(R)&&p(Oe)})}y(Te),w(re,Te)}),y(T);var te=D(T,2);Ct(te,5,()=>n(c),re=>Kr(re),(re,L)=>{var R=Fn(),oe=ft(R);{var Te=Oe=>{const p=Ve(()=>(n(L),d(()=>n(L).release)));var ze=Lf(),ve=E(ze),Tt=E(ve),jt=D(E(Tt),2),lr=E(jt,!0);y(jt),y(Tt);var $e=D(Tt,2),Ce=E($e);{var Ae=q=>{var g=Ba(),ce=D(E(g));y(g),j(()=>V(ce,` ${_(n(p)),d(()=>n(p).branch)??""}`)),w(q,g)};Q(Ce,q=>{_(n(p)),d(()=>n(p).branch)&&q(Ae)})}var Se=D(Ce,2);{var Er=q=>{var g=Fa(),ce=E(g,!0);y(g),j(N=>V(ce,N),[()=>(_(n(p)),d(()=>n(p).commit_sha.slice(0,7)))]),w(q,g)};Q(Se,q=>{_(n(p)),d(()=>n(p).commit_sha)&&q(Er)})}var $r=D(Se,2),Yn=E($r,!0);y($r);var Sn=D($r,2);{var oo=q=>{var g=Pa(),ce=D(E(g),2),N=E(ce,!0);y(ce),y(g),j(()=>{Hr(ce,"href",`/users/${_(n(p)),d(()=>n(p).source_user)??""}`),V(N,(_(n(p)),d(()=>n(p).source_user)))}),w(q,g)};Q(Sn,q=>{_(n(p)),d(()=>n(p).source_user)&&q(oo)})}var gs=D(Sn,2);{var ms=q=>{var g=za(),ce=E(g,!0);y(g),j(()=>{Hr(g,"href",`/orgs/${o()??""}/projects/${_(n(p)),d(()=>n(p).project_name)??""}`),V(ce,(_(n(p)),d(()=>n(p).project_name)))}),w(q,g)};Q(gs,q=>{_(n(p)),_(l()),d(()=>n(p).project_name&&n(p).project_name!==l())&&q(ms)})}y($e),y(ve);var Qn=D(ve,2),Dn=E(Qn),lo=E(Dn);{var en=q=>{const g=Ve(()=>(_(n(p)),d(()=>n(p).env_groups&&n(p).env_groups.length>0&&n(p).env_groups.every(me=>me.status==="SUCCEEDED"))));var ce=Va(),N=D(ft(ce));{var gt=me=>{var lt=Ha();dr(2),w(me,lt)},mt=me=>{var lt=Ga();dr(2),w(me,lt)};Q(N,me=>{n(g)?me(gt):me(mt,-1)})}w(q,ce)},Kn=Vt(()=>(_(n(p)),_(hn),d(()=>n(p).has_pipeline&&!hn(n(p).pipeline_stages)))),io=q=>{const g=Ve(()=>(_(hn),_(n(p)),d(()=>hn(n(p).pipeline_stages))));var ce=nf(),N=D(ft(ce),2);{var gt=z=>{var H=Wa();w(z,H)},mt=z=>{var H=Ya();j(()=>he(H,0,`w-4 h-4 ${_(n(g)),d(()=>n(g).iconColor)??""} shrink-0`,"svelte-4kxpm1")),w(z,H)},me=z=>{var H=Qa();j(()=>he(H,0,`w-4 h-4 ${_(n(g)),d(()=>n(g).iconColor)??""} shrink-0`,"svelte-4kxpm1")),w(z,H)},lt=z=>{var H=Ka();j(()=>he(H,0,`w-4 h-4 ${_(n(g)),d(()=>n(g).iconColor)??""} shrink-0`,"svelte-4kxpm1")),w(z,H)},tn=z=>{var H=Ja();j(()=>he(H,0,`w-4 h-4 ${_(n(g)),d(()=>n(g).iconColor)??""} shrink-0`,"svelte-4kxpm1")),w(z,H)},rn=z=>{var H=Xa();w(z,H)};Q(N,z=>{_(n(g)),d(()=>n(g).icon==="pulse")?z(gt):(_(n(g)),d(()=>n(g).icon==="check-circle")?z(mt,1):(_(n(g)),d(()=>n(g).icon==="x-circle")?z(me,2):(_(n(g)),d(()=>n(g).icon==="clock")?z(lt,3):(_(n(g)),d(()=>n(g).icon==="shield")?z(tn,4):z(rn,-1)))))})}var Ze=D(N,2),Bt=E(Ze,!0);y(Ze);var Xt=D(Ze,2);Ct(Xt,1,()=>(_(n(p)),d(()=>n(p).pipeline_stages)),z=>z.id||z.environment||z.stage_type,(z,H)=>{var le=rf(),ue=ft(le);{var At=O=>{const I=Ve(()=>(_(xr),n(H),d(()=>xr(n(H).environment||"")))),De=Ve(()=>(_(ql),n(H),_(n(I)),d(()=>ql(n(H).status)||n(I).dot)));var xt=Za(),ar=E(xt),Nn=D(ar);y(xt),j(()=>{he(xt,1,`inline-flex items-center gap-1 text-xs font-medium px-2 py-0.5 rounded-full ${_(n(I)),d(()=>n(I).bg)??""}`,"svelte-4kxpm1"),V(ar,`${n(H),d(()=>n(H).environment)??""} `),he(Nn,1,`w-1.5 h-1.5 rounded-full ${n(De)??""}`,"svelte-4kxpm1")}),w(O,xt)},it=Vt(()=>(n(H),_(n(g)),d(()=>n(H).stage_type==="deploy"&&Jr(n(g),n(H).status))));Q(ue,O=>{n(it)&&O(At)})}var Zt=D(ue,2);{var ir=O=>{var I=Fn(),De=ft(I);{var xt=Tn=>{var nn=ef();j(vo=>nn.disabled=vo,[()=>(n(K),_(n(p)),n(H),d(()=>n(K).has(`${n(p).release_intent_id}:${n(H).environment}`)))]),_r("click",nn,Al(()=>{confirm("You are the release author. Bypass approval?")&&Dt(n(p),n(H),!0)})),w(Tn,nn)},ar=Vt(()=>(_(n(p)),d(()=>ht(n(p))&&Ke()))),Nn=Tn=>{var nn=tf();j(vo=>nn.disabled=vo,[()=>(n(K),_(n(p)),n(H),d(()=>n(K).has(`${n(p).release_intent_id}:${n(H).environment}`)))]),_r("click",nn,Al(()=>Dt(n(p),n(H)))),w(Tn,nn)},uo=Vt(()=>(_(n(p)),d(()=>!ht(n(p)))));Q(De,Tn=>{n(ar)?Tn(xt):n(uo)&&Tn(Nn,1)})}w(O,I)};Q(Zt,O=>{n(H),_(n(p)),_(i()),d(()=>n(H).blocked_by&&n(p).release_intent_id&&i())&&O(ir)})}w(z,le)});var Cr=D(Xt,2),Ft=E(Cr);y(Cr),j(()=>{he(Ze,1,`${_(n(g)),d(()=>n(g).color)??""} text-sm`,"svelte-4kxpm1"),V(Bt,(_(n(g)),d(()=>n(g).label))),V(Ft,`${_(n(g)),d(()=>n(g).done)??""}/${_(n(g)),d(()=>n(g).total)??""}`)}),w(q,ce)},ao=Vt(()=>(_(n(p)),_(hn),d(()=>n(p).has_pipeline&&hn(n(p).pipeline_stages)))),fc=q=>{const g=Ve(()=>(_(n(p)),d(()=>n(p).env_groups.every(me=>me.status==="SUCCEEDED"))));var ce=Fn(),N=ft(ce);{var gt=me=>{var lt=sf();dr(2),w(me,lt)},mt=me=>{var lt=Fn(),tn=ft(lt);Ct(tn,1,()=>(_(n(p)),d(()=>n(p).env_groups)),cs,(rn,Ze)=>{var Bt=Fn(),Xt=ft(Bt);{var Cr=Ft=>{const z=Ve(()=>(_(Xs),n(Ze),d(()=>Xs[n(Ze).status]||Xs.SUCCEEDED)));var H=cf(),le=ft(H);{var ue=I=>{var De=of();w(I,De)},At=I=>{var De=lf();j(()=>he(De,0,`w-4 h-4 ${_(n(z)),d(()=>n(z).iconColor)??""} shrink-0`,"svelte-4kxpm1")),w(I,De)},it=I=>{var De=af();j(()=>he(De,0,`w-4 h-4 ${_(n(z)),d(()=>n(z).iconColor)??""} shrink-0`,"svelte-4kxpm1")),w(I,De)};Q(le,I=>{_(n(z)),d(()=>n(z).icon==="pulse")?I(ue):(_(n(z)),d(()=>n(z).icon==="check-circle")?I(At,1):I(it,-1))})}var Zt=D(le,2),ir=E(Zt,!0);y(Zt);var O=D(Zt,2);Ct(O,1,()=>(n(Ze),d(()=>n(Ze).envs)),I=>I,(I,De)=>{const xt=Ve(()=>(_(xr),n(De),d(()=>xr(n(De)))));var ar=ff(),Nn=E(ar),uo=D(Nn);y(ar),j(()=>{he(ar,1,`inline-flex items-center gap-1 text-xs font-medium px-2 py-0.5 rounded-full ${_(n(xt)),d(()=>n(xt).bg)??""}`,"svelte-4kxpm1"),V(Nn,`${n(De)??""} `),he(uo,1,`w-1.5 h-1.5 rounded-full ${_(n(xt)),d(()=>n(xt).dot)??""}`,"svelte-4kxpm1")}),w(I,ar)}),j(()=>{he(Zt,1,`${_(n(z)),d(()=>n(z).color)??""} text-sm`,"svelte-4kxpm1"),V(ir,(_(n(z)),d(()=>n(z).label)))}),w(Ft,H)};Q(Xt,Ft=>{n(Ze),d(()=>n(Ze).status!=="SUCCEEDED")&&Ft(Cr)})}w(rn,Bt)}),w(me,lt)};Q(N,me=>{n(g)?me(gt):me(mt,-1)})}w(q,ce)},cc=q=>{var g=uf();dr(2),w(q,g)};Q(lo,q=>{n(Kn)?q(en):n(ao)?q(io,1):(_(n(p)),d(()=>n(p).env_groups&&n(p).env_groups.length>0)?q(fc,2):q(cc,-1))})}dr(2),y(Dn);var fo=D(Dn,2),Pl=E(fo);{var uc=q=>{var g=df(),ce=E(g,!0);y(g),j(()=>V(ce,(_(n(p)),d(()=>n(p).description)))),w(q,g)};Q(Pl,q=>{_(n(p)),d(()=>n(p).description)&&q(uc)})}var zl=D(Pl,2),co=E(zl),dc=E(co,!0);y(co);var vc=D(co,2);{var pc=q=>{var g=vf(),ce=E(g,!0);y(g),j(()=>V(ce,(_(n(p)),d(()=>n(p).version)))),w(q,g)};Q(vc,q=>{_(n(p)),d(()=>n(p).version)&&q(pc)})}y(zl),y(fo);var Hl=D(fo,2);{var hc=q=>{var g=yf();Ct(g,7,()=>(_(n(p)),d(()=>n(p).pipeline_stages)),(ce,N)=>ce.id||`${ce.stage_type}-${ce.environment}-${N}`,(ce,N,gt)=>{var mt=kf(),me=E(mt);{var lt=le=>{var ue=pf();w(le,ue)},tn=le=>{var ue=hf();w(le,ue)},rn=le=>{var ue=_f();w(le,ue)},Ze=le=>{var ue=gf();w(le,ue)},Bt=le=>{var ue=mf();w(le,ue)};Q(me,le=>{n(N),d(()=>n(N).status==="SUCCEEDED")?le(lt):(n(N),d(()=>n(N).status==="RUNNING")?le(tn,1):(n(N),d(()=>n(N).status==="QUEUED")?le(rn,2):(n(N),d(()=>n(N).status==="FAILED")?le(Ze,3):le(Bt,-1))))})}var Xt=D(me,2);{var Cr=le=>{const ue=Ve(()=>(_(xr),n(N),d(()=>xr(n(N).environment||""))));var At=xf(),it=ft(At),Zt=E(it,!0);y(it);var ir=D(it,2),O=E(ir),I=D(O);y(ir),j(De=>{he(it,1,`text-sm ${n(N),d(()=>n(N).status==="SUCCEEDED"?"text-gray-700":n(N).status==="RUNNING"?"text-yellow-700":n(N).status==="FAILED"?"text-red-700":"text-gray-400")??""}`,"svelte-4kxpm1"),V(Zt,De),he(ir,1,`inline-flex items-center gap-1 text-xs font-medium px-2 py-0.5 rounded-full ${_(n(ue)),d(()=>n(ue).bg)??""}`,"svelte-4kxpm1"),V(O,`${n(N),d(()=>n(N).environment)??""} `),he(I,1,`w-1.5 h-1.5 rounded-full ${_(n(ue)),d(()=>n(ue).dot)??""}`,"svelte-4kxpm1")},[()=>(_(Ul),n(N),d(()=>Ul(n(N).status)))]),w(le,At)},Ft=le=>{var ue=bf(),At=E(ue);y(ue),j(it=>{he(ue,1,`text-sm ${n(N),d(()=>n(N).status==="SUCCEEDED"?"text-gray-700":n(N).status==="RUNNING"?"text-yellow-700":"text-gray-400")??""}`,"svelte-4kxpm1"),V(At,`${it??""} ${n(N),d(()=>n(N).duration_seconds)??""}s`)},[()=>(_(Ol),n(N),d(()=>Ol(n(N).status)))]),w(le,ue)};Q(Xt,le=>{n(N),d(()=>n(N).stage_type==="deploy")?le(Cr):(n(N),d(()=>n(N).stage_type==="wait")&&le(Ft,1))})}var z=D(Xt,2);{var H=le=>{var ue=wf(),At=E(ue,!0);y(ue),j(it=>V(At,it),[()=>(n(N),d(()=>Nt(n(N).started_at,n(N).completed_at,n(N).status)))]),w(le,ue)};Q(z,le=>{n(N),d(()=>n(N).started_at&&(n(N).status==="RUNNING"||n(N).status==="QUEUED"||n(N).completed_at))&&le(H)})}dr(2),y(mt),j(()=>he(mt,1,`px-4 py-2.5 flex items-center gap-3 text-sm ${_(n(gt)),_(n(p)),d(()=>n(gt)n(N).status==="PENDING"?"opacity-50":"")??""}`,"svelte-4kxpm1")),w(ce,mt)}),y(g),w(q,g)};Q(Hl,q=>{_(n(p)),d(()=>n(p).has_pipeline)&&q(hc)})}var _c=D(Hl,2);Ct(_c,3,()=>(_(n(p)),d(()=>n(p).destinations)),q=>q.name,(q,g,ce)=>{const N=Ve(()=>(_(xr),n(g),d(()=>xr(n(g).environment||""))));var gt=If(),mt=E(gt);{var me=O=>{var I=Ef();w(O,I)},lt=O=>{var I=$f();w(O,I)},tn=O=>{var I=Cf();w(O,I)},rn=O=>{var I=Sf();w(O,I)},Ze=O=>{var I=Df();w(O,I)};Q(mt,O=>{n(g),d(()=>n(g).status==="SUCCEEDED")?O(me):(n(g),d(()=>n(g).status==="RUNNING"||n(g).status==="ASSIGNED")?O(lt,1):(n(g),d(()=>n(g).status==="QUEUED")?O(tn,2):(n(g),d(()=>n(g).status==="FAILED")?O(rn,3):O(Ze,-1))))})}var Bt=D(mt,2),Xt=E(Bt),Cr=D(Xt);y(Bt);var Ft=D(Bt,2),z=E(Ft,!0);y(Ft);var H=D(Ft,2);{var le=O=>{var I=Nf();w(O,I)},ue=O=>{var I=Tf();w(O,I)},At=O=>{var I=Af(),De=E(I);y(I),j(()=>V(De,`Queued${n(g),d(()=>n(g).queue_position?` #${n(g).queue_position}`:"")??""}`)),w(O,I)},it=O=>{var I=Mf();w(O,I)};Q(H,O=>{n(g),d(()=>n(g).status==="SUCCEEDED")?O(le):(n(g),d(()=>n(g).status==="RUNNING")?O(ue,1):(n(g),d(()=>n(g).status==="QUEUED")?O(At,2):(n(g),d(()=>n(g).status==="FAILED")&&O(it,3))))})}var Zt=D(H,2);{var ir=O=>{var I=Rf(),De=E(I,!0);y(I),j(xt=>V(De,xt),[()=>(_(pn),n(g),d(()=>pn(n(g).completed_at)))]),w(O,I)};Q(Zt,O=>{n(g),d(()=>n(g).completed_at)&&O(ir)})}y(gt),j(()=>{he(gt,1,`px-4 py-2 flex items-center gap-3 text-sm ${_(n(ce)),_(n(p)),d(()=>n(ce)n(N).bg)??""}`,"svelte-4kxpm1"),V(Xt,`${n(g),d(()=>n(g).environment)??""} `),he(Cr,1,`w-1.5 h-1.5 rounded-full ${_(n(N)),d(()=>n(N).dot)??""}`,"svelte-4kxpm1"),V(z,(n(g),d(()=>n(g).name)))}),w(q,gt)}),y(Qn),y(ze),j(q=>{Hr(ze,"data-envs",(_(n(p)),d(()=>n(p).dest_envs))),Hr(jt,"href",`/orgs/${o()??""}/projects/${_(n(p)),_(l()),d(()=>n(p).project_name||l())??""}/releases/${_(n(p)),d(()=>n(p).slug)??""}`),V(lr,(_(n(p)),d(()=>n(p).title))),V(Yn,q),V(dc,(_(n(p)),d(()=>n(p).slug)))},[()=>(_(pn),_(n(p)),d(()=>pn(n(p).created_at)))]),_r("toggle",Qn,_t),w(Oe,ze)},Xe=Oe=>{var p=Uf(),ze=E(p),ve=D(E(ze)),Tt=D(ve,3),jt=E(Tt);y(Tt);var lr=D(Tt,2),$e=E(lr);y(lr),y(ze);var Ce=D(ze,2);Ct(Ce,5,()=>(n(L),d(()=>n(L).releases||[])),Ae=>Ae.slug,(Ae,Se)=>{var Er=Of(),$r=E(Er),Yn=E($r),Sn=D(E(Yn),2),oo=E(Sn,!0);y(Sn),y(Yn);var gs=D(Yn,2),ms=E(gs);{var Qn=en=>{var Kn=qf(),io=E(Kn,!0);y(Kn),j(ao=>V(io,ao),[()=>(n(Se),d(()=>n(Se).commit_sha.slice(0,7)))]),w(en,Kn)};Q(ms,en=>{n(Se),d(()=>n(Se).commit_sha)&&en(Qn)})}var Dn=D(ms,2),lo=E(Dn,!0);y(Dn),y(gs),y($r),y(Er),j(en=>{Hr(Sn,"href",`/orgs/${o()??""}/projects/${n(Se),_(l()),d(()=>n(Se).project_name||l())??""}/releases/${n(Se),d(()=>n(Se).slug)??""}`),V(oo,(n(Se),d(()=>n(Se).title))),V(lo,en)},[()=>(_(pn),n(Se),d(()=>pn(n(Se).created_at)))]),w(Ae,Er)}),y(Ce),y(p),j(()=>{V(ve,` ${n(L),d(()=>n(L).count)??""} hidden commit${n(L),d(()=>n(L).count!==1?"s":"")??""} `),V(jt,`Show commit${n(L),d(()=>n(L).count!==1?"s":"")??""}`),V($e,`Hide commit${n(L),d(()=>n(L).count!==1?"s":"")??""}`)}),_r("toggle",p,_t),w(Oe,p)};Q(oe,Oe=>{n(L),d(()=>n(L).kind==="release"&&n(L).release)?Oe(Te):(n(L),d(()=>n(L).kind==="hidden")&&Oe(Xe,1))})}w(re,R)}),y(te),Tl(te,re=>U(x,re),()=>n(x));var P=D(te,2);Ct(P,5,()=>n(v),re=>re.name,(re,L)=>{var R=jf();zr(R,"width: 20px; margin-right: 4px; display: flex; justify-content: center;");var oe=E(R),Te=E(oe,!0);y(oe),y(R),j(()=>{zr(oe,`writing-mode: vertical-rl; transform: rotate(180deg); font-size: 10px; font-weight: 500; color: ${n(L),d(()=>n(L).color)??""}; white-space: nowrap;`),V(Te,(n(L),d(()=>n(L).name)))}),w(re,R)}),y(P),y(k),j(()=>zr(k,`grid-template-columns: ${n(s)??""}px 1fr; grid-template-rows: 1fr auto;`)),w(h,k)};Q(Cn,h=>{n(m)?h(ro):n(b)?h(no,1):(n(c),d(()=>n(c).length===0)?h(so,2):h(ac,-1))})}return w(e,Xr),ns($n)}customElements.define("release-timeline",Ks(zf,{org:{},project:{},csrf:{},username:{},role:{}},[],[]));var Hf=C(' Waiting for logs…',1),Gf=C('
'),Vf=C('
No logs recorded for this release.
'),Wf=C(''),Yf=C(' Live'),Qf=Le(''),Kf=Le(''),Jf=C(' '),Xf=C('
'),Zf=C(''),ec=C('
',1),tc=C("
");const rc={hash:"svelte-qvn6bd",code:`.logs-root.svelte-qvn6bd {position:relative;border:1px solid #e5e7eb;border-radius:0.5rem;overflow:hidden;font-family:ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;font-size:0.8125rem;line-height:1.625;background:#111827;color:#d1d5db;}.logs-empty.svelte-qvn6bd {padding:2rem;text-align:center;color:#6b7280;font-family:system-ui, -apple-system, sans-serif;font-size:0.875rem;display:flex;align-items:center;justify-content:center;gap:0.5rem;}.logs-header.svelte-qvn6bd {display:flex;align-items:center;background:#1f2937;border-bottom:1px solid #374151;}.logs-tabs.svelte-qvn6bd {display:flex;gap:0;overflow-x:auto;flex:1;min-width:0;}.logs-tab.svelte-qvn6bd {padding:0.5rem 1rem;font-size:0.75rem;font-family:system-ui, -apple-system, sans-serif;color:#9ca3af;background:transparent;border:none;border-bottom:2px solid transparent;cursor:pointer;white-space:nowrap;display:flex;align-items:center;gap:0.375rem;transition:color 0.15s, border-color 0.15s;}.logs-tab.svelte-qvn6bd:hover {color:#e5e7eb;}.logs-tab.active.svelte-qvn6bd {color:#f9fafb;border-bottom-color:#3b82f6;}.logs-count.svelte-qvn6bd {font-size:0.625rem;padding:0.0625rem 0.375rem;border-radius:9999px;background:#374151;color:#9ca3af;}.logs-controls.svelte-qvn6bd {display:flex;align-items:center;gap:0.25rem;padding:0 0.5rem;flex-shrink:0;}.logs-ctrl-btn.svelte-qvn6bd {display:flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;border-radius:0.25rem;border:none;background:transparent;color:#6b7280;cursor:pointer;transition:color 0.15s, background 0.15s;}.logs-ctrl-btn.svelte-qvn6bd:hover {color:#d1d5db;background:#374151;}.logs-ctrl-btn.active.svelte-qvn6bd {color:#93c5fd;background:#1e3a5f;}.logs-live.svelte-qvn6bd {display:flex;align-items:center;gap:0.375rem;font-family:system-ui, -apple-system, sans-serif;font-size:0.6875rem;color:#34d399;text-transform:uppercase;letter-spacing:0.05em;padding-right:0.5rem;}.logs-dot.svelte-qvn6bd {width:0.5rem;height:0.5rem;border-radius:9999px;background:#34d399;display:inline-block; + animation: svelte-4kxpm1-lane-pulse 2s ease-in-out infinite;}`};function cc(e,t){us(t,!1),oo(e,fc);const n=et(),s=et();let o=Er(t,"org",12,""),a=Er(t,"project",12,""),l=Er(t,"csrf",12,""),i=Er(t,"username",12,""),f=Er(t,"role",12,""),u=et([]),v=et([]),x=et(!0),y=et(null),M=et(null),N=Date.now(),H=null,k=et(null),L=et({});const ie=20,oe=4,ae=12,nt=new Set(["QUEUED","RUNNING","ASSIGNED"]),me=new Set(["SUCCEEDED"]);let q=et(new Set),he=et(null);function st(){return f()==="owner"||f()==="admin"}function wt(_){return i()&&_.source_user===i()}async function Mt(_,b,T=!1){const G=`${_.release_intent_id}:${b.environment}`;if(!r(q).has(G)){r(q).add(G),I(q,r(q)),I(he,null);try{const F=new URLSearchParams;F.set("csrf_token",l()),F.set("release_intent_id",_.release_intent_id),F.set("target_environment",b.environment),T&&F.set("force_bypass","true");const K=await fetch(`/orgs/${o()}/projects/${_.project_name}/releases/${_.slug}/approve`,{method:"POST",body:F,credentials:"same-origin",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},redirect:"manual"});if(K.ok||K.status===303||K.status===302||K.status===0)await Ye();else{const j=await K.text().catch(()=>"");let P;try{P=JSON.parse(j).error}catch{}if(!P){const Z=j.match(/]*>\s*(.*?)\s*<\/p>/);P=Z==null?void 0:Z[1]}I(he,P||`Approval failed (${K.status})`),setTimeout(()=>{I(he,null)},8e3)}}catch(F){I(he,F.message||"Approval request failed"),setTimeout(()=>{I(he,null)},8e3)}finally{r(q).delete(G),I(q,r(q))}}}let R=et({}),J=et(new Set);async function X(_,b,T=!1){const G=`plan:${_.release_intent_id}:${b.id}`;if(!r(q).has(G)){r(q).add(G),I(q,r(q)),I(he,null);try{const F=T?"reject":"approve",K=new URLSearchParams;K.set("csrf_token",l()),K.set("release_intent_id",_.release_intent_id);const j=await fetch(`/api/orgs/${o()}/projects/${_.project_name||a()}/plan-stages/${b.id}/${F}`,{method:"POST",body:K,credentials:"same-origin",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"}});if(j.ok)await Ye();else{const P=await j.text().catch(()=>"");let Z;try{Z=JSON.parse(P).error}catch{}I(he,Z||`Plan ${F} failed (${j.status})`),setTimeout(()=>{I(he,null)},8e3)}}catch(F){I(he,F.message||"Plan action failed"),setTimeout(()=>{I(he,null)},8e3)}finally{r(q).delete(G),I(q,r(q))}}}async function de(_,b){const T=`${_.release_intent_id}:${b.id}`;if(!r(J).has(T)){if(r(R)[T]){delete r(R)[T],I(R,r(R));return}r(J).add(T),I(J,r(J));try{const G=await fetch(`/api/orgs/${o()}/projects/${_.project_name||a()}/plan-stages/${b.id}/output?release_intent_id=${encodeURIComponent(_.release_intent_id)}`,{credentials:"same-origin",headers:{Accept:"application/json"}});if(G.ok){const F=await G.json();ri(R,r(R)[T]=F),I(R,r(R))}else I(he,`Failed to load plan output (${G.status})`),setTimeout(()=>{I(he,null)},8e3)}catch(G){I(he,G.message||"Failed to load plan output"),setTimeout(()=>{I(he,null)},8e3)}finally{r(J).delete(T),I(J,r(J))}}}let Me=null;function Se(){Me||(Me=setTimeout(()=>{Me=null,Ye()},300))}async function ot(){try{I(y,null);const _=await Ba(o(),a());Sr(_.timeline,_.lanes),I(x,!1),ge()}catch(_){I(y,_.message),I(x,!1)}}async function Ye(){try{const _=await Ba(o(),a());Sr(_.timeline,_.lanes),ge()}catch(_){console.warn("[release-timeline] refresh failed:",_)}}function Sr(_,b){const T=new Map;for(const F of r(u))F.kind==="release"&&F.release&&T.set(F.release.slug,F);const G=_.map(F=>{if(F.kind!=="release"||!F.release)return F;const K=T.get(F.release.slug);if(!K)return F;const j=K.release,P=F.release;return j.dest_envs===P.dest_envs&&j.has_pipeline===P.has_pipeline&&Rn(j.pipeline_stages,P.pipeline_stages)&&co(j.destinations,P.destinations)?K:F});I(u,G),I(v,b)}function Rn(_,b){if(_.length!==b.length)return!1;for(let T=0;T<_.length;T++)if(_[T].status!==b[T].status||_[T].started_at!==b[T].started_at||_[T].completed_at!==b[T].completed_at)return!1;return!0}function co(_,b){if(_.length!==b.length)return!1;for(let T=0;T<_.length;T++)if(_[T].status!==b[T].status||_[T].completed_at!==b[T].completed_at)return!1;return!0}function uo(_,b){_==="destination"&&b.action==="status_changed"?Es(b):_==="release"?b.action==="created"?Se():(b.action==="status_changed"||b.action==="updated")&&on(b):_==="artifact"&&(b.action==="created"||b.action==="updated")?Se():_==="pipeline"&&vo(b)}function Es(_){var K,j,P;const b=(K=_.metadata)==null?void 0:K.status,T=((j=_.metadata)==null?void 0:j.destination_name)||_.resource_id,G=(P=_.metadata)==null?void 0:P.environment;if(!b||!T)return;let F=!1;I(u,r(u).map(Z=>{if(Z.kind!=="release"||!Z.release)return Z;const Re=Z.release;if(Re.destinations.findIndex(_e=>_e.name===T)===-1)return Z;F=!0;const Be=Re.destinations.map(_e=>_e.name===T?{..._e,status:b,...["SUCCEEDED","FAILED","TIMED_OUT","CANCELLED"].includes(b)?{completed_at:new Date().toISOString()}:{}}:_e),p=Be.map(_e=>`${_e.environment}:${_e.status||"PENDING"}`).join(","),Qe=G?Re.pipeline_stages.map(_e=>_e.stage_type==="deploy"&&_e.environment===G?{..._e,status:b==="ASSIGNED"?"RUNNING":b}:_e):Re.pipeline_stages;return{...Z,release:{...Re,destinations:Be,dest_envs:p,pipeline_stages:Qe}}})),F&&ge()}function on(_){var G,F;const b=(G=_.metadata)==null?void 0:G.status,T=(F=_.metadata)==null?void 0:F.environment;b&&T?Es(_):Se()}function vo(_){var K,j,P;const b=(K=_.metadata)==null?void 0:K.status,T=(j=_.metadata)==null?void 0:j.environment,G=(P=_.metadata)==null?void 0:P.stage_type;if(!b){(_.action==="created"||_.action==="updated")&&Se();return}let F=!1;I(u,r(u).map(Z=>{if(Z.kind!=="release"||!Z.release)return Z;const Re=Z.release;let at=!1;const Be=Re.pipeline_stages.map(p=>T&&p.stage_type==="deploy"&&p.environment===T?(at=!0,{...p,status:b,...p.started_at?{}:{started_at:new Date().toISOString()}}):G==="wait"&&p.stage_type==="wait"?(at=!0,{...p,status:b}):p);return at?(F=!0,{...Z,release:{...Re,pipeline_stages:Be}}):Z})),F&&ge()}function $s(_){return _?_.split(",").map(b=>b.trim()).filter(Boolean).map(b=>{const T=b.indexOf(":");return T===-1?{env:b,status:"SUCCEEDED"}:{env:b.slice(0,T),status:b.slice(T+1)}}):[]}let xe=null;function ge(){xe||(xe=requestAnimationFrame(()=>{xe=null,vi().then(Rt)}))}function Rt(){if(!r(k))return;const _=r(k).getBoundingClientRect();if(_.height===0)return;const b=_.height,T=Array.from(r(k).querySelectorAll("[data-release]")),G={};for(const F of r(v)){const K=F.name;let j=null,P=null,Z=-1,Re=-1;for(let Ne=0;NeIr.env===K))continue;const Tr=(Ne.querySelector("[data-avatar]")||Ne).getBoundingClientRect();vr.push(Tr.top+Tr.height/2-_.top)}G[K]={solidH:p,hasHatch:Qe,hatchTop:_e,hatchH:Lt,isForward:Ht,dots:vr,color:zi(K)}}I(L,G)}const Nr=new Map;function Dr(_,b){const T=`${_}|${b}`;let G=Nr.get(T);if(G)return G;const F=``;return G=`url("data:image/svg+xml,${encodeURIComponent(F)}")`,Nr.set(T,G),G}Ra(()=>{ot(),H=setInterval(()=>{N=Date.now()},1e4)}),yi(()=>{r(M)&&r(M)(),H&&clearInterval(H),Me&&clearTimeout(Me),xe&&cancelAnimationFrame(xe)});function Ln(){ge()}function Pn(_,b,T){if(!_)return"";const G=new Date(_).getTime();if(isNaN(G))return"";if(b&&T!=="RUNNING"&&T!=="QUEUED"){const F=new Date(b).getTime();if(!isNaN(F))return za(Math.floor((F-G)/1e3))}return za(Math.floor((N-G)/1e3))}function On(_){var b;return _.kind==="release"&&_.release?`r:${_.release.slug}`:_.kind==="hidden"?`h:${_.count}:${((b=(_.releases||[])[0])==null?void 0:b.slug)||""}`:`u:${Math.random()}`}function ts(_,b){if(!_)return!1;switch(_.label){case"Pipeline complete":return b==="SUCCEEDED";case"Pipeline failed":return b==="FAILED"||b==="RUNNING"||b==="ASSIGNED";case"Deploying to":return b==="RUNNING"||b==="ASSIGNED";case"Queued":return b==="QUEUED";case"Waiting for time window":return b==="RUNNING"||b==="ASSIGNED";default:return b!=="PENDING"&&b!=="SUCCEEDED"}}function an(_){return _.stage_type==="plan"&&_.approval_status&&(_.approval_status==="AWAITINGAPPROVAL"||_.approval_status==="AWAITING_APPROVAL")?"AWAITING_APPROVAL":_.status}function po(_){return _.stage_type==="plan"&&an(_)==="AWAITING_APPROVAL"}Ys(()=>(r(x),r(y),h(o()),r(M),h(a())),()=>{!r(x)&&!r(y)&&o()&&!r(M)&&I(M,Fi(o(),a(),uo))}),Ys(()=>r(v),()=>{I(n,r(v).length)}),Ys(()=>r(n),()=>{I(s,r(n)*(ie+oe)+8)}),ii();var ho={get org(){return o()},set org(_){o(_),Kt()},get project(){return a()},set project(_){a(_),Kt()},get csrf(){return l()},set csrf(_){l(_),Kt()},get username(){return i()},set username(_){i(_),Kt()},get role(){return f()},set role(_){f(_),Kt()}};Pi();var Cs=ic();Tt("resize",Gs,Ln);var Ka=Fe(Cs);{var Nc=_=>{var b=Gi(),T=A(E(b)),G=A(T);w(b),O(()=>B(T,` ${r(he)??""} `)),Tt("click",G,()=>I(he,null)),m(_,b)};Y(Ka,_=>{r(he)&&_(Nc)})}var Dc=A(Ka,2);{var Tc=_=>{var b=Hi();m(_,b)},Ic=_=>{var b=Vi(),T=E(b),G=E(T,!0);w(T);var F=A(T,2);w(b),O(()=>B(G,r(y))),Tt("click",F,ot),m(_,b)},Mc=_=>{var b=Wi();m(_,b)},Rc=_=>{var b=lc(),T=E(b);mt(T,5,()=>r(v),K=>K.name,(K,j)=>{const P=qe(()=>(r(L),r(j),c(()=>r(L)[r(j).name]))),Z=qe(()=>{const[p,Qe]=(h(r(P)),r(j),c(()=>{var _e;return((_e=r(P))==null?void 0:_e.color)||[r(j).color,"#e5e7eb"]}));return{barColor:p,lightColor:Qe}});var Re=Xi();Zr(Re,"width: 20px; margin-right: 4px; position: relative;");var at=E(Re);{var Be=p=>{var Qe=Ki(),_e=Fe(Qe);{var Lt=De=>{var Le=Yi();O(Te=>Zr(Le,`position: absolute; left: 0; width: 100%; top: ${h(r(P)),c(()=>r(P).hatchTop)??""}px; height: ${h(r(P)),c(()=>r(P).hatchH+(r(P).solidH>0?ie/2:0))??""}px; background-image: ${Te??""}; background-size: 8px 8px; background-repeat: repeat; border-radius: 9999px; z-index: 0;`),[()=>(h(r(P)),h(r(Z).barColor),h(r(Z).lightColor),c(()=>r(P).isForward?Dr(r(Z).barColor,r(Z).lightColor):Dr("#f59e0b","#fef3c7")))]),m(De,Le)};Y(_e,De=>{h(r(P)),c(()=>r(P).hasHatch)&&De(Lt)})}var Ht=A(_e,2);{var vr=De=>{var Le=Qi();O(()=>Zr(Le,`position: absolute; bottom: 0; left: 0; width: 100%; height: ${h(r(P)),c(()=>r(P).solidH+(r(P).hasHatch?ie/2:0))??""}px; background: ${r(Z).barColor??""}; border-radius: 9999px; z-index: 1;`)),m(De,Le)};Y(Ht,De=>{h(r(P)),c(()=>r(P).solidH>0)&&De(vr)})}var Ne=A(Ht,2);mt(Ne,1,()=>(h(r(P)),c(()=>r(P).dots)),xs,(De,Le)=>{var Te=Ji();O(()=>Zr(Te,`position: absolute; left: 50%; transform: translateX(-50%); top: ${r(Le)-ae/2}px; width: 12px; height: 12px; border-radius: 50%; background: #fff; border: 2px solid ${r(Z).barColor??""}; z-index: 2;`)),m(De,Te)}),m(p,Qe)};Y(at,p=>{r(P)&&p(Be)})}w(Re),m(K,Re)}),w(T);var G=A(T,2);mt(G,5,()=>r(u),K=>On(K),(K,j)=>{var P=kn(),Z=Fe(P);{var Re=Be=>{const p=qe(()=>(r(j),c(()=>r(j).release)));var Qe=rc(),_e=E(Qe),Lt=E(_e),Ht=A(E(Lt),2),vr=E(Ht,!0);w(Ht),w(Lt);var Ne=A(Lt,2),De=E(Ne);{var Le=z=>{var g=Zi(),fe=A(E(g));w(g),O(()=>B(fe,` ${h(r(p)),c(()=>r(p).branch)??""}`)),m(z,g)};Y(De,z=>{h(r(p)),c(()=>r(p).branch)&&z(Le)})}var Te=A(De,2);{var Tr=z=>{var g=ef(),fe=E(g,!0);w(g),O(S=>B(fe,S),[()=>(h(r(p)),c(()=>r(p).commit_sha.slice(0,7)))]),m(z,g)};Y(Te,z=>{h(r(p)),c(()=>r(p).commit_sha)&&z(Tr)})}var Ir=A(Te,2),rs=E(Ir,!0);w(Ir);var jn=A(Ir,2);{var _o=z=>{var g=tf(),fe=A(E(g),2),S=E(fe,!0);w(fe),w(g),O(()=>{en(fe,"href",`/users/${h(r(p)),c(()=>r(p).source_user)??""}`),B(S,(h(r(p)),c(()=>r(p).source_user)))}),m(z,g)};Y(jn,z=>{h(r(p)),c(()=>r(p).source_user)&&z(_o)})}var As=A(jn,2);{var Ss=z=>{var g=rf(),fe=E(g,!0);w(g),O(()=>{en(g,"href",`/orgs/${o()??""}/projects/${h(r(p)),c(()=>r(p).project_name)??""}`),B(fe,(h(r(p)),c(()=>r(p).project_name)))}),m(z,g)};Y(As,z=>{h(r(p)),h(a()),c(()=>r(p).project_name&&r(p).project_name!==a())&&z(Ss)})}w(Ne),w(_e);var ns=A(_e,2),qn=E(ns),mo=E(qn);{var ln=z=>{const g=qe(()=>(h(r(p)),c(()=>r(p).env_groups&&r(p).env_groups.length>0&&r(p).env_groups.every(ke=>ke.status==="SUCCEEDED"))));var fe=of(),S=A(Fe(fe));{var kt=ke=>{var Je=nf();lr(2),m(ke,Je)},ce=ke=>{var Je=sf();lr(2),m(ke,Je)};Y(S,ke=>{r(g)?ke(kt):ke(ce,-1)})}m(z,fe)},ss=qt(()=>(h(r(p)),h($n),c(()=>r(p).has_pipeline&&!$n(r(p).pipeline_stages)))),go=z=>{const g=qe(()=>(h($n),h(r(p)),c(()=>$n(r(p).pipeline_stages))));var fe=gf(),S=A(Fe(fe),2);{var kt=V=>{var U=af();m(V,U)},ce=V=>{var U=lf();O(()=>pe(U,0,`w-4 h-4 ${h(r(g)),c(()=>r(g).iconColor)??""} shrink-0`,"svelte-4kxpm1")),m(V,U)},ke=V=>{var U=ff();O(()=>pe(U,0,`w-4 h-4 ${h(r(g)),c(()=>r(g).iconColor)??""} shrink-0`,"svelte-4kxpm1")),m(V,U)},Je=V=>{var U=cf();O(()=>pe(U,0,`w-4 h-4 ${h(r(g)),c(()=>r(g).iconColor)??""} shrink-0`,"svelte-4kxpm1")),m(V,U)},Mr=V=>{var U=uf();O(()=>pe(U,0,`w-4 h-4 ${h(r(g)),c(()=>r(g).iconColor)??""} shrink-0`,"svelte-4kxpm1")),m(V,U)},fn=V=>{var U=df();m(V,U)};Y(S,V=>{h(r(g)),c(()=>r(g).icon==="pulse")?V(kt):(h(r(g)),c(()=>r(g).icon==="check-circle")?V(ce,1):(h(r(g)),c(()=>r(g).icon==="x-circle")?V(ke,2):(h(r(g)),c(()=>r(g).icon==="clock")?V(Je,3):(h(r(g)),c(()=>r(g).icon==="shield")?V(Mr,4):V(fn,-1)))))})}var lt=A(S,2),Vt=E(lt,!0);w(lt);var pr=A(lt,2);mt(pr,1,()=>(h(r(p)),c(()=>r(p).pipeline_stages)),V=>V.id||V.environment||V.stage_type,(V,U)=>{var hr=mf(),Lr=Fe(hr);{var cn=re=>{const $e=qe(()=>(h(er),r(U),c(()=>er(r(U).environment||"")))),Ie=qe(()=>(h(Ga),r(U),h(r($e)),c(()=>Ga(r(U).status)||r($e).dot)));var ze=vf(),yt=E(ze),Pt=A(yt);w(ze),O(()=>{pe(ze,1,`inline-flex items-center gap-1 text-xs font-medium px-2 py-0.5 rounded-full ${h(r($e)),c(()=>r($e).bg)??""}`,"svelte-4kxpm1"),B(yt,`${r(U),c(()=>r(U).environment)??""} `),pe(Pt,1,`w-1.5 h-1.5 rounded-full ${r(Ie)??""}`,"svelte-4kxpm1")}),m(re,ze)},un=qt(()=>(r(U),h(r(g)),c(()=>r(U).stage_type==="deploy"&&ts(r(g),r(U).status))));Y(Lr,re=>{r(un)&&re(cn)})}var Yt=A(Lr,2);{var dn=re=>{var $e=pf(),Ie=Fe($e),ze=E(Ie);lr(),w(Ie);var yt=A(Ie,2);O(Pt=>{B(ze,`${r(U),c(()=>r(U).environment)??""} plan `),yt.disabled=Pt},[()=>(r(q),h(r(p)),r(U),c(()=>r(q).has(`plan:${r(p).release_intent_id}:${r(U).id}`)))]),Tt("click",yt,yn(()=>X(r(p),r(U)))),m(re,$e)},C=qt(()=>(r(U),h(r(p)),h(l()),c(()=>r(U).stage_type==="plan"&&po(r(U))&&r(p).release_intent_id&&l())));Y(Yt,re=>{r(C)&&re(dn)})}var $=A(Yt,2);{var ue=re=>{var $e=kn(),Ie=Fe($e);{var ze=it=>{var Et=hf();O(Ke=>Et.disabled=Ke,[()=>(r(q),h(r(p)),r(U),c(()=>r(q).has(`${r(p).release_intent_id}:${r(U).environment}`)))]),Tt("click",Et,yn(()=>{confirm("You are the release author. Bypass approval?")&&Mt(r(p),r(U),!0)})),m(it,Et)},yt=qt(()=>(h(r(p)),c(()=>wt(r(p))&&st()))),Pt=it=>{var Et=_f();O(Ke=>Et.disabled=Ke,[()=>(r(q),h(r(p)),r(U),c(()=>r(q).has(`${r(p).release_intent_id}:${r(U).environment}`)))]),Tt("click",Et,yn(()=>Mt(r(p),r(U)))),m(it,Et)},or=qt(()=>(h(r(p)),c(()=>!wt(r(p)))));Y(Ie,it=>{r(yt)?it(ze):r(or)&&it(Pt,1)})}m(re,$e)};Y($,re=>{r(U),h(r(p)),h(l()),c(()=>r(U).blocked_by&&r(p).release_intent_id&&l())&&re(ue)})}m(V,hr)});var Rr=A(pr,2),Wt=E(Rr);w(Rr),O(()=>{pe(lt,1,`${h(r(g)),c(()=>r(g).color)??""} text-sm`,"svelte-4kxpm1"),B(Vt,(h(r(g)),c(()=>r(g).label))),B(Wt,`${h(r(g)),c(()=>r(g).done)??""}/${h(r(g)),c(()=>r(g).total)??""}`)}),m(z,fe)},xo=qt(()=>(h(r(p)),h($n),c(()=>r(p).has_pipeline&&$n(r(p).pipeline_stages)))),Lc=z=>{const g=qe(()=>(h(r(p)),c(()=>r(p).env_groups.every(ke=>ke.status==="SUCCEEDED"))));var fe=kn(),S=Fe(fe);{var kt=ke=>{var Je=xf();lr(2),m(ke,Je)},ce=ke=>{var Je=kn(),Mr=Fe(Je);mt(Mr,1,()=>(h(r(p)),c(()=>r(p).env_groups)),xs,(fn,lt)=>{var Vt=kn(),pr=Fe(Vt);{var Rr=Wt=>{const V=qe(()=>(h(io),r(lt),c(()=>io[r(lt).status]||io.SUCCEEDED)));var U=Ef(),hr=Fe(U);{var Lr=$=>{var ue=bf();m($,ue)},cn=$=>{var ue=wf();O(()=>pe(ue,0,`w-4 h-4 ${h(r(V)),c(()=>r(V).iconColor)??""} shrink-0`,"svelte-4kxpm1")),m($,ue)},un=$=>{var ue=kf();O(()=>pe(ue,0,`w-4 h-4 ${h(r(V)),c(()=>r(V).iconColor)??""} shrink-0`,"svelte-4kxpm1")),m($,ue)};Y(hr,$=>{h(r(V)),c(()=>r(V).icon==="pulse")?$(Lr):(h(r(V)),c(()=>r(V).icon==="check-circle")?$(cn,1):$(un,-1))})}var Yt=A(hr,2),dn=E(Yt,!0);w(Yt);var C=A(Yt,2);mt(C,1,()=>(r(lt),c(()=>r(lt).envs)),$=>$,($,ue)=>{const re=qe(()=>(h(er),r(ue),c(()=>er(r(ue)))));var $e=yf(),Ie=E($e),ze=A(Ie);w($e),O(()=>{pe($e,1,`inline-flex items-center gap-1 text-xs font-medium px-2 py-0.5 rounded-full ${h(r(re)),c(()=>r(re).bg)??""}`,"svelte-4kxpm1"),B(Ie,`${r(ue)??""} `),pe(ze,1,`w-1.5 h-1.5 rounded-full ${h(r(re)),c(()=>r(re).dot)??""}`,"svelte-4kxpm1")}),m($,$e)}),O(()=>{pe(Yt,1,`${h(r(V)),c(()=>r(V).color)??""} text-sm`,"svelte-4kxpm1"),B(dn,(h(r(V)),c(()=>r(V).label)))}),m(Wt,U)};Y(pr,Wt=>{r(lt),c(()=>r(lt).status!=="SUCCEEDED")&&Wt(Rr)})}m(fn,Vt)}),m(ke,Je)};Y(S,ke=>{r(g)?ke(kt):ke(ce,-1)})}m(z,fe)},Pc=z=>{var g=$f();lr(2),m(z,g)};Y(mo,z=>{r(ss)?z(ln):r(xo)?z(go,1):(h(r(p)),c(()=>r(p).env_groups&&r(p).env_groups.length>0)?z(Lc,2):z(Pc,-1))})}lr(2),w(qn);var bo=A(qn,2),Xa=E(bo);{var Oc=z=>{var g=Cf(),fe=E(g,!0);w(g),O(()=>B(fe,(h(r(p)),c(()=>r(p).description)))),m(z,g)};Y(Xa,z=>{h(r(p)),c(()=>r(p).description)&&z(Oc)})}var Za=A(Xa,2),wo=E(Za),jc=E(wo,!0);w(wo);var qc=A(wo,2);{var Uc=z=>{var g=Af(),fe=E(g,!0);w(g),O(()=>B(fe,(h(r(p)),c(()=>r(p).version)))),m(z,g)};Y(qc,z=>{h(r(p)),c(()=>r(p).version)&&z(Uc)})}w(Za),w(bo);var el=A(bo,2);{var Fc=z=>{var g=Gf();mt(g,7,()=>(h(r(p)),c(()=>r(p).pipeline_stages)),(fe,S)=>fe.id||`${fe.stage_type}-${fe.environment}-${S}`,(fe,S,kt)=>{const ce=qe(()=>(r(S),c(()=>an(r(S)))));var ke=zf(),Je=Fe(ke),Mr=E(Je);{var fn=C=>{var $=Sf();m(C,$)},lt=C=>{var $=Nf();m(C,$)},Vt=C=>{var $=Df();m(C,$)},pr=C=>{var $=Tf();m(C,$)},Rr=C=>{var $=If();m(C,$)},Wt=C=>{var $=Mf();m(C,$)};Y(Mr,C=>{r(ce)==="SUCCEEDED"?C(fn):r(ce)==="RUNNING"?C(lt,1):r(ce)==="QUEUED"?C(Vt,2):r(ce)==="FAILED"?C(pr,3):r(ce)==="AWAITING_APPROVAL"?C(Rr,4):C(Wt,-1)})}var V=A(Mr,2);{var U=C=>{const $=qe(()=>(h(er),r(S),c(()=>er(r(S).environment||""))));var ue=Rf(),re=Fe(ue),$e=E(re,!0);w(re);var Ie=A(re,2),ze=E(Ie),yt=A(ze);w(Ie),O(Pt=>{pe(re,1,`text-sm ${r(S),c(()=>r(S).status==="SUCCEEDED"?"text-gray-700":r(S).status==="RUNNING"?"text-yellow-700":r(S).status==="FAILED"?"text-red-700":"text-gray-400")??""}`,"svelte-4kxpm1"),B($e,Pt),pe(Ie,1,`inline-flex items-center gap-1 text-xs font-medium px-2 py-0.5 rounded-full ${h(r($)),c(()=>r($).bg)??""}`,"svelte-4kxpm1"),B(ze,`${r(S),c(()=>r(S).environment)??""} `),pe(yt,1,`w-1.5 h-1.5 rounded-full ${h(r($)),c(()=>r($).dot)??""}`,"svelte-4kxpm1")},[()=>(h(Va),r(S),c(()=>Va(r(S).status)))]),m(C,ue)},hr=C=>{var $=Lf(),ue=E($);w($),O(re=>{pe($,1,`text-sm ${r(S),c(()=>r(S).status==="SUCCEEDED"?"text-gray-700":r(S).status==="RUNNING"?"text-yellow-700":"text-gray-400")??""}`,"svelte-4kxpm1"),B(ue,`${re??""} ${r(S),c(()=>r(S).duration_seconds)??""}s`)},[()=>(h(Ha),r(S),c(()=>Ha(r(S).status)))]),m(C,$)},Lr=C=>{const $=qe(()=>(h(er),r(S),c(()=>er(r(S).environment||""))));var ue=jf(),re=Fe(ue),$e=E(re,!0);w(re);var Ie=A(re,2),ze=E(Ie),yt=A(ze);w(Ie);var Pt=A(Ie,2);{var or=Ke=>{var ft=Pf(),_r=Fe(ft),Pr=A(_r,2);O((os,ko)=>{_r.disabled=os,Pr.disabled=ko},[()=>(r(q),h(r(p)),r(S),c(()=>r(q).has(`plan:${r(p).release_intent_id}:${r(S).id}`))),()=>(r(q),h(r(p)),r(S),c(()=>r(q).has(`plan:${r(p).release_intent_id}:${r(S).id}`)))]),Tt("click",_r,yn(()=>X(r(p),r(S)))),Tt("click",Pr,yn(()=>{confirm("Reject this plan?")&&X(r(p),r(S),!0)})),m(Ke,ft)};Y(Pt,Ke=>{h(r(ce)),h(r(p)),h(l()),c(()=>r(ce)==="AWAITING_APPROVAL"&&r(p).release_intent_id&&l())&&Ke(or)})}var it=A(Pt,2);{var Et=Ke=>{var ft=Of(),_r=E(ft,!0);w(ft),O(Pr=>{ft.disabled=Pr,B(_r,(r(R),h(r(p)),r(S),c(()=>r(R)[`${r(p).release_intent_id}:${r(S).id}`]?"Hide plan":"View plan")))},[()=>(r(J),h(r(p)),r(S),c(()=>r(J).has(`${r(p).release_intent_id}:${r(S).id}`)))]),Tt("click",ft,yn(()=>de(r(p),r(S)))),m(Ke,ft)};Y(it,Ke=>{h(r(ce)),h(r(p)),c(()=>(r(ce)==="AWAITING_APPROVAL"||r(ce)==="SUCCEEDED"||r(ce)==="FAILED")&&r(p).release_intent_id)&&Ke(Et)})}O(Ke=>{pe(re,1,`text-sm ${r(ce)==="AWAITING_APPROVAL"?"text-purple-700":r(ce)==="SUCCEEDED"?"text-gray-700":r(ce)==="RUNNING"?"text-yellow-700":r(ce)==="FAILED"?"text-red-700":"text-gray-400"}`,"svelte-4kxpm1"),B($e,Ke),pe(Ie,1,`inline-flex items-center gap-1 text-xs font-medium px-2 py-0.5 rounded-full ${h(r($)),c(()=>r($).bg)??""}`,"svelte-4kxpm1"),B(ze,`${r(S),c(()=>r(S).environment)??""} `),pe(yt,1,`w-1.5 h-1.5 rounded-full ${h(r($)),c(()=>r($).dot)??""}`,"svelte-4kxpm1")},[()=>(h(Wa),h(r(ce)),c(()=>Wa(r(ce))))]),m(C,ue)};Y(V,C=>{r(S),c(()=>r(S).stage_type==="deploy")?C(U):(r(S),c(()=>r(S).stage_type==="wait")?C(hr,1):(r(S),c(()=>r(S).stage_type==="plan")&&C(Lr,2)))})}var cn=A(V,2);{var un=C=>{var $=qf(),ue=E($,!0);w($),O(re=>B(ue,re),[()=>(r(S),c(()=>Pn(r(S).started_at,r(S).completed_at,r(S).status)))]),m(C,$)};Y(cn,C=>{r(S),h(r(ce)),c(()=>r(S).started_at&&(r(ce)==="RUNNING"||r(ce)==="QUEUED"||r(ce)==="AWAITING_APPROVAL"||r(S).completed_at))&&C(un)})}lr(2),w(Je);var Yt=A(Je,2);{var dn=C=>{const $=qe(()=>(r(R),h(r(p)),r(S),c(()=>r(R)[`${r(p).release_intent_id}:${r(S).id}`])));var ue=Bf(),re=E(ue),$e=A(E(re),2),Ie=E($e,!0);w($e),w(re);var ze=A(re,2);{var yt=or=>{var it=kn(),Et=Fe(it);mt(Et,1,()=>(h(r($)),c(()=>r($).outputs)),Ke=>Ke.destination_id,(Ke,ft)=>{var _r=Uf(),Pr=E(_r),os=E(Pr),ko=E(os,!0);w(os);var tl=A(os,2),zc=E(tl,!0);w(tl),w(Pr);var rl=A(Pr,2),Gc=E(rl,!0);w(rl),w(_r),O(()=>{B(ko,(r(ft),c(()=>r(ft).destination_name))),B(zc,(r(ft),c(()=>r(ft).status))),B(Gc,(r(ft),c(()=>r(ft).plan_output||"(no output)")))}),m(Ke,_r)}),m(or,it)},Pt=or=>{var it=Ff(),Et=E(it,!0);w(it),O(()=>B(Et,(h(r($)),c(()=>r($).plan_output||"(no output)")))),m(or,it)};Y(ze,or=>{h(r($)),c(()=>r($).outputs&&r($).outputs.length>0)?or(yt):or(Pt,-1)})}w(ue),O(()=>B(Ie,(h(r($)),c(()=>r($).status)))),m(C,ue)};Y(Yt,C=>{r(S),r(R),h(r(p)),c(()=>r(S).stage_type==="plan"&&r(R)[`${r(p).release_intent_id}:${r(S).id}`])&&C(dn)})}O(()=>pe(Je,1,`px-4 py-2.5 flex items-center gap-3 text-sm ${h(r(kt)),h(r(p)),c(()=>r(kt){h(r(p)),c(()=>r(p).has_pipeline)&&z(Fc)})}var Bc=A(el,2);mt(Bc,3,()=>(h(r(p)),c(()=>r(p).destinations)),z=>z.name,(z,g,fe)=>{const S=qe(()=>(h(er),r(g),c(()=>er(r(g).environment||""))));var kt=tc(),ce=E(kt);{var ke=C=>{var $=Hf();m(C,$)},Je=C=>{var $=Vf();m(C,$)},Mr=C=>{var $=Wf();m(C,$)},fn=C=>{var $=Yf();m(C,$)},lt=C=>{var $=Qf();m(C,$)};Y(ce,C=>{r(g),c(()=>r(g).status==="SUCCEEDED")?C(ke):(r(g),c(()=>r(g).status==="RUNNING"||r(g).status==="ASSIGNED")?C(Je,1):(r(g),c(()=>r(g).status==="QUEUED")?C(Mr,2):(r(g),c(()=>r(g).status==="FAILED")?C(fn,3):C(lt,-1))))})}var Vt=A(ce,2),pr=E(Vt),Rr=A(pr);w(Vt);var Wt=A(Vt,2),V=E(Wt,!0);w(Wt);var U=A(Wt,2);{var hr=C=>{var $=Jf();m(C,$)},Lr=C=>{var $=Kf();m(C,$)},cn=C=>{var $=Xf(),ue=E($);w($),O(()=>B(ue,`Queued${r(g),c(()=>r(g).queue_position?` #${r(g).queue_position}`:"")??""}`)),m(C,$)},un=C=>{var $=Zf();m(C,$)};Y(U,C=>{r(g),c(()=>r(g).status==="SUCCEEDED")?C(hr):(r(g),c(()=>r(g).status==="RUNNING")?C(Lr,1):(r(g),c(()=>r(g).status==="QUEUED")?C(cn,2):(r(g),c(()=>r(g).status==="FAILED")&&C(un,3))))})}var Yt=A(U,2);{var dn=C=>{var $=ec(),ue=E($,!0);w($),O(re=>B(ue,re),[()=>(h(En),r(g),c(()=>En(r(g).completed_at)))]),m(C,$)};Y(Yt,C=>{r(g),c(()=>r(g).completed_at)&&C(dn)})}w(kt),O(()=>{pe(kt,1,`px-4 py-2 flex items-center gap-3 text-sm ${h(r(fe)),h(r(p)),c(()=>r(fe)r(S).bg)??""}`,"svelte-4kxpm1"),B(pr,`${r(g),c(()=>r(g).environment)??""} `),pe(Rr,1,`w-1.5 h-1.5 rounded-full ${h(r(S)),c(()=>r(S).dot)??""}`,"svelte-4kxpm1"),B(V,(r(g),c(()=>r(g).name)))}),m(z,kt)}),w(ns),w(Qe),O(z=>{en(Qe,"data-envs",(h(r(p)),c(()=>r(p).dest_envs))),en(Ht,"href",`/orgs/${o()??""}/projects/${h(r(p)),h(a()),c(()=>r(p).project_name||a())??""}/releases/${h(r(p)),c(()=>r(p).slug)??""}`),B(vr,(h(r(p)),c(()=>r(p).title))),B(rs,z),B(jc,(h(r(p)),c(()=>r(p).slug)))},[()=>(h(En),h(r(p)),c(()=>En(r(p).created_at)))]),Tt("toggle",ns,ge),m(Be,Qe)},at=Be=>{var p=oc(),Qe=E(p),_e=A(E(Qe)),Lt=A(_e,3),Ht=E(Lt);w(Lt);var vr=A(Lt,2),Ne=E(vr);w(vr),w(Qe);var De=A(Qe,2);mt(De,5,()=>(r(j),c(()=>r(j).releases||[])),Le=>Le.slug,(Le,Te)=>{var Tr=sc(),Ir=E(Tr),rs=E(Ir),jn=A(E(rs),2),_o=E(jn,!0);w(jn),w(rs);var As=A(rs,2),Ss=E(As);{var ns=ln=>{var ss=nc(),go=E(ss,!0);w(ss),O(xo=>B(go,xo),[()=>(r(Te),c(()=>r(Te).commit_sha.slice(0,7)))]),m(ln,ss)};Y(Ss,ln=>{r(Te),c(()=>r(Te).commit_sha)&&ln(ns)})}var qn=A(Ss,2),mo=E(qn,!0);w(qn),w(As),w(Ir),w(Tr),O(ln=>{en(jn,"href",`/orgs/${o()??""}/projects/${r(Te),h(a()),c(()=>r(Te).project_name||a())??""}/releases/${r(Te),c(()=>r(Te).slug)??""}`),B(_o,(r(Te),c(()=>r(Te).title))),B(mo,ln)},[()=>(h(En),r(Te),c(()=>En(r(Te).created_at)))]),m(Le,Tr)}),w(De),w(p),O(()=>{B(_e,` ${r(j),c(()=>r(j).count)??""} hidden commit${r(j),c(()=>r(j).count!==1?"s":"")??""} `),B(Ht,`Show commit${r(j),c(()=>r(j).count!==1?"s":"")??""}`),B(Ne,`Hide commit${r(j),c(()=>r(j).count!==1?"s":"")??""}`)}),Tt("toggle",p,ge),m(Be,p)};Y(Z,Be=>{r(j),c(()=>r(j).kind==="release"&&r(j).release)?Be(Re):(r(j),c(()=>r(j).kind==="hidden")&&Be(at,1))})}m(K,P)}),w(G),qa(G,K=>I(k,K),()=>r(k));var F=A(G,2);mt(F,5,()=>r(v),K=>K.name,(K,j)=>{var P=ac();Zr(P,"width: 20px; margin-right: 4px; display: flex; justify-content: center;");var Z=E(P),Re=E(Z,!0);w(Z),w(P),O(()=>{Zr(Z,`writing-mode: vertical-rl; transform: rotate(180deg); font-size: 10px; font-weight: 500; color: ${r(j),c(()=>r(j).color)??""}; white-space: nowrap;`),B(Re,(r(j),c(()=>r(j).name)))}),m(K,P)}),w(F),w(b),O(()=>Zr(b,`grid-template-columns: ${r(s)??""}px 1fr; grid-template-rows: 1fr auto;`)),m(_,b)};Y(Dc,_=>{r(x)?_(Tc):r(y)?_(Ic,1):(r(u),c(()=>r(u).length===0)?_(Mc,2):_(Rc,-1))})}return m(e,Cs),ds(ho)}customElements.define("release-timeline",ao(cc,{org:{},project:{},csrf:{},username:{},role:{}},[],[]));var uc=D(' Waiting for logs…',1),dc=D('
'),vc=D('
No logs recorded for this release.
'),pc=D(''),hc=D(' Live'),_c=Oe(''),mc=Oe(''),gc=D(' '),xc=D('
'),bc=D(''),wc=D('
',1),kc=D("
");const yc={hash:"svelte-qvn6bd",code:`.logs-root.svelte-qvn6bd {position:relative;border:1px solid #e5e7eb;border-radius:0.5rem;overflow:hidden;font-family:ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;font-size:0.8125rem;line-height:1.625;background:#111827;color:#d1d5db;}.logs-empty.svelte-qvn6bd {padding:2rem;text-align:center;color:#6b7280;font-family:system-ui, -apple-system, sans-serif;font-size:0.875rem;display:flex;align-items:center;justify-content:center;gap:0.5rem;}.logs-header.svelte-qvn6bd {display:flex;align-items:center;background:#1f2937;border-bottom:1px solid #374151;}.logs-tabs.svelte-qvn6bd {display:flex;gap:0;overflow-x:auto;flex:1;min-width:0;}.logs-tab.svelte-qvn6bd {padding:0.5rem 1rem;font-size:0.75rem;font-family:system-ui, -apple-system, sans-serif;color:#9ca3af;background:transparent;border:none;border-bottom:2px solid transparent;cursor:pointer;white-space:nowrap;display:flex;align-items:center;gap:0.375rem;transition:color 0.15s, border-color 0.15s;}.logs-tab.svelte-qvn6bd:hover {color:#e5e7eb;}.logs-tab.active.svelte-qvn6bd {color:#f9fafb;border-bottom-color:#3b82f6;}.logs-count.svelte-qvn6bd {font-size:0.625rem;padding:0.0625rem 0.375rem;border-radius:9999px;background:#374151;color:#9ca3af;}.logs-controls.svelte-qvn6bd {display:flex;align-items:center;gap:0.25rem;padding:0 0.5rem;flex-shrink:0;}.logs-ctrl-btn.svelte-qvn6bd {display:flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;border-radius:0.25rem;border:none;background:transparent;color:#6b7280;cursor:pointer;transition:color 0.15s, background 0.15s;}.logs-ctrl-btn.svelte-qvn6bd:hover {color:#d1d5db;background:#374151;}.logs-ctrl-btn.active.svelte-qvn6bd {color:#93c5fd;background:#1e3a5f;}.logs-live.svelte-qvn6bd {display:flex;align-items:center;gap:0.375rem;font-family:system-ui, -apple-system, sans-serif;font-size:0.6875rem;color:#34d399;text-transform:uppercase;letter-spacing:0.05em;padding-right:0.5rem;}.logs-dot.svelte-qvn6bd {width:0.5rem;height:0.5rem;border-radius:9999px;background:#34d399;display:inline-block; animation: svelte-qvn6bd-pulse 2s ease-in-out infinite;} @keyframes svelte-qvn6bd-pulse { @@ -16,7 +16,7 @@ var gc=Object.defineProperty;var Gl=_e=>{throw TypeError(_e)};var mc=(_e,de,Me)= 50% { opacity: 0.4; } - }.logs-output.svelte-qvn6bd {max-height:60vh;overflow-y:auto;padding:0.25rem 0;}.logs-root.expanded.svelte-qvn6bd .logs-output:where(.svelte-qvn6bd) {max-height:85vh;}.logs-output.svelte-qvn6bd::-webkit-scrollbar {width:0.5rem;}.logs-output.svelte-qvn6bd::-webkit-scrollbar-track {background:#1f2937;}.logs-output.svelte-qvn6bd::-webkit-scrollbar-thumb {background:#4b5563;border-radius:0.25rem;}.logs-line.svelte-qvn6bd {display:flex;padding:0 1rem 0 0;gap:0;min-height:1.5rem;}.logs-line.svelte-qvn6bd:hover {background:rgba(255, 255, 255, 0.04);}.logs-line.stderr.svelte-qvn6bd {color:#fca5a5;background:rgba(239, 68, 68, 0.06);}.logs-line.stderr.svelte-qvn6bd:hover {background:rgba(239, 68, 68, 0.1);}.logs-line.status-line.svelte-qvn6bd {color:#93c5fd;font-weight:600;padding-top:0.375rem;padding-bottom:0.375rem;border-top:1px solid #1e3a5f;margin-top:0.25rem;}.logs-ts.svelte-qvn6bd {color:#4b5563;white-space:nowrap;user-select:none;flex-shrink:0;width:3.5rem;text-align:right;padding-right:1rem;padding-left:0.75rem;border-right:1px solid #1f2937;margin-right:0.75rem;}.logs-text.svelte-qvn6bd {white-space:pre-wrap;word-break:break-all;flex:1;min-width:0;padding-left:1rem;}.logs-line.svelte-qvn6bd .logs-ts:where(.svelte-qvn6bd) + .logs-text:where(.svelte-qvn6bd) {padding-left:0;}.logs-scroll-btn.svelte-qvn6bd {position:absolute;bottom:0.75rem;left:50%;transform:translateX(-50%);padding:0.25rem 0.75rem;font-size:0.6875rem;font-family:system-ui, -apple-system, sans-serif;color:#d1d5db;background:#374151;border:1px solid #4b5563;border-radius:9999px;cursor:pointer;opacity:0.9;transition:opacity 0.15s;}.logs-scroll-btn.svelte-qvn6bd:hover {opacity:1;background:#4b5563;}`};function nc(e,t){rs(t,!0),Qs(e,rc);let r=mr(t,"url",7,""),s=Ie(Or({})),o=Ie(null),l=Ie(!1),i=Ie(!1),a=Ie(!0),f=Ie(!0),c=Ie(!1),v=Ie(null),m=Vt(()=>Object.keys(n(s)).sort()),b=Vt(()=>n(o)&&n(s)[n(o)]?n(s)[n(o)]:[]);function S(){if(!r())return;const M=new EventSource(r());return U(l,!0),M.addEventListener("log",se=>{try{const J=JSON.parse(se.data),fe=J.destination||"unknown";n(s)[fe]||(n(s)[fe]=[],n(o)||U(o,fe,!0)),n(s)[fe]=[...n(s)[fe],{line:J.line,timestamp:J.timestamp,channel:J.channel||"stdout"}],n(a)&&requestAnimationFrame(()=>{n(v)&&(n(v).scrollTop=n(v).scrollHeight)})}catch(J){console.warn("[release-logs] bad log event:",J)}}),M.addEventListener("status",se=>{try{const J=JSON.parse(se.data),fe=J.destination||"unknown";n(s)[fe]||(n(s)[fe]=[],n(o)||U(o,fe,!0)),n(s)[fe]=[...n(s)[fe],{line:`── ${J.status} ──`,timestamp:"",channel:"status"}]}catch{}}),M.addEventListener("done",()=>{U(i,!0)}),M.addEventListener("error",()=>{U(l,!1),M.close()}),()=>{M.close(),U(l,!1)}}On(()=>{if(r())return S()});function $(){if(!n(v))return;const M=n(v).scrollHeight-n(v).scrollTop-n(v).clientHeight<40;U(a,M)}function B(){n(v)&&(n(v).scrollTop=n(v).scrollHeight,U(a,!0))}function x(M){if(!M)return null;const se=Number(M);if(Number.isFinite(se)&&se>1e12)return se;const J=new Date(M);return isNaN(J.getTime())?null:J.getTime()}function A(M,se){const J=x(M);if(J===null||se===null)return"";const fe=J-se;if(fe<0)return"0s";const Pe=Math.floor(fe/1e3);if(Pe<60)return`${Pe}s`;const qe=Math.floor(Pe/60),ot=Pe%60;return`${qe}m${String(ot).padStart(2,"0")}s`}let ae=Vt(()=>{const M={};for(const[se,J]of Object.entries(n(s)))for(const fe of J)if(fe.timestamp){M[se]=x(fe.timestamp);break}return M}),ee=Vt(()=>n(o)?n(ae)[n(o)]??null:null);function ne(M){const se=x(M);if(se===null)return"";const J=new Date(se),fe=String(J.getHours()).padStart(2,"0"),Pe=String(J.getMinutes()).padStart(2,"0"),qe=String(J.getSeconds()).padStart(2,"0"),ot=String(J.getMilliseconds()).padStart(3,"0");return`${fe}:${Pe}:${qe}.${ot}`}var Qe={get url(){return r()},set url(M=""){r(M),Ht()}},pe=tc();let K;var Ne=E(pe);{var Ke=M=>{var se=Gf(),J=E(se);{var fe=qe=>{var ot=Hf();dr(),w(qe,ot)},Pe=qe=>{var ot=sa("No logs available");w(qe,ot)};Q(J,qe=>{n(l)?qe(fe):qe(Pe,-1)})}y(se),w(M,se)},ht=M=>{var se=Vf();w(M,se)},Dt=M=>{var se=ec(),J=ft(se),fe=E(J);Ct(fe,21,()=>n(m),cs,(xe,Ee)=>{var Nt=Wf();let Kr;var Jr=E(Nt),$n=D(Jr),Xr=E($n,!0);y($n),y(Nt),j(()=>{var Zr;Kr=he(Nt,1,"logs-tab svelte-qvn6bd",null,Kr,{active:n(o)===n(Ee)}),V(Jr,`${n(Ee)??""} `),V(Xr,((Zr=n(s)[n(Ee)])==null?void 0:Zr.length)||0)}),Bn("click",Nt,()=>U(o,n(Ee),!0)),w(xe,Nt)}),y(fe);var Pe=D(fe,2),qe=E(Pe);{var ot=xe=>{var Ee=Yf();w(xe,Ee)};Q(qe,xe=>{n(l)&&!n(i)&&xe(ot)})}var Je=D(qe,2);let yr;var En=D(Je,2),eo=E(En);{var hs=xe=>{var Ee=Qf();w(xe,Ee)},Qr=xe=>{var Ee=Kf();w(xe,Ee)};Q(eo,xe=>{n(c)?xe(hs):xe(Qr,-1)})}y(En),y(Pe),y(J);var _t=D(J,2);Ct(_t,21,()=>n(b),cs,(xe,Ee)=>{var Nt=Xf();let Kr;var Jr=E(Nt);{var $n=Wn=>{var Cn=Jf(),ro=E(Cn,!0);y(Cn),j((no,so)=>{Hr(Cn,"title",no),V(ro,so)},[()=>ne(n(Ee).timestamp),()=>A(n(Ee).timestamp,n(ee))]),w(Wn,Cn)};Q(Jr,Wn=>{n(f)&&Wn($n)})}var Xr=D(Jr,2),Zr=E(Xr,!0);y(Xr),y(Nt),j(()=>{Kr=he(Nt,1,"logs-line svelte-qvn6bd",null,Kr,{stderr:n(Ee).channel==="stderr","status-line":n(Ee).channel==="status"}),V(Zr,n(Ee).line)}),w(xe,Nt)}),y(_t),Tl(_t,xe=>U(v,xe),()=>n(v));var to=D(_t,2);{var _s=xe=>{var Ee=Zf();Bn("click",Ee,B),w(xe,Ee)};Q(to,xe=>{n(a)||xe(_s)})}j(()=>{yr=he(Je,1,"logs-ctrl-btn svelte-qvn6bd",null,yr,{active:n(f)}),Hr(En,"title",n(c)?"Collapse":"Expand")}),Bn("click",Je,()=>U(f,!n(f))),Bn("click",En,()=>U(c,!n(c))),_r("scroll",_t,$),w(M,se)};Q(Ne,M=>{n(m).length===0&&!n(i)?M(Ke):n(m).length===0&&n(i)?M(ht,1):M(Dt,-1)})}return y(pe),j(()=>K=he(pe,1,"logs-root svelte-qvn6bd",null,K,{expanded:n(c)})),w(e,pe),ns(Qe)}bl(["click"]),customElements.define("release-logs",Ks(nc,{url:{}},[],[],{mode:"open"}));var sc=C('
'),oc=C('
');const lc={hash:"svelte-47dto6",code:`.spec-root.svelte-47dto6 {border:1px solid #e5e7eb;border-radius:0.5rem;overflow:hidden;font-family:system-ui, -apple-system, sans-serif;}.spec-root.expanded.svelte-47dto6 {max-height:36rem;overflow-y:auto;}.spec-header.svelte-47dto6 {display:flex;align-items:center;justify-content:space-between;width:100%;padding:0.5rem 0.75rem;background:#f9fafb;border:none;border-bottom:1px solid transparent;cursor:pointer;transition:background 0.15s;}.spec-root.expanded.svelte-47dto6 .spec-header:where(.svelte-47dto6) {position:sticky;top:0;z-index:1;border-bottom-color:#e5e7eb;}.spec-header.svelte-47dto6:hover {background:#f3f4f6;}.spec-header-left.svelte-47dto6 {display:flex;align-items:center;gap:0.375rem;}.spec-chevron.svelte-47dto6 {color:#6b7280;transition:transform 0.15s ease;flex-shrink:0;}.spec-chevron.rotated.svelte-47dto6 {transform:rotate(90deg);}.spec-filename.svelte-47dto6 {font-family:ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;font-size:0.8125rem;font-weight:500;color:#374151;}.spec-meta.svelte-47dto6 {font-size:0.75rem;color:#9ca3af;}.spec-code.svelte-47dto6 {background:#111827;}.spec-root.expanded.svelte-47dto6::-webkit-scrollbar {width:0.5rem;height:0.5rem;}.spec-root.expanded.svelte-47dto6::-webkit-scrollbar-track {background:#1f2937;}.spec-root.expanded.svelte-47dto6::-webkit-scrollbar-thumb {background:#4b5563;border-radius:0.25rem;}.spec-code.svelte-47dto6 pre:where(.svelte-47dto6) {margin:0;padding:1rem;font-family:ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;font-size:0.8125rem;line-height:1.625;color:#e5e7eb;white-space:pre;tab-size:4;overflow-x:auto;}.spec-code.svelte-47dto6 code:where(.svelte-47dto6) {color:inherit;} + }.logs-output.svelte-qvn6bd {max-height:60vh;overflow-y:auto;padding:0.25rem 0;}.logs-root.expanded.svelte-qvn6bd .logs-output:where(.svelte-qvn6bd) {max-height:85vh;}.logs-output.svelte-qvn6bd::-webkit-scrollbar {width:0.5rem;}.logs-output.svelte-qvn6bd::-webkit-scrollbar-track {background:#1f2937;}.logs-output.svelte-qvn6bd::-webkit-scrollbar-thumb {background:#4b5563;border-radius:0.25rem;}.logs-line.svelte-qvn6bd {display:flex;padding:0 1rem 0 0;gap:0;min-height:1.5rem;}.logs-line.svelte-qvn6bd:hover {background:rgba(255, 255, 255, 0.04);}.logs-line.stderr.svelte-qvn6bd {color:#fca5a5;background:rgba(239, 68, 68, 0.06);}.logs-line.stderr.svelte-qvn6bd:hover {background:rgba(239, 68, 68, 0.1);}.logs-line.status-line.svelte-qvn6bd {color:#93c5fd;font-weight:600;padding-top:0.375rem;padding-bottom:0.375rem;border-top:1px solid #1e3a5f;margin-top:0.25rem;}.logs-ts.svelte-qvn6bd {color:#4b5563;white-space:nowrap;user-select:none;flex-shrink:0;width:3.5rem;text-align:right;padding-right:1rem;padding-left:0.75rem;border-right:1px solid #1f2937;margin-right:0.75rem;}.logs-text.svelte-qvn6bd {white-space:pre-wrap;word-break:break-all;flex:1;min-width:0;padding-left:1rem;}.logs-line.svelte-qvn6bd .logs-ts:where(.svelte-qvn6bd) + .logs-text:where(.svelte-qvn6bd) {padding-left:0;}.logs-scroll-btn.svelte-qvn6bd {position:absolute;bottom:0.75rem;left:50%;transform:translateX(-50%);padding:0.25rem 0.75rem;font-size:0.6875rem;font-family:system-ui, -apple-system, sans-serif;color:#d1d5db;background:#374151;border:1px solid #4b5563;border-radius:9999px;cursor:pointer;opacity:0.9;transition:opacity 0.15s;}.logs-scroll-btn.svelte-qvn6bd:hover {opacity:1;background:#4b5563;}`};function Ec(e,t){us(t,!0),oo(e,yc);let n=Er(t,"url",7,""),s=Ue(Wr({})),o=Ue(null),a=Ue(!1),l=Ue(!1),i=Ue(!0),f=Ue(!0),u=Ue(!1),v=Ue(null),x=qt(()=>Object.keys(r(s)).sort()),y=qt(()=>r(o)&&r(s)[r(o)]?r(s)[r(o)]:[]);function M(){if(!n())return;const R=new EventSource(n());return I(a,!0),R.addEventListener("log",J=>{try{const X=JSON.parse(J.data),de=X.destination||"unknown";r(s)[de]||(r(s)[de]=[],r(o)||I(o,de,!0)),r(s)[de]=[...r(s)[de],{line:X.line,timestamp:X.timestamp,channel:X.channel||"stdout"}],r(i)&&requestAnimationFrame(()=>{r(v)&&(r(v).scrollTop=r(v).scrollHeight)})}catch(X){console.warn("[release-logs] bad log event:",X)}}),R.addEventListener("status",J=>{try{const X=JSON.parse(J.data),de=X.destination||"unknown";r(s)[de]||(r(s)[de]=[],r(o)||I(o,de,!0)),r(s)[de]=[...r(s)[de],{line:`── ${X.status} ──`,timestamp:"",channel:"status"}]}catch{}}),R.addEventListener("done",()=>{I(l,!0)}),R.addEventListener("error",()=>{I(a,!1),R.close()}),()=>{R.close(),I(a,!1)}}Vn(()=>{if(n())return M()});function N(){if(!r(v))return;const R=r(v).scrollHeight-r(v).scrollTop-r(v).clientHeight<40;I(i,R)}function H(){r(v)&&(r(v).scrollTop=r(v).scrollHeight,I(i,!0))}function k(R){if(!R)return null;const J=Number(R);if(Number.isFinite(J)&&J>1e12)return J;const X=new Date(R);return isNaN(X.getTime())?null:X.getTime()}function L(R,J){const X=k(R);if(X===null||J===null)return"";const de=X-J;if(de<0)return"0s";const Me=Math.floor(de/1e3);if(Me<60)return`${Me}s`;const Se=Math.floor(Me/60),ot=Me%60;return`${Se}m${String(ot).padStart(2,"0")}s`}let ie=qt(()=>{const R={};for(const[J,X]of Object.entries(r(s)))for(const de of X)if(de.timestamp){R[J]=k(de.timestamp);break}return R}),oe=qt(()=>r(o)?r(ie)[r(o)]??null:null);function ae(R){const J=k(R);if(J===null)return"";const X=new Date(J),de=String(X.getHours()).padStart(2,"0"),Me=String(X.getMinutes()).padStart(2,"0"),Se=String(X.getSeconds()).padStart(2,"0"),ot=String(X.getMilliseconds()).padStart(3,"0");return`${de}:${Me}:${Se}.${ot}`}var nt={get url(){return n()},set url(R=""){n(R),Kt()}},me=kc();let q;var he=E(me);{var st=R=>{var J=dc(),X=E(J);{var de=Se=>{var ot=uc();lr(),m(Se,ot)},Me=Se=>{var ot=mi("No logs available");m(Se,ot)};Y(X,Se=>{r(a)?Se(de):Se(Me,-1)})}w(J),m(R,J)},wt=R=>{var J=vc();m(R,J)},Mt=R=>{var J=wc(),X=Fe(J),de=E(X);mt(de,21,()=>r(x),xs,(xe,ge)=>{var Rt=pc();let Nr;var Dr=E(Rt),Ln=A(Dr),Pn=E(Ln,!0);w(Ln),w(Rt),O(()=>{var On;Nr=pe(Rt,1,"logs-tab svelte-qvn6bd",null,Nr,{active:r(o)===r(ge)}),B(Dr,`${r(ge)??""} `),B(Pn,((On=r(s)[r(ge)])==null?void 0:On.length)||0)}),Qn("click",Rt,()=>I(o,r(ge),!0)),m(xe,Rt)}),w(de);var Me=A(de,2),Se=E(Me);{var ot=xe=>{var ge=hc();m(xe,ge)};Y(Se,xe=>{r(a)&&!r(l)&&xe(ot)})}var Ye=A(Se,2);let Sr;var Rn=A(Ye,2),co=E(Rn);{var uo=xe=>{var ge=_c();m(xe,ge)},Es=xe=>{var ge=mc();m(xe,ge)};Y(co,xe=>{r(u)?xe(uo):xe(Es,-1)})}w(Rn),w(Me),w(X);var on=A(X,2);mt(on,21,()=>r(y),xs,(xe,ge)=>{var Rt=xc();let Nr;var Dr=E(Rt);{var Ln=ts=>{var an=gc(),po=E(an,!0);w(an),O((ho,Cs)=>{en(an,"title",ho),B(po,Cs)},[()=>ae(r(ge).timestamp),()=>L(r(ge).timestamp,r(oe))]),m(ts,an)};Y(Dr,ts=>{r(f)&&ts(Ln)})}var Pn=A(Dr,2),On=E(Pn,!0);w(Pn),w(Rt),O(()=>{Nr=pe(Rt,1,"logs-line svelte-qvn6bd",null,Nr,{stderr:r(ge).channel==="stderr","status-line":r(ge).channel==="status"}),B(On,r(ge).line)}),m(xe,Rt)}),w(on),qa(on,xe=>I(v,xe),()=>r(v));var vo=A(on,2);{var $s=xe=>{var ge=bc();Qn("click",ge,H),m(xe,ge)};Y(vo,xe=>{r(i)||xe($s)})}O(()=>{Sr=pe(Ye,1,"logs-ctrl-btn svelte-qvn6bd",null,Sr,{active:r(f)}),en(Rn,"title",r(u)?"Collapse":"Expand")}),Qn("click",Ye,()=>I(f,!r(f))),Qn("click",Rn,()=>I(u,!r(u))),Tt("scroll",on,N),m(R,J)};Y(he,R=>{r(x).length===0&&!r(l)?R(st):r(x).length===0&&r(l)?R(wt,1):R(Mt,-1)})}return w(me),O(()=>q=pe(me,1,"logs-root svelte-qvn6bd",null,q,{expanded:r(u)})),m(e,me),ds(nt)}Na(["click"]),customElements.define("release-logs",ao(Ec,{url:{}},[],[],{mode:"open"}));var $c=D('
'),Cc=D('
');const Ac={hash:"svelte-47dto6",code:`.spec-root.svelte-47dto6 {border:1px solid #e5e7eb;border-radius:0.5rem;overflow:hidden;font-family:system-ui, -apple-system, sans-serif;}.spec-root.expanded.svelte-47dto6 {max-height:36rem;overflow-y:auto;}.spec-header.svelte-47dto6 {display:flex;align-items:center;justify-content:space-between;width:100%;padding:0.5rem 0.75rem;background:#f9fafb;border:none;border-bottom:1px solid transparent;cursor:pointer;transition:background 0.15s;}.spec-root.expanded.svelte-47dto6 .spec-header:where(.svelte-47dto6) {position:sticky;top:0;z-index:1;border-bottom-color:#e5e7eb;}.spec-header.svelte-47dto6:hover {background:#f3f4f6;}.spec-header-left.svelte-47dto6 {display:flex;align-items:center;gap:0.375rem;}.spec-chevron.svelte-47dto6 {color:#6b7280;transition:transform 0.15s ease;flex-shrink:0;}.spec-chevron.rotated.svelte-47dto6 {transform:rotate(90deg);}.spec-filename.svelte-47dto6 {font-family:ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;font-size:0.8125rem;font-weight:500;color:#374151;}.spec-meta.svelte-47dto6 {font-size:0.75rem;color:#9ca3af;}.spec-code.svelte-47dto6 {background:#111827;}.spec-root.expanded.svelte-47dto6::-webkit-scrollbar {width:0.5rem;height:0.5rem;}.spec-root.expanded.svelte-47dto6::-webkit-scrollbar-track {background:#1f2937;}.spec-root.expanded.svelte-47dto6::-webkit-scrollbar-thumb {background:#4b5563;border-radius:0.25rem;}.spec-code.svelte-47dto6 pre:where(.svelte-47dto6) {margin:0;padding:1rem;font-family:ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;font-size:0.8125rem;line-height:1.625;color:#e5e7eb;white-space:pre;tab-size:4;overflow-x:auto;}.spec-code.svelte-47dto6 code:where(.svelte-47dto6) {color:inherit;} - /* Syntax highlighting tokens */.spec-code.svelte-47dto6 .hl-comment {color:#6b7280;font-style:italic;}.spec-code.svelte-47dto6 .hl-string {color:#a5d6ff;}.spec-code.svelte-47dto6 .hl-keyword {color:#ff7b72;}.spec-code.svelte-47dto6 .hl-number {color:#79c0ff;}`};function ic(e,t){rs(t,!0),Qs(e,lc);let r=mr(t,"content",7,""),s=mr(t,"filename",7,"forest.cue"),o=Ie(!1),l=Ie("");function i(pe){let K=pe.replace(/&/g,"&").replace(//g,">");return K=K.replace(/(\/\/.*)/g,'$1').replace(/"(?:[^"\\]|\\.)*"/g,'$&').replace(/\b(package|import|let|if|for|in|true|false|null|enabled|path)\b/g,'$1').replace(/\b(\d+)\b/g,'$1'),K}On(()=>{n(o)&&r()&&!n(l)&&U(l,i(r()),!0)});function a(){U(o,!n(o))}let f=Vt(()=>r()?r().split(` -`).length:0);var c={get content(){return r()},set content(pe=""){r(pe),Ht()},get filename(){return s()},set filename(pe="forest.cue"){s(pe),Ht()}},v=oc();let m;var b=E(v),S=E(b),$=E(S);let B;var x=D($,2),A=E(x,!0);y(x),y(S);var ae=D(S,2),ee=E(ae);y(ae),y(b);var ne=D(b,2);{var Qe=pe=>{var K=sc(),Ne=E(K),Ke=E(Ne),ht=E(Ke);ha(ht,()=>n(l)),y(Ke),y(Ne),y(K),w(pe,K)};Q(ne,pe=>{n(o)&&pe(Qe)})}return y(v),j(()=>{m=he(v,1,"spec-root svelte-47dto6",null,m,{expanded:n(o)}),B=he($,0,"spec-chevron svelte-47dto6",null,B,{rotated:n(o)}),V(A,s()),V(ee,`${n(f)??""} lines`)}),Bn("click",b,a),w(e,v),ns(c)}bl(["click"]),customElements.define("spec-viewer",Ks(ic,{content:{},filename:{}},[],[],{mode:"open"}))})(); + /* Syntax highlighting tokens */.spec-code.svelte-47dto6 .hl-comment {color:#6b7280;font-style:italic;}.spec-code.svelte-47dto6 .hl-string {color:#a5d6ff;}.spec-code.svelte-47dto6 .hl-keyword {color:#ff7b72;}.spec-code.svelte-47dto6 .hl-number {color:#79c0ff;}`};function Sc(e,t){us(t,!0),oo(e,Ac);let n=Er(t,"content",7,""),s=Er(t,"filename",7,"forest.cue"),o=Ue(!1),a=Ue("");function l(me){let q=me.replace(/&/g,"&").replace(//g,">");return q=q.replace(/(\/\/.*)/g,'$1').replace(/"(?:[^"\\]|\\.)*"/g,'$&').replace(/\b(package|import|let|if|for|in|true|false|null|enabled|path)\b/g,'$1').replace(/\b(\d+)\b/g,'$1'),q}Vn(()=>{r(o)&&n()&&!r(a)&&I(a,l(n()),!0)});function i(){I(o,!r(o))}let f=qt(()=>n()?n().split(` +`).length:0);var u={get content(){return n()},set content(me=""){n(me),Kt()},get filename(){return s()},set filename(me="forest.cue"){s(me),Kt()}},v=Cc();let x;var y=E(v),M=E(y),N=E(M);let H;var k=A(N,2),L=E(k,!0);w(k),w(M);var ie=A(M,2),oe=E(ie);w(ie),w(y);var ae=A(y,2);{var nt=me=>{var q=$c(),he=E(q),st=E(he),wt=E(st);Si(wt,()=>r(a)),w(st),w(he),w(q),m(me,q)};Y(ae,me=>{r(o)&&me(nt)})}return w(v),O(()=>{x=pe(v,1,"spec-root svelte-47dto6",null,x,{expanded:r(o)}),H=pe(N,0,"spec-chevron svelte-47dto6",null,H,{rotated:r(o)}),B(L,s()),B(oe,`${r(f)??""} lines`)}),Qn("click",y,i),m(e,v),ds(u)}Na(["click"]),customElements.define("spec-viewer",ao(Sc,{content:{},filename:{}},[],[],{mode:"open"}))})(); diff --git a/static/js/pipeline-builder.js b/static/js/pipeline-builder.js index 8505427..45bbc7e 100644 --- a/static/js/pipeline-builder.js +++ b/static/js/pipeline-builder.js @@ -42,6 +42,7 @@ class PipelineBuilder extends HTMLElement { if (!config) return "deploy"; if (config.Deploy !== undefined) return "deploy"; if (config.Wait !== undefined) return "wait"; + if (config.Plan !== undefined) return "plan"; return "deploy"; } @@ -50,6 +51,7 @@ class PipelineBuilder extends HTMLElement { if (!config) return ""; if (config.Deploy) return config.Deploy.environment || ""; if (config.Wait) return config.Wait.duration_seconds ? `${config.Wait.duration_seconds}s` : ""; + if (config.Plan) return config.Plan.environment || ""; return ""; } @@ -367,7 +369,7 @@ class PipelineBuilder extends HTMLElement { // Type select (deploy / wait) const typeSelect = el("select", "border border-gray-200 rounded px-2 py-1 text-xs bg-white shrink-0"); - for (const t of ["deploy", "wait"]) { + for (const t of ["deploy", "wait", "plan"]) { const opt = document.createElement("option"); opt.value = t; opt.textContent = t; @@ -379,6 +381,8 @@ class PipelineBuilder extends HTMLElement { clearTimeout(this._blurTimer); if (typeSelect.value === "wait") { this.stages[index].config = { Wait: { duration_seconds: 0 } }; + } else if (typeSelect.value === "plan") { + this.stages[index].config = { Plan: { environment: "", auto_approve: false } }; } else { this.stages[index].config = { Deploy: { environment: "" } }; } @@ -440,6 +444,33 @@ class PipelineBuilder extends HTMLElement { }; const secLabel = el("span", "text-xs text-gray-400", "seconds"); configRow.append(durLabel, durInput, secLabel); + } else if (type === "plan") { + const envLabel = el("span", "text-xs text-gray-500 shrink-0", "env:"); + const envInput = el("input", "border border-gray-200 rounded px-2 py-1 text-xs w-32 focus:outline-none focus:ring-1 focus:ring-gray-400"); + envInput.type = "text"; + envInput.value = (stage.config.Plan && stage.config.Plan.environment) || ""; + envInput.placeholder = "environment"; + envInput.onmousedown = (e) => e.stopPropagation(); + envInput.oninput = () => { + if (!this.stages[index].config.Plan) this.stages[index].config = { Plan: { environment: "", auto_approve: false } }; + this.stages[index].config.Plan.environment = envInput.value.trim(); + this._sync(); + }; + envInput.onblur = () => { + this._blurTimer = setTimeout(() => this._render(), 150); + }; + const autoLabel = el("label", "text-xs text-gray-500 flex items-center gap-1 ml-2 shrink-0"); + const autoCheck = el("input", ""); + autoCheck.type = "checkbox"; + autoCheck.checked = !!(stage.config.Plan && stage.config.Plan.auto_approve); + autoCheck.onmousedown = (e) => e.stopPropagation(); + autoCheck.onchange = () => { + if (!this.stages[index].config.Plan) this.stages[index].config = { Plan: { environment: "", auto_approve: false } }; + this.stages[index].config.Plan.auto_approve = autoCheck.checked; + this._sync(); + }; + autoLabel.append(autoCheck, document.createTextNode("auto-approve")); + configRow.append(envLabel, envInput, autoLabel); } card.append(configRow); @@ -568,6 +599,7 @@ class PipelineBuilder extends HTMLElement { const TYPE_COLORS = { deploy: { bg: "#dbeafe", border: "#93c5fd", text: "#1e40af" }, wait: { bg: "#fef3c7", border: "#fcd34d", text: "#92400e" }, + plan: { bg: "#ede9fe", border: "#c4b5fd", text: "#5b21b6" }, }; for (const s of named) { diff --git a/tasks/approval-gate.md b/tasks/approval-gate.md index a9710a5..1ec1fb5 100644 --- a/tasks/approval-gate.md +++ b/tasks/approval-gate.md @@ -169,3 +169,83 @@ CREATE TABLE approval_decisions ( 2. Run `buf generate` in forest to regenerate gRPC interface stubs 3. Run forest tests 4. E2E test: create approval policy, trigger release, verify UI shows approval buttons + +--- + +## Plan Stage Support (Prepare-Before-Deploy) + +### Overview + +Added support for "plan" pipeline stages — destinations that run a prepare/dry-run (e.g. terraform plan) and require approval of the output before the actual deploy proceeds. Forest already had full infrastructure for this; this work surfaces it in the Forage UI. + +### Changes + +#### forage-core (`crates/forage-core/src/platform/mod.rs`) +- Added `PipelineStageConfig::Plan { environment, auto_approve }` variant +- Added `approval_status: Option` and `auto_approve: Option` to `PipelineRunStageState` +- Added 3 new `ForestPlatform` trait methods: `approve_plan_stage`, `reject_plan_stage`, `get_plan_output` +- Added `PlanOutput` struct (`plan_output: String`, `status: String`) + +#### forage-server gRPC client (`forest_client.rs`) +- `convert_pipeline_stage`: handles `Plan` config variant (was previously mapped to empty Deploy) +- `convert_pipeline_stage_state`: recognizes `Plan` stage type + `AwaitingApproval` status + new fields +- `convert_stages_to_grpc`: handles `PipelineStageConfig::Plan` → `PlanStageConfig` +- Implemented `approve_plan_stage`, `reject_plan_stage`, `get_plan_output` calling forest's RPCs + +#### forage-server routes (`routes/platform.rs`) +- Added 3 API routes: + - `POST /api/orgs/{org}/projects/{project}/plan-stages/{stage_id}/approve` + - `POST /api/orgs/{org}/projects/{project}/plan-stages/{stage_id}/reject` + - `GET /api/orgs/{org}/projects/{project}/plan-stages/{stage_id}/output` +- `ApiPipelineStage` now includes `approval_status` and `auto_approve` +- `build_timeline_json`: plan stages with `AWAITING_APPROVAL` status are shown with that status; releases with plan stages awaiting approval are treated as `needs_action` (not hidden) + +#### Pipeline builder (`static/js/pipeline-builder.js`) +- Added "plan" as third stage type in dropdown +- Plan stage config: environment + auto-approve checkbox +- Purple color scheme for plan nodes in DAG visualization + +#### Svelte timeline (`frontend/src/ReleaseTimeline.svelte`) +- `approvePlanStage(release, stage, reject)` function for approve/reject via API +- `viewPlanOutput(release, stage)` function for on-demand plan output fetching (toggle) +- Plan stages render with purple shield icon when `AWAITING_APPROVAL` +- "Approve plan" / "Reject" buttons on plan stages awaiting approval +- "View plan" / "Hide plan" button to toggle plan output display +- Plan output shown in collapsible `
` block (monospace, max-height 256px with scroll)
+- Summary line shows plan stage badge + approve button when plan awaiting approval
+
+#### Status helpers (`frontend/src/lib/status.js`)
+- Added `planStageLabel(status)` function
+- `pipelineSummary`: detects `AWAITING_APPROVAL` plan stages → "Awaiting plan approval" (purple)
+
+#### Slack notifications (`forage-core/src/integrations/router.rs`)
+- Plan stage rendering in Slack blocks: "Planning", "Awaiting plan approval", "Plan approved", "Plan failed"
+- Shield emoji for AWAITING_APPROVAL status
+
+#### Test support (`test_support.rs`)
+- Added default mock implementations for the 3 new trait methods
+
+### Forest Runner Infrastructure
+
+#### Proto (`runner.proto`)
+- Added `ReleaseMode` enum: `RELEASE_MODE_UNSPECIFIED`, `RELEASE_MODE_DEPLOY`, `RELEASE_MODE_PLAN`
+- Added `mode` field (type `ReleaseMode`) to `WorkAssignment` — tells remote runners whether to deploy or plan
+- Added `plan_output` field (optional string) to `CompleteReleaseRequest` — runners send plan output back
+
+#### Scheduler (`scheduler.rs`)
+- Reads `release_state.mode` and maps to `ReleaseMode::Plan` / `ReleaseMode::Deploy`
+- Includes `mode` in `WorkAssignment` when dispatching to remote runners
+
+#### Runner gRPC handler (`grpc/runner.rs`)
+- `complete_release`: stores `plan_output` from `CompleteReleaseRequest` to `release_states.plan_output` in DB
+
+#### Terraform destination (`destinations/terraformv1.rs`)
+- `plan()`: now captures actual terraform plan stdout (not just a marker)
+- Added `run_capture()` method — same as `run()` but captures stdout into a String
+- Added `run_command_capture()` — like `run_command()` but returns captured stdout while still logging
+
+#### Runner crate (`forest-runner`)
+- `RunnerDestination` trait: added `plan()` method (default returns None)
+- `Executor`: checks `ReleaseMode` from `WorkAssignment`, calls `plan()` instead of `release()` for plan mode
+- `RunnerSession::complete_release`: accepts optional `plan_output` parameter
+- `run_destination_plan()` function: prepare + plan, returns `Option`
diff --git a/templates/pages/artifact_detail.html.jinja b/templates/pages/artifact_detail.html.jinja
index 00cd8d6..55da50b 100644
--- a/templates/pages/artifact_detail.html.jinja
+++ b/templates/pages/artifact_detail.html.jinja
@@ -79,6 +79,49 @@
     
     {% endif %}
 
+    {# ── Deploy action ─────────────────────────────────────────── #}
+    {% if is_admin %}
+    
+
+ + + Deploy this release + + +
+
+ + + + {% if has_active_pipeline %} +
+ + +
+ {% endif %} + +
+ + +

Leave empty when using a pipeline — it will deploy to all configured stages.

+
+ + +
+
+
+
+ {% endif %} + {# ── Pipeline stages ───────────────────────────────────────── #} {% if has_pipeline and pipeline_stages | length > 0 %}
@@ -95,6 +138,8 @@ {% elif stage.status == "FAILED" %} + {% elif stage.status == "AWAITING_APPROVAL" or (stage.stage_type == "plan" and (stage.approval_status == "AWAITINGAPPROVAL" or stage.approval_status == "AWAITING_APPROVAL")) %} + {% else %} {% endif %} @@ -112,6 +157,30 @@ {% if stage.status == "SUCCEEDED" %}Waited{% elif stage.status == "RUNNING" %}Waiting{% elif stage.status == "FAILED" %}Wait failed{% elif stage.status == "CANCELLED" %}Wait cancelled{% else %}Wait{% endif %} {% if stage.duration_seconds %}{{ stage.duration_seconds }}s{% endif %} + {% elif stage.stage_type == "plan" %} + {% set plan_awaiting = stage.approval_status == "AWAITINGAPPROVAL" or stage.approval_status == "AWAITING_APPROVAL" or stage.status == "AWAITING_APPROVAL" %} + + {% if stage.status == "SUCCEEDED" %}Plan approved{% elif plan_awaiting %}Awaiting plan approval{% elif stage.status == "RUNNING" %}Planning{% elif stage.status == "FAILED" %}Plan failed{% elif stage.status == "CANCELLED" %}Plan cancelled{% else %}Plan{% endif %} + + + {{ stage.environment }} + + {% if plan_awaiting and release_intent_id %} +
+
+ + + + +
+
+ + + + +
+
+ {% endif %} {% endif %} {# Elapsed time #} @@ -146,17 +215,39 @@ {# ── Policy evaluations (approval, soak, branch) ──────────── #} {% if policy_evaluations | length > 0 %} + {% set pns = namespace(passed=0, total=0, pending=0) %} + {% for eval in policy_evaluations %} + {% set pns.total = pns.total + 1 %} + {% if eval.passed %} + {% set pns.passed = pns.passed + 1 %} + {% else %} + {% set pns.pending = pns.pending + 1 %} + {% endif %} + {% endfor %}
-

Policy Requirements

-
+
+

Policy Requirements

+ {% if pns.passed == pns.total %} + + + {{ pns.passed }}/{{ pns.total }} passed + + {% else %} + + + {{ pns.passed }}/{{ pns.total }} passed + + {% endif %} +
+ + {# ── Pending / failed policies (expanded) ──────────────── #} + {% if pns.pending > 0 %} +
{% for eval in policy_evaluations %} + {% if not eval.passed %}
- {% if eval.passed %} - - {% else %} - {% endif %} {% if eval.policy_type == "approval" %} Approval @@ -196,42 +287,73 @@
{% endif %} - {% if not eval.passed %} - {% if is_release_author and not is_admin %} -

You cannot approve your own release.

- {% else %} -
- {% if not is_release_author %} -
- - - - -
- {% endif %} - {% if is_release_author and is_admin %} -
- - - - - -
- {% endif %} -
- - - - -
-
+ {% if is_release_author and not is_admin %} +

You cannot approve your own release.

+ {% else %} +
+ {% if not is_release_author %} +
+ + + + +
{% endif %} + {% if is_admin %} +
+ + + + + +
+ {% endif %} +
+ + + + +
+
{% endif %}
{% endif %}
+ {% endif %} {% endfor %}
+ {% endif %} + + {# ── Passed policies (collapsed) ───────────────────────── #} + {% if pns.passed > 0 %} +
+ + + + {{ pns.passed }} passed polic{{ "y" if pns.passed == 1 else "ies" }} + +
+ {% for eval in policy_evaluations %} + {% if eval.passed %} +
+ + + {% if eval.policy_type == "approval" %} + Approval + {% elif eval.policy_type == "soak_time" %} + Soak Time + {% elif eval.policy_type == "branch_restriction" %} + Branch + {% endif %} + + {{ eval.policy_name }} + {{ eval.reason }} +
+ {% endif %} + {% endfor %} +
+
+ {% endif %}
{% endif %}