@jfvilas/plugin-kwirth-metrics 0.12.5 → 0.12.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,7 +7,7 @@ This very first version of KwirthMetrics is compatible with Kwirth core server v
7
7
 
8
8
  | Plugin Kwirth version | Kwirth version |
9
9
  |-|-|
10
- |0.0.1|0.4.20|
10
+ |0.12.5|0.4.20|
11
11
 
12
12
 
13
13
 
@@ -63,7 +63,7 @@ If everyting is correctly configured and tagged, the user should see a list of c
63
63
 
64
64
  ```bash
65
65
  # From your Backstage root directory
66
- yarn --cwd packages/app add @jfvilas/plugin-kwirth-metrics @jfvilas/plugin-kwirth-common
66
+ yarn --cwd packages/app add @jfvilas/plugin-kwirth-metrics @jfvilas/plugin-kwirth-common @jfvilas/kwirth-common
67
67
  ```
68
68
 
69
69
  3. Make sure the [Kwirth backend plugin](https://www.npmjs.com/package/@jfvilas/plugin-kwirth-backend#configure) is installed and configured.
@@ -77,7 +77,7 @@ If everyting is correctly configured and tagged, the user should see a list of c
77
77
  Firstly, import the plugin module.
78
78
  ```typescript
79
79
  // In packages/app/src/components/catalog/EntityPage.tsx
80
- import { EntityKwirthMetricsContent, isKwirthAvailable } from '@jfvilas/plugin-kwirth-common';
80
+ import { EntityKwirthMetricsContent, isKwirthAvailable } from '@jfvilas/plugin-kwirth-metrics';
81
81
  ```
82
82
 
83
83
  Then, add a tab to your EntityPage (the 'if' is optional, you can keep the 'KwirthMetrics' tab always visible if you prefer to do it that way).
@@ -87,7 +87,7 @@ If everyting is correctly configured and tagged, the user should see a list of c
87
87
  <EntityLayout>
88
88
  {/* other tabs... */}
89
89
  <EntityLayout.Route if={isKwirthAvailable} path="/kwirthmetrics" title="KwirthMetrics">
90
- <EntityKwirthMetricsContent />
90
+ <EntityKwirthMetricsContent allMetrics={true} enableRestart={false} />
91
91
  </EntityLayout.Route>
92
92
  </EntityLayout>
93
93
  )
@@ -141,7 +141,7 @@ When you access the tab, if you have not yet tagged your entities you would see
141
141
 
142
142
  Once you tag your entities and your Kubernetes objects, you should see something similar to this:
143
143
 
144
- ![kwirthmetrics-available](https://raw.githubusercontent.com/jfvilas/plugin-kwirth-metrics/blob/master/images/kwirthmetrics-available.png)
144
+ ![kwirthmetrics-available](https://raw.githubusercontent.com/jfvilas/plugin-kwirth-metrics/master/images/kwirthmetrics-available.png)
145
145
 
146
146
  KwirthMetrics is ready to show your favourite charts!!
147
147
 
@@ -163,13 +163,13 @@ The icons will light up in its corresponding color when a new event takes place.
163
163
 
164
164
  This is how it feels:
165
165
 
166
- ![status info](https://raw.githubusercontent.com/jfvilas/plugin-kwirth-metrics/master/images/status-info.png)
166
+ ![status info](https://raw.githubusercontent.com/jfvilas/plugin-kwirth-metrics/master/images/kwirthmetrics-status.png)
167
167
 
168
168
 
169
169
  ## Restarting pods
170
170
  If your Backstage administrator has configured **Restarting** permissions and you are permitted, you would see a "Restart Pod" button just on the left of the "Play" button.
171
171
 
172
- ![status info](https://raw.githubusercontent.com/jfvilas/plugin-kwirth-metrics/master/images/restart-pod.png)
172
+ ![restart-pod](https://raw.githubusercontent.com/jfvilas/plugin-kwirth-metrics/master/images/kwirthmetrics-restart-pod.png)
173
173
 
174
174
  When you are not allowed to restart a pod, you can see the icon but you cannot click it. Conversely, if you are allowed, you can click the button and the pod (in the *namespace you have selected*) will be restarted.
175
175
 
@@ -271,5 +271,5 @@ Please check the examples below to understand how each one of these will behave:
271
271
  **Merge**
272
272
  ![kwirthmetrics-merge](https://raw.githubusercontent.com/jfvilas/plugin-kwirth-metrics/master/images/kwirthmetrics-merge.png)
273
273
 
274
- **MErge and Stack**
274
+ **Merge and Stack**
275
275
  ![kwirthmetrics-merge-stack](https://raw.githubusercontent.com/jfvilas/plugin-kwirth-metrics/master/images/kwirthmetrics-merge-stack.png)
@@ -1,4 +1,4 @@
1
- import { getVersion, requestAccess } from '@jfvilas/plugin-kwirth-common';
1
+ import { getVersion, getResources, requestAccess } from '@jfvilas/plugin-kwirth-common';
2
2
 
3
3
  class KwirthMetricsClient {
4
4
  discoveryApi;
@@ -27,20 +27,24 @@ class KwirthMetricsClient {
27
27
  // throw new Error(`getVersion error: ${err}`)
28
28
  // }
29
29
  // }
30
+ // async getResources(entity:Entity): Promise<ClusterValidPods> {
31
+ // try {
32
+ // const baseUrl = await this.discoveryApi.getBaseUrl('kwirth')
33
+ // const targetUrl = `${baseUrl}/start`
34
+ // var payload=JSON.stringify(entity)
35
+ // const result = await this.fetchApi.fetch(targetUrl, {method:'POST', body:payload, headers:{'Content-Type':'application/json'}})
36
+ // const data = await result.json() as ClusterValidPods
37
+ // if (!result.ok) {
38
+ // throw new Error(`getResources error: not ok`)
39
+ // }
40
+ // return data
41
+ // }
42
+ // catch (err) {
43
+ // throw new Error(`getResources error: ${err}`)
44
+ // }
45
+ // }
30
46
  async getResources(entity) {
31
- try {
32
- const baseUrl = await this.discoveryApi.getBaseUrl("kwirth");
33
- const targetUrl = `${baseUrl}/start`;
34
- var payload = JSON.stringify(entity);
35
- const result = await this.fetchApi.fetch(targetUrl, { method: "POST", body: payload, headers: { "Content-Type": "application/json" } });
36
- const data = await result.json();
37
- if (!result.ok) {
38
- throw new Error(`getResources error: not ok`);
39
- }
40
- return data;
41
- } catch (err) {
42
- throw new Error(`getResources error: ${err}`);
43
- }
47
+ return getResources(this.discoveryApi, this.fetchApi, entity);
44
48
  }
45
49
  async requestAccess(entity, channel, scopes) {
46
50
  return requestAccess(this.discoveryApi, this.fetchApi, entity, channel, scopes);
@@ -1 +1 @@
1
- {"version":3,"file":"KwirthMetricsClient.esm.js","sources":["../../src/api/KwirthMetricsClient.ts"],"sourcesContent":["/*\r\nCopyright 2024 Julio Fernandez\r\n\r\nLicensed under the Apache License, Version 2.0 (the \"License\");\r\nyou may not use this file except in compliance with the License.\r\nYou may obtain a copy of the License at\r\n\r\n http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nUnless required by applicable law or agreed to in writing, software\r\ndistributed under the License is distributed on an \"AS IS\" BASIS,\r\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\nSee the License for the specific language governing permissions and\r\nlimitations under the License.\r\n*/\r\nimport { DiscoveryApi, FetchApi } from '@backstage/core-plugin-api'\r\nimport { KwirthMetricsApi } from './types'\r\nimport { Entity } from '@backstage/catalog-model'\r\nimport { ClusterValidPods, getVersion, requestAccess } from '@jfvilas/plugin-kwirth-common'\r\nimport { InstanceConfigScopeEnum } from '@jfvilas/kwirth-common'\r\n\r\nexport interface KwirthMetricsClientOptions {\r\n discoveryApi: DiscoveryApi\r\n fetchApi: FetchApi\r\n}\r\n\r\nexport class KwirthMetricsClient implements KwirthMetricsApi {\r\n private readonly discoveryApi: DiscoveryApi\r\n private readonly fetchApi: FetchApi\r\n\r\n\r\n constructor(options: KwirthMetricsClientOptions) {\r\n this.discoveryApi = options.discoveryApi\r\n this.fetchApi = options.fetchApi\r\n }\r\n\r\n // +++ test\r\n async getVersion() : Promise<string> {\r\n return getVersion(this.discoveryApi, this.fetchApi)\r\n }\r\n\r\n // move to common\r\n // async getVersion(): Promise<string> {\r\n // try {\r\n // const baseUrl = await this.discoveryApi.getBaseUrl('kwirth')\r\n // const targetUrl = `${baseUrl}/version`\r\n\r\n // const result = await this.fetchApi.fetch(targetUrl)\r\n // const data = await result.json()\r\n\r\n // if (!result.ok) {\r\n // throw new Error(`getVersion error: not ok`)\r\n // }\r\n // return data.version\r\n // }\r\n // catch (err) {\r\n // throw new Error(`getVersion error: ${err}`)\r\n // }\r\n // }\r\n\r\n async getResources(entity:Entity): Promise<ClusterValidPods> {\r\n try {\r\n const baseUrl = await this.discoveryApi.getBaseUrl('kwirth')\r\n const targetUrl = `${baseUrl}/start`\r\n\r\n var payload=JSON.stringify(entity)\r\n const result = await this.fetchApi.fetch(targetUrl, {method:'POST', body:payload, headers:{'Content-Type':'application/json'}})\r\n const data = await result.json() as ClusterValidPods\r\n\r\n if (!result.ok) {\r\n throw new Error(`getResources error: not ok`)\r\n }\r\n return data\r\n }\r\n catch (err) {\r\n throw new Error(`getResources error: ${err}`)\r\n }\r\n }\r\n\r\n async requestAccess(entity:Entity, channel:string, scopes:InstanceConfigScopeEnum[]): Promise<ClusterValidPods[]> {\r\n return requestAccess(this.discoveryApi, this.fetchApi, entity, channel, scopes)\r\n }\r\n\r\n //+++ move to backstage-common\r\n // async requestAccess(entity:Entity, channel:string, scopes:InstanceConfigScopeEnum[]): Promise<ClusterValidPods[]> {\r\n // try {\r\n // const baseUrl = await this.discoveryApi.getBaseUrl('kwirth')\r\n // var targetUrl:URL= new URL (`${baseUrl}/access`)\r\n // targetUrl.searchParams.append('scopes',scopes.join(','))\r\n // targetUrl.searchParams.append('channel',channel)\r\n\r\n // var payload=JSON.stringify(entity)\r\n // const result = await this.fetchApi.fetch(targetUrl, {method:'POST', body:payload, headers:{'Content-Type':'application/json'}})\r\n // const data = await result.json() as ClusterValidPods[]\r\n\r\n // // we reconstruct the 'Map' from string of arrays\r\n // for (var c of data) {\r\n // c.accessKeys = new Map(JSON.parse(((c as any).accessKeys)))\r\n // }\r\n // if (!result.ok) {\r\n // throw new Error(`requestAccess error: not ok`)\r\n // }\r\n // return data\r\n // }\r\n // catch (err) {\r\n // throw new Error(`requestAccess error: ${err}`)\r\n // }\r\n // }\r\n\r\n}\r\n"],"names":[],"mappings":";;AA0BO,MAAM,mBAAgD,CAAA;AAAA,EACxC,YAAA;AAAA,EACA,QAAA;AAAA,EAGjB,YAAY,OAAqC,EAAA;AAC7C,IAAA,IAAA,CAAK,eAAe,OAAQ,CAAA,YAAA;AAC5B,IAAA,IAAA,CAAK,WAAW,OAAQ,CAAA,QAAA;AAAA;AAC5B;AAAA,EAGA,MAAM,UAA+B,GAAA;AACjC,IAAA,OAAO,UAAW,CAAA,IAAA,CAAK,YAAc,EAAA,IAAA,CAAK,QAAQ,CAAA;AAAA;AACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAM,aAAa,MAA0C,EAAA;AACzD,IAAI,IAAA;AACA,MAAA,MAAM,OAAU,GAAA,MAAM,IAAK,CAAA,YAAA,CAAa,WAAW,QAAQ,CAAA;AAC3D,MAAM,MAAA,SAAA,GAAY,GAAG,OAAO,CAAA,MAAA,CAAA;AAE5B,MAAI,IAAA,OAAA,GAAQ,IAAK,CAAA,SAAA,CAAU,MAAM,CAAA;AACjC,MAAA,MAAM,SAAS,MAAM,IAAA,CAAK,QAAS,CAAA,KAAA,CAAM,WAAW,EAAC,MAAA,EAAO,MAAQ,EAAA,IAAA,EAAK,SAAS,OAAQ,EAAA,EAAC,cAAe,EAAA,kBAAA,IAAoB,CAAA;AAC9H,MAAM,MAAA,IAAA,GAAO,MAAM,MAAA,CAAO,IAAK,EAAA;AAE/B,MAAI,IAAA,CAAC,OAAO,EAAI,EAAA;AACZ,QAAM,MAAA,IAAI,MAAM,CAA4B,0BAAA,CAAA,CAAA;AAAA;AAEhD,MAAO,OAAA,IAAA;AAAA,aAEJ,GAAK,EAAA;AACR,MAAA,MAAM,IAAI,KAAA,CAAM,CAAuB,oBAAA,EAAA,GAAG,CAAE,CAAA,CAAA;AAAA;AAChD;AACJ,EAEA,MAAM,aAAA,CAAc,MAAe,EAAA,OAAA,EAAgB,MAA+D,EAAA;AAC9G,IAAA,OAAO,cAAc,IAAK,CAAA,YAAA,EAAc,KAAK,QAAU,EAAA,MAAA,EAAQ,SAAS,MAAM,CAAA;AAAA;AAClF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4BJ;;;;"}
1
+ {"version":3,"file":"KwirthMetricsClient.esm.js","sources":["../../src/api/KwirthMetricsClient.ts"],"sourcesContent":["/*\r\nCopyright 2024 Julio Fernandez\r\n\r\nLicensed under the Apache License, Version 2.0 (the \"License\");\r\nyou may not use this file except in compliance with the License.\r\nYou may obtain a copy of the License at\r\n\r\n http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nUnless required by applicable law or agreed to in writing, software\r\ndistributed under the License is distributed on an \"AS IS\" BASIS,\r\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\nSee the License for the specific language governing permissions and\r\nlimitations under the License.\r\n*/\r\nimport { DiscoveryApi, FetchApi } from '@backstage/core-plugin-api'\r\nimport { KwirthMetricsApi } from './types'\r\nimport { Entity } from '@backstage/catalog-model'\r\nimport { ClusterValidPods, getResources, getVersion, requestAccess } from '@jfvilas/plugin-kwirth-common'\r\nimport { InstanceConfigScopeEnum } from '@jfvilas/kwirth-common'\r\n\r\nexport interface KwirthMetricsClientOptions {\r\n discoveryApi: DiscoveryApi\r\n fetchApi: FetchApi\r\n}\r\n\r\nexport class KwirthMetricsClient implements KwirthMetricsApi {\r\n private readonly discoveryApi: DiscoveryApi\r\n private readonly fetchApi: FetchApi\r\n\r\n\r\n constructor(options: KwirthMetricsClientOptions) {\r\n this.discoveryApi = options.discoveryApi\r\n this.fetchApi = options.fetchApi\r\n }\r\n\r\n // +++ test\r\n async getVersion() : Promise<string> {\r\n return getVersion(this.discoveryApi, this.fetchApi)\r\n }\r\n\r\n // move to common\r\n // async getVersion(): Promise<string> {\r\n // try {\r\n // const baseUrl = await this.discoveryApi.getBaseUrl('kwirth')\r\n // const targetUrl = `${baseUrl}/version`\r\n\r\n // const result = await this.fetchApi.fetch(targetUrl)\r\n // const data = await result.json()\r\n\r\n // if (!result.ok) {\r\n // throw new Error(`getVersion error: not ok`)\r\n // }\r\n // return data.version\r\n // }\r\n // catch (err) {\r\n // throw new Error(`getVersion error: ${err}`)\r\n // }\r\n // }\r\n\r\n // async getResources(entity:Entity): Promise<ClusterValidPods> {\r\n // try {\r\n // const baseUrl = await this.discoveryApi.getBaseUrl('kwirth')\r\n // const targetUrl = `${baseUrl}/start`\r\n\r\n // var payload=JSON.stringify(entity)\r\n // const result = await this.fetchApi.fetch(targetUrl, {method:'POST', body:payload, headers:{'Content-Type':'application/json'}})\r\n // const data = await result.json() as ClusterValidPods\r\n\r\n // if (!result.ok) {\r\n // throw new Error(`getResources error: not ok`)\r\n // }\r\n // return data\r\n // }\r\n // catch (err) {\r\n // throw new Error(`getResources error: ${err}`)\r\n // }\r\n // }\r\n async getResources(entity:Entity): Promise<ClusterValidPods> {\r\n return getResources(this.discoveryApi, this.fetchApi, entity)\r\n }\r\n\r\n async requestAccess(entity:Entity, channel:string, scopes:InstanceConfigScopeEnum[]): Promise<ClusterValidPods[]> {\r\n return requestAccess(this.discoveryApi, this.fetchApi, entity, channel, scopes)\r\n }\r\n\r\n //+++ move to backstage-common\r\n // async requestAccess(entity:Entity, channel:string, scopes:InstanceConfigScopeEnum[]): Promise<ClusterValidPods[]> {\r\n // try {\r\n // const baseUrl = await this.discoveryApi.getBaseUrl('kwirth')\r\n // var targetUrl:URL= new URL (`${baseUrl}/access`)\r\n // targetUrl.searchParams.append('scopes',scopes.join(','))\r\n // targetUrl.searchParams.append('channel',channel)\r\n\r\n // var payload=JSON.stringify(entity)\r\n // const result = await this.fetchApi.fetch(targetUrl, {method:'POST', body:payload, headers:{'Content-Type':'application/json'}})\r\n // const data = await result.json() as ClusterValidPods[]\r\n\r\n // // we reconstruct the 'Map' from string of arrays\r\n // for (var c of data) {\r\n // c.accessKeys = new Map(JSON.parse(((c as any).accessKeys)))\r\n // }\r\n // if (!result.ok) {\r\n // throw new Error(`requestAccess error: not ok`)\r\n // }\r\n // return data\r\n // }\r\n // catch (err) {\r\n // throw new Error(`requestAccess error: ${err}`)\r\n // }\r\n // }\r\n\r\n}\r\n"],"names":[],"mappings":";;AA0BO,MAAM,mBAAgD,CAAA;AAAA,EACxC,YAAA;AAAA,EACA,QAAA;AAAA,EAGjB,YAAY,OAAqC,EAAA;AAC7C,IAAA,IAAA,CAAK,eAAe,OAAQ,CAAA,YAAA;AAC5B,IAAA,IAAA,CAAK,WAAW,OAAQ,CAAA,QAAA;AAAA;AAC5B;AAAA,EAGA,MAAM,UAA+B,GAAA;AACjC,IAAA,OAAO,UAAW,CAAA,IAAA,CAAK,YAAc,EAAA,IAAA,CAAK,QAAQ,CAAA;AAAA;AACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuCA,MAAM,aAAa,MAA0C,EAAA;AACzD,IAAA,OAAO,YAAa,CAAA,IAAA,CAAK,YAAc,EAAA,IAAA,CAAK,UAAU,MAAM,CAAA;AAAA;AAChE,EAEA,MAAM,aAAA,CAAc,MAAe,EAAA,OAAA,EAAgB,MAA+D,EAAA;AAC9G,IAAA,OAAO,cAAc,IAAK,CAAA,YAAA,EAAc,KAAK,QAAU,EAAA,MAAA,EAAQ,SAAS,MAAM,CAAA;AAAA;AAClF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4BJ;;;;"}
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { CodeSnippet } from '@backstage/core-components';
3
3
  import { Grid, Typography, Button } from '@material-ui/core';
4
4
  import KwirthComponentNotFound from '../../assets/kwirthmetrics-component-not-found.svg';
5
- import { ANNOTATION_KWIRTH_LOCATION } from '@jfvilas/plugin-kwirth-common';
5
+ import { ANNOTATION_BACKSTAGE_KUBERNETES_LABELID, ANNOTATION_BACKSTAGE_KUBERNETES_LABELSELECTOR } from '@jfvilas/plugin-kwirth-common';
6
6
 
7
7
  var ErrorType = /* @__PURE__ */ ((ErrorType2) => {
8
8
  ErrorType2[ErrorType2["NO_PODS"] = 0] = "NO_PODS";
@@ -15,7 +15,9 @@ metadata:
15
15
  name: '$entityName'
16
16
  description: '$entityDescription'
17
17
  labels:
18
- ${ANNOTATION_KWIRTH_LOCATION} : '$entityName'
18
+ ${ANNOTATION_BACKSTAGE_KUBERNETES_LABELID} : '$entityName'
19
+ # Or just don't add this label and use Backstage label selector this way:
20
+ # ${ANNOTATION_BACKSTAGE_KUBERNETES_LABELSELECTOR}: app=$entityName
19
21
  spec:
20
22
  selector:
21
23
  matchLabels:
@@ -25,7 +27,8 @@ spec:
25
27
  name: '$entityName'-pod
26
28
  labels:
27
29
  app: '$entityName'
28
- ${ANNOTATION_KWIRTH_LOCATION} : '$entityName'
30
+ # Or just don't add this label and use Backstage label selector this way:
31
+ # ${ANNOTATION_BACKSTAGE_KUBERNETES_LABELSELECTOR}: app=$entityName
29
32
  spec:
30
33
  containers:
31
34
  - name: '$entityName'
@@ -43,7 +46,7 @@ const ComponentNotFound = (props) => {
43
46
  customStyle: { background: "inherit" }
44
47
  }
45
48
  );
46
- var nopodsMsg = `Although this component is well tagged, and we have found some clusters configured in Backstage, we were unable to find "${props.entity.metadata.name}" running on any pod. Maybe you need to tag Kubernetes objects (deployment and pod templates).`;
49
+ var nopodsMsg = `Although this component is well tagged inside Backstage, and we have found some clusters configured in Backstage, we were unable to find "${props.entity.metadata.name}" running on any pod. Maybe you need to tag Kubernetes objects (deployment and pod templates).`;
47
50
  var noclustersMsg = `Although this component has a correct 'kubernetes-id' in the ${props.entity.metadata.name} Component YAML, we couldn't find any cluster. Maybe you need to tag Kubernetes objects (deployments and pod templates).`;
48
51
  switch (props.error) {
49
52
  case 0 /* NO_PODS */:
@@ -1 +1 @@
1
- {"version":3,"file":"ComponentNotFound.esm.js","sources":["../../../src/components/ComponentNotFound/ComponentNotFound.tsx"],"sourcesContent":["/*\r\nCopyright 2024 Julio Fernandez\r\n\r\nLicensed under the Apache License, Version 2.0 (the \"License\");\r\nyou may not use this file except in compliance with the License.\r\nYou may obtain a copy of the License at\r\n\r\n http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nUnless required by applicable law or agreed to in writing, software\r\ndistributed under the License is distributed on an \"AS IS\" BASIS,\r\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\nSee the License for the specific language governing permissions and\r\nlimitations under the License.\r\n*/\r\nimport React from 'react'\r\nimport { Entity } from '@backstage/catalog-model'\r\nimport { CodeSnippet } from '@backstage/core-components'\r\nimport { Button, Grid, Typography } from '@material-ui/core'\r\nimport KwirthComponentNotFound from '../../assets/kwirthmetrics-component-not-found.svg'\r\nimport { ANNOTATION_KWIRTH_LOCATION } from '@jfvilas/plugin-kwirth-common'\r\n\r\nenum ErrorType {\r\n NO_PODS,\r\n NO_CLUSTERS\r\n}\r\n\r\nconst KUBERNETES_YAML = `apiVersion: apps/v1\r\nkind: Deployment\r\nmetadata:\r\n name: '$entityName'\r\n description: '$entityDescription'\r\n labels:\r\n ${ANNOTATION_KWIRTH_LOCATION} : '$entityName'\r\nspec:\r\n selector:\r\n matchLabels:\r\n app: '$entityName'\r\n template:\r\n metadata:\r\n name: '$entityName'-pod\r\n labels:\r\n app: '$entityName'\r\n ${ANNOTATION_KWIRTH_LOCATION} : '$entityName'\r\n spec:\r\n containers:\r\n - name: '$entityName'\r\n image: your-OCI-image\r\n ...`;\r\n\r\nconst ComponentNotFound = (props: {error: ErrorType, entity:Entity}) => {\r\n var text:string='';\r\n var content:JSX.Element=<CodeSnippet\r\n text={KUBERNETES_YAML.replaceAll('$entityName', props.entity.metadata.name).replaceAll('$entityDescription',props.entity.metadata.description!)}\r\n language=\"yaml\"\r\n showLineNumbers\r\n highlightedNumbers={[7, 17]}\r\n customStyle={{ background: 'inherit' }}\r\n />;\r\n\r\n var nopodsMsg=`Although this component is well tagged, and we have found some clusters configured in Backstage, we were unable to find \"${props.entity.metadata.name}\" running on any pod. Maybe you need to tag Kubernetes objects (deployment and pod templates).`;\r\n var noclustersMsg=`Although this component has a correct 'kubernetes-id' in the ${props.entity.metadata.name} Component YAML, we couldn't find any cluster. Maybe you need to tag Kubernetes objects (deployments and pod templates).`;\r\n \r\n switch(props.error) {\r\n case ErrorType.NO_PODS:\r\n text=nopodsMsg;\r\n break;\r\n case ErrorType.NO_CLUSTERS:\r\n text=noclustersMsg;\r\n break;\r\n }\r\n\r\n return (<>\r\n <Grid container direction=\"row\" justifyContent=\"flex-start\" alignItems=\"flex-start\" spacing={2} >\r\n <Grid item xs={6} md={6}>\r\n <Grid container direction=\"column\">\r\n <Grid item xs>\r\n <Typography variant=\"h5\">{'Component not found'}</Typography>\r\n </Grid>\r\n <Grid item xs>\r\n <Typography variant=\"body1\">{text}</Typography>\r\n </Grid>\r\n <Grid item xs>\r\n {content}\r\n </Grid>\r\n </Grid>\r\n </Grid>\r\n {\r\n <img src={KwirthComponentNotFound} style={{ left:'10%', marginTop:'10%', width:'30%', position:'relative' }} />\r\n }\r\n </Grid>\r\n <Button variant=\"contained\" color=\"primary\" target=\"_blank\" href=\"https://backstage.io/docs/features/kubernetes/configuration#surfacing-your-kubernetes-components-as-part-of-an-entity\">\r\n READ MORE\r\n </Button>\r\n </>);\r\n}\r\n\r\nexport { ComponentNotFound, ErrorType }"],"names":["ErrorType"],"mappings":"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"}
1
+ {"version":3,"file":"ComponentNotFound.esm.js","sources":["../../../src/components/ComponentNotFound/ComponentNotFound.tsx"],"sourcesContent":["/*\r\nCopyright 2024 Julio Fernandez\r\n\r\nLicensed under the Apache License, Version 2.0 (the \"License\");\r\nyou may not use this file except in compliance with the License.\r\nYou may obtain a copy of the License at\r\n\r\n http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nUnless required by applicable law or agreed to in writing, software\r\ndistributed under the License is distributed on an \"AS IS\" BASIS,\r\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\nSee the License for the specific language governing permissions and\r\nlimitations under the License.\r\n*/\r\nimport React from 'react'\r\nimport { Entity } from '@backstage/catalog-model'\r\nimport { CodeSnippet } from '@backstage/core-components'\r\nimport { Button, Grid, Typography } from '@material-ui/core'\r\nimport KwirthComponentNotFound from '../../assets/kwirthmetrics-component-not-found.svg'\r\nimport { ANNOTATION_BACKSTAGE_KUBERNETES_LABELID, ANNOTATION_BACKSTAGE_KUBERNETES_LABELSELECTOR } from '@jfvilas/plugin-kwirth-common'\r\n\r\nenum ErrorType {\r\n NO_PODS,\r\n NO_CLUSTERS\r\n}\r\n\r\nconst KUBERNETES_YAML = `apiVersion: apps/v1\r\nkind: Deployment\r\nmetadata:\r\n name: '$entityName'\r\n description: '$entityDescription'\r\n labels:\r\n ${ANNOTATION_BACKSTAGE_KUBERNETES_LABELID} : '$entityName'\r\n # Or just don't add this label and use Backstage label selector this way:\r\n # ${ANNOTATION_BACKSTAGE_KUBERNETES_LABELSELECTOR}: app=$entityName\r\nspec:\r\n selector:\r\n matchLabels:\r\n app: '$entityName'\r\n template:\r\n metadata:\r\n name: '$entityName'-pod\r\n labels:\r\n app: '$entityName'\r\n # Or just don't add this label and use Backstage label selector this way:\r\n # ${ANNOTATION_BACKSTAGE_KUBERNETES_LABELSELECTOR}: app=$entityName\r\n spec:\r\n containers:\r\n - name: '$entityName'\r\n image: your-OCI-image\r\n ...`;\r\n\r\nconst ComponentNotFound = (props: {error: ErrorType, entity:Entity}) => {\r\n var text:string='';\r\n var content:JSX.Element=<CodeSnippet\r\n text={KUBERNETES_YAML.replaceAll('$entityName', props.entity.metadata.name).replaceAll('$entityDescription',props.entity.metadata.description!)}\r\n language=\"yaml\"\r\n showLineNumbers\r\n highlightedNumbers={[7, 17]}\r\n customStyle={{ background: 'inherit' }}\r\n />;\r\n\r\n var nopodsMsg=`Although this component is well tagged inside Backstage, and we have found some clusters configured in Backstage, we were unable to find \"${props.entity.metadata.name}\" running on any pod. Maybe you need to tag Kubernetes objects (deployment and pod templates).`;\r\n var noclustersMsg=`Although this component has a correct 'kubernetes-id' in the ${props.entity.metadata.name} Component YAML, we couldn't find any cluster. Maybe you need to tag Kubernetes objects (deployments and pod templates).`;\r\n \r\n switch(props.error) {\r\n case ErrorType.NO_PODS:\r\n text=nopodsMsg;\r\n break;\r\n case ErrorType.NO_CLUSTERS:\r\n text=noclustersMsg;\r\n break;\r\n }\r\n\r\n return (<>\r\n <Grid container direction=\"row\" justifyContent=\"flex-start\" alignItems=\"flex-start\" spacing={2} >\r\n <Grid item xs={6} md={6}>\r\n <Grid container direction=\"column\">\r\n <Grid item xs>\r\n <Typography variant=\"h5\">{'Component not found'}</Typography>\r\n </Grid>\r\n <Grid item xs>\r\n <Typography variant=\"body1\">{text}</Typography>\r\n </Grid>\r\n <Grid item xs>\r\n {content}\r\n </Grid>\r\n </Grid>\r\n </Grid>\r\n {\r\n <img src={KwirthComponentNotFound} style={{ left:'10%', marginTop:'10%', width:'30%', position:'relative' }} />\r\n }\r\n </Grid>\r\n <Button variant=\"contained\" color=\"primary\" target=\"_blank\" href=\"https://backstage.io/docs/features/kubernetes/configuration#surfacing-your-kubernetes-components-as-part-of-an-entity\">\r\n READ MORE\r\n </Button>\r\n </>);\r\n}\r\n\r\nexport { ComponentNotFound, ErrorType }"],"names":["ErrorType"],"mappings":"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"}
@@ -2,7 +2,7 @@ import React, { useState, useRef } from 'react';
2
2
  import useAsync from 'react-use/esm/useAsync';
3
3
  import { Progress, WarningPanel } from '@backstage/core-components';
4
4
  import { useApi, alertApiRef } from '@backstage/core-plugin-api';
5
- import { isKwirthAvailable, ANNOTATION_KWIRTH_LOCATION } from '@jfvilas/plugin-kwirth-common';
5
+ import { isKwirthAvailable, ANNOTATION_BACKSTAGE_KUBERNETES_LABELID, ANNOTATION_BACKSTAGE_KUBERNETES_LABELSELECTOR } from '@jfvilas/plugin-kwirth-common';
6
6
  import { useEntity, MissingAnnotationEmptyState } from '@backstage/plugin-catalog-react';
7
7
  import { kwirthMetricsApiRef } from '../../api/types.esm.js';
8
8
  import { SignalMessageLevelEnum, InstanceConfigScopeEnum, InstanceMessageTypeEnum, OpsCommandEnum, accessKeySerialize, InstanceMessageChannelEnum, InstanceMessageFlowEnum, InstanceMessageActionEnum, MetricsConfigModeEnum, InstanceConfigViewEnum, InstanceConfigObjectEnum } from '@jfvilas/kwirth-common';
@@ -512,7 +512,7 @@ const EntityKwirthMetricsContent = (props) => {
512
512
  websocket?.send(JSON.stringify(rm));
513
513
  }
514
514
  };
515
- return /* @__PURE__ */ React.createElement(React.Fragment, null, showError !== "" && /* @__PURE__ */ React.createElement(ShowError, { message: showError, onClose: () => setShowError("") }), loading && /* @__PURE__ */ React.createElement(Progress, null), !isKwirthAvailable(entity) && !loading && error && /* @__PURE__ */ React.createElement(WarningPanel, { title: "An error has ocurred while obtaining data from kuebernetes clusters.", message: error?.message }), !isKwirthAvailable(entity) && !loading && /* @__PURE__ */ React.createElement(MissingAnnotationEmptyState, { readMoreUrl: "https://github.com/jfvilas/kwirth", annotation: ANNOTATION_KWIRTH_LOCATION }), isKwirthAvailable(entity) && !loading && clusterValidPods && clusterValidPods.length === 0 && /* @__PURE__ */ React.createElement(ComponentNotFound, { error: ErrorType.NO_CLUSTERS, entity }), isKwirthAvailable(entity) && !loading && clusterValidPods && clusterValidPods.length > 0 && clusterValidPods.reduce((sum, cluster) => sum + cluster.data.length, 0) === 0 && /* @__PURE__ */ React.createElement(ComponentNotFound, { error: ErrorType.NO_PODS, entity }), isKwirthAvailable(entity) && !loading && clusterValidPods && clusterValidPods.length > 0 && clusterValidPods.reduce((sum, cluster) => sum + cluster.data.length, 0) > 0 && /* @__PURE__ */ React.createElement(Box, { sx: { display: "flex" } }, /* @__PURE__ */ React.createElement(Box, { sx: { width: "200px" } }, /* @__PURE__ */ React.createElement(Grid, { container: true, direction: "column" }, /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(Card, null, /* @__PURE__ */ React.createElement(ClusterList, { resources: clusterValidPods, selectedClusterName, onSelect: onSelectCluster }))), /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(Card, null, /* @__PURE__ */ React.createElement(Options, { options: kwirthMetricsOptionsRef.current, selectedNamespaces, selectedPodNames, selectedContainerNames, onChange: onChangeOptions, disabled: selectedNamespaces.length === 0 || paused.current }))))), /* @__PURE__ */ React.createElement(Box, { sx: { flexGrow: 1, p: 1 } }, !selectedClusterName && /* @__PURE__ */ React.createElement("img", { src: KwirthMetricsLogo, alt: "No cluster selected", style: { left: "40%", marginTop: "10%", width: "20%", position: "relative" } }), selectedClusterName && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Card, { style: { marginTop: -8 } }, /* @__PURE__ */ React.createElement(
515
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, showError !== "" && /* @__PURE__ */ React.createElement(ShowError, { message: showError, onClose: () => setShowError("") }), loading && /* @__PURE__ */ React.createElement(Progress, null), !isKwirthAvailable(entity) && !loading && error && /* @__PURE__ */ React.createElement(WarningPanel, { title: "An error has ocurred while obtaining data from kuebernetes clusters.", message: error?.message }), !isKwirthAvailable(entity) && !loading && /* @__PURE__ */ React.createElement(MissingAnnotationEmptyState, { readMoreUrl: "https://github.com/jfvilas/kwirth", annotation: [ANNOTATION_BACKSTAGE_KUBERNETES_LABELID, ANNOTATION_BACKSTAGE_KUBERNETES_LABELSELECTOR] }), isKwirthAvailable(entity) && !loading && clusterValidPods && clusterValidPods.length === 0 && /* @__PURE__ */ React.createElement(ComponentNotFound, { error: ErrorType.NO_CLUSTERS, entity }), isKwirthAvailable(entity) && !loading && clusterValidPods && clusterValidPods.length > 0 && clusterValidPods.reduce((sum, cluster) => sum + cluster.data.length, 0) === 0 && /* @__PURE__ */ React.createElement(ComponentNotFound, { error: ErrorType.NO_PODS, entity }), isKwirthAvailable(entity) && !loading && clusterValidPods && clusterValidPods.length > 0 && clusterValidPods.reduce((sum, cluster) => sum + cluster.data.length, 0) > 0 && /* @__PURE__ */ React.createElement(Box, { sx: { display: "flex" } }, /* @__PURE__ */ React.createElement(Box, { sx: { width: "200px" } }, /* @__PURE__ */ React.createElement(Grid, { container: true, direction: "column" }, /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(Card, null, /* @__PURE__ */ React.createElement(ClusterList, { resources: clusterValidPods, selectedClusterName, onSelect: onSelectCluster }))), /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(Card, null, /* @__PURE__ */ React.createElement(Options, { options: kwirthMetricsOptionsRef.current, selectedNamespaces, selectedPodNames, selectedContainerNames, onChange: onChangeOptions, disabled: selectedNamespaces.length === 0 || paused.current }))))), /* @__PURE__ */ React.createElement(Box, { sx: { flexGrow: 1, p: 1 } }, !selectedClusterName && /* @__PURE__ */ React.createElement("img", { src: KwirthMetricsLogo, alt: "No cluster selected", style: { left: "40%", marginTop: "10%", width: "20%", position: "relative" } }), selectedClusterName && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Card, { style: { marginTop: -8 } }, /* @__PURE__ */ React.createElement(
516
516
  CardHeader,
517
517
  {
518
518
  title: statusButtons(selectedClusterName),
@@ -1 +1 @@
1
- {"version":3,"file":"EntityKwirthMetricsContent.esm.js","sources":["../../../src/components/EntityKwirthMetricsContent/EntityKwirthMetricsContent.tsx"],"sourcesContent":["/*\r\nCopyright 2025 Julio Fernandez\r\n\r\nLicensed under the Apache License, Version 2.0 (the \"License\");\r\nyou may not use this file except in compliance with the License.\r\nYou may obtain a copy of the License at\r\n\r\n http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nUnless required by applicable law or agreed to in writing, software\r\ndistributed under the License is distributed on an \"AS IS\" BASIS,\r\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\nSee the License for the specific language governing permissions and\r\nlimitations under the License.\r\n*/\r\nimport React, { useRef, useState } from 'react'\r\nimport useAsync from 'react-use/esm/useAsync'\r\n\r\nimport { Progress, WarningPanel } from '@backstage/core-components'\r\nimport { alertApiRef, useApi } from '@backstage/core-plugin-api'\r\nimport { ANNOTATION_KWIRTH_LOCATION, isKwirthAvailable, ClusterValidPods, PodData, IStatusLine, MetricDefinition } from '@jfvilas/plugin-kwirth-common'\r\nimport { MissingAnnotationEmptyState, useEntity } from '@backstage/plugin-catalog-react'\r\n\r\n// kwirthMetrics\r\nimport { kwirthMetricsApiRef } from '../../api'\r\nimport { accessKeySerialize, MetricsConfigModeEnum, MetricsMessage, InstanceMessageActionEnum, InstanceMessageFlowEnum, InstanceConfigScopeEnum, InstanceConfigViewEnum, InstanceMessage, InstanceMessageTypeEnum, SignalMessage, SignalMessageLevelEnum, InstanceConfigObjectEnum, InstanceConfig, InstanceMessageChannelEnum, OpsCommandEnum, IOpsMessageResponse, IOpsMessage, IRouteMessage } from '@jfvilas/kwirth-common'\r\n\r\n// kwirthMetrics components\r\nimport { ComponentNotFound, ErrorType } from '../ComponentNotFound'\r\nimport { Options, MetricsOptions } from '../Options'\r\nimport { ClusterList } from '../ClusterList'\r\nimport { ObjectSelector } from '../ObjectSelector'\r\nimport { ShowError } from '../ShowError'\r\nimport { StatusLog } from '../StatusLog'\r\n\r\n// Material-UI\r\nimport { Box, Checkbox, FormControl, Grid, MenuItem, Select } from '@material-ui/core'\r\nimport { Card, CardHeader, CardContent } from '@material-ui/core'\r\nimport Divider from '@material-ui/core/Divider'\r\nimport IconButton from '@material-ui/core/IconButton'\r\nimport Typography from '@material-ui/core/Typography'\r\n\r\n// Icons\r\nimport PlayIcon from '@material-ui/icons/PlayArrow'\r\nimport PauseIcon from '@material-ui/icons/Pause'\r\nimport StopIcon from '@material-ui/icons/Stop'\r\nimport InfoIcon from '@material-ui/icons/Info'\r\nimport WarningIcon from '@material-ui/icons/Warning'\r\nimport ErrorIcon from '@material-ui/icons/Error'\r\nimport RefreshIcon from '@material-ui/icons/Refresh'\r\nimport KwirthMetricsLogo from '../../assets/kwirthmetrics-logo.svg'\r\n\r\nimport { Area, AreaChart, Bar, BarChart, CartesianGrid, LabelList, Legend, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts'\r\n\r\nexport const EntityKwirthMetricsContent = (props:{\r\n allMetrics: boolean\r\n enableRestart: boolean\r\n }) => { \r\n const kwirthMetricsApi = useApi(kwirthMetricsApiRef)\r\n const alertApi = useApi(alertApiRef)\r\n const { entity } = useEntity()\r\n const [clusterValidPods, setClusterValidPods] = useState<ClusterValidPods[]>([])\r\n const [selectedClusterName, setSelectedClusterName] = useState('')\r\n const [selectedNamespaces, setSelectedNamespaces] = useState<string[]>([])\r\n const [selectedPodNames, setSelectedPodNames] = useState<string[]>([])\r\n const [selectedContainerNames, setSelectedContainerNames] = useState<string[]>([])\r\n const [selectedMetrics, setSelectedMetrics] = useState<string[]>([])\r\n const [showError, setShowError] = useState('')\r\n const [started, setStarted] = useState(false)\r\n const [stopped, setStopped] = useState(true)\r\n const paused=useRef<boolean>(false)\r\n const [metricsMessages, setMetricsMessages] = useState<MetricsMessage[]>([])\r\n const [statusMessages, setStatusMessages] = useState<IStatusLine[]>([])\r\n const [websocket, setWebsocket] = useState<WebSocket>()\r\n const [instance, setInstance] = useState<string>()\r\n const kwirthMetricsOptionsRef = useRef<MetricsOptions>({depth:10, width:3, interval:10, chart:'area', aggregate:false, merge:false, stack:false })\r\n const [showStatusDialog, setShowStatusDialog] = useState(false)\r\n const [statusLevel, setStatusLevel] = useState<SignalMessageLevelEnum>(SignalMessageLevelEnum.INFO)\r\n const [backendVersion, setBackendVersion ] = useState<string>('')\r\n const [_refresh,setRefresh] = useState(0)\r\n const [allMetrics, setAllMetrics] = useState<MetricDefinition[]>(\r\n [\r\n {metric:'kwirth_container_memory_percentage',help:'',eval:'',type:'counter'},\r\n {metric:'kwirth_container_cpu_percentage',help:'',eval:'',type:'counter'},\r\n {metric:'kwirth_container_transmit_percentage',help:'',eval:'',type:'counter'},\r\n {metric:'kwirth_container_receive_percentage',help:'',eval:'',type:'counter'},\r\n {metric:'kwirth_container_transmit_mbps',help:'',eval:'',type:'counter'},\r\n {metric:'kwirth_container_receive_mbps',help:'',eval:'',type:'counter'}\r\n ])\r\n const { loading, error } = useAsync ( async () => {\r\n if (backendVersion==='') setBackendVersion(await kwirthMetricsApi.getVersion())\r\n let reqScopes = [InstanceConfigScopeEnum.STREAM]\r\n if (props.enableRestart) reqScopes.push(InstanceConfigScopeEnum.RESTART)\r\n let data = await kwirthMetricsApi.requestAccess(entity,'metrics', reqScopes)\r\n setClusterValidPods(data)\r\n })\r\n\r\n const colours = [\r\n \"#6e5bb8\", // morado oscuro\r\n \"#4a9076\", // verde oscuro\r\n \"#b56c52\", // naranja oscuro\r\n \"#7f6b97\", // color lavanda oscuro\r\n \"#b0528f\", // rosa oscuro\r\n \"#b0b052\", // amarillo oscuro\r\n \"#b05252\", // rojo oscuro\r\n \"#5285b0\", // azul oscuro\r\n \"#a38ad6\", // morado pastel\r\n \"#89c1a0\", // verde pastel\r\n \"#e4a28a\", // naranja pastel\r\n \"#b09dbd\", // lavanda pastel\r\n \"#e2a4c6\", // rosa pastel\r\n \"#c5c89e\", // amarillo pastel\r\n \"#e2a4a4\", // rojo pastel\r\n \"#90b7e2\", // azul pastel\r\n \"#f8d5e1\", // rosa claro pastel\r\n \"#b2d7f0\", // azul muy claro pastel\r\n \"#f7e1b5\", // amarillo muy claro pastel\r\n \"#d0f0c0\", // verde muy claro pastel\r\n \"#f5b0a1\", // coral pastel\r\n \"#d8a7db\", // lavanda muy claro pastel\r\n \"#f4c2c2\", // rosa suave pastel\r\n \"#e6c7b9\", // marron claro pastel\r\n \"#f0e2b6\", // crema pastel\r\n \"#a7c7e7\", // azul palido pastel\r\n \"#f5e6a5\", // amarillo palido pastel\r\n \"#e3c8f5\", // lilas pastel\r\n \"#d0c4e8\", // lila palido pastel\r\n \"#b8d8b8\", // verde claro pastel\r\n \"#d2ebfa\", // azul muy claro pastel\r\n \"#f1c1d2\" // rosa bebe pastel\r\n ]\r\n \r\n const clickStart = () => {\r\n if (!paused.current) {\r\n setMetricsMessages([])\r\n setStarted(true)\r\n paused.current=false\r\n setStopped(false)\r\n startMetricsViewer()\r\n }\r\n else {\r\n paused.current=false\r\n setStarted(true)\r\n }\r\n }\r\n\r\n const clickPause = () => {\r\n setStarted(false)\r\n paused.current=true\r\n }\r\n\r\n const clickStop = () => {\r\n setStarted(false)\r\n setStopped(true)\r\n paused.current=false\r\n stopMetricsViewer()\r\n }\r\n\r\n const onSelectCluster = async (clusterName:string|undefined) => {\r\n if (clusterName) {\r\n setSelectedClusterName(clusterName)\r\n setSelectedNamespaces([])\r\n setSelectedPodNames([])\r\n setSelectedContainerNames([])\r\n setMetricsMessages([])\r\n setStatusMessages([])\r\n clickStop()\r\n let cluster = clusterValidPods.find(cluster => cluster.name === clusterName)\r\n if (cluster && cluster.metrics) {\r\n cluster.metrics.sort( (a,b) => a.metric.startsWith('kwirth')? -1:1)\r\n setAllMetrics(cluster.metrics)\r\n }\r\n }\r\n }\r\n\r\n const processMetricsMessage = (wsEvent:any) => {\r\n let instanceMessage = JSON.parse(wsEvent.data) as InstanceMessage\r\n switch (instanceMessage.type) {\r\n case InstanceMessageTypeEnum.DATA:\r\n let metricsMessage = instanceMessage as MetricsMessage\r\n if (metricsMessage.timestamp===0) { // initial metrics values\r\n metricsMessage.timestamp = Date.now()\r\n setMetricsMessages([metricsMessage])\r\n }\r\n else {\r\n setMetricsMessages((prev) => {\r\n while (prev.length>kwirthMetricsOptionsRef.current.depth) {\r\n prev.splice(0,1)\r\n }\r\n if (paused.current)\r\n return prev\r\n else\r\n return [ ...prev, metricsMessage ]\r\n })\r\n }\r\n break\r\n case InstanceMessageTypeEnum.SIGNAL:\r\n if (instanceMessage.flow === InstanceMessageFlowEnum.RESPONSE && instanceMessage.action === InstanceMessageActionEnum.START) {\r\n if (instanceMessage.instance!=='')\r\n setInstance(instanceMessage.instance)\r\n else {\r\n let signalMessage = instanceMessage as SignalMessage\r\n alertApi.post({ message: signalMessage.text, severity:'error', display:'transient' })\r\n }\r\n }\r\n else {\r\n let signalMessage = instanceMessage as SignalMessage\r\n addMessage(signalMessage.level, signalMessage.text)\r\n switch(signalMessage.level) {\r\n case SignalMessageLevelEnum.INFO:\r\n alertApi.post({ message: signalMessage.text, severity:'info', display:'transient' })\r\n break\r\n case SignalMessageLevelEnum.WARNING:\r\n alertApi.post({ message: signalMessage.text, severity:'warning', display:'transient' })\r\n break\r\n case SignalMessageLevelEnum.ERROR:\r\n alertApi.post({ message: signalMessage.text, severity:'error', display:'transient' })\r\n break\r\n default:\r\n alertApi.post({ message: signalMessage.text, severity:'success', display:'transient' })\r\n break\r\n }\r\n }\r\n break\r\n default:\r\n addMessage(SignalMessageLevelEnum.ERROR, 'Invalid message type received: ' + instanceMessage.type)\r\n alertApi.post({ message: 'Invalid message type received: ' + instanceMessage.type, severity:'error', display:'transient' })\r\n break\r\n }\r\n }\r\n \r\n const websocketOnChunk = (wsEvent:any) => {\r\n let instanceMessage:InstanceMessage\r\n try {\r\n instanceMessage = JSON.parse(wsEvent.data) as InstanceMessage\r\n }\r\n catch (err) {\r\n console.log(err)\r\n console.log(wsEvent.data)\r\n return\r\n }\r\n\r\n switch(instanceMessage.channel) {\r\n case InstanceMessageChannelEnum.METRICS:\r\n processMetricsMessage(wsEvent)\r\n break\r\n case InstanceMessageChannelEnum.OPS:\r\n let opsMessage = instanceMessage as IOpsMessageResponse\r\n if (opsMessage.data?.data) \r\n addMessage (SignalMessageLevelEnum.WARNING, 'Operations message: '+opsMessage.data.data)\r\n else\r\n addMessage (SignalMessageLevelEnum.WARNING, 'Operations message: '+JSON.stringify(opsMessage))\r\n break\r\n default:\r\n console.log('Invalid channel in message: ', instanceMessage)\r\n break\r\n }\r\n\r\n }\r\n\r\n const websocketOnOpen = (ws:WebSocket) => {\r\n let cluster=clusterValidPods.find(cluster => cluster.name===selectedClusterName)\r\n if (!cluster) {\r\n addMessage(SignalMessageLevelEnum.ERROR, 'Cluster not found')\r\n return\r\n }\r\n let pods = cluster.data.filter(p => selectedNamespaces.includes(p.namespace))\r\n if (!pods || pods.length===0) {\r\n addMessage(SignalMessageLevelEnum.ERROR, 'Pod not found')\r\n return\r\n }\r\n\r\n console.log(`WS connected`)\r\n let accessKey = cluster.accessKeys.get(InstanceConfigScopeEnum.STREAM)\r\n if (accessKey) {\r\n let containers:string[] = []\r\n if (selectedContainerNames.length>0) {\r\n for(var p of selectedPodNames) {\r\n for (var c of selectedContainerNames) {\r\n containers.push(p+'+'+c)\r\n }\r\n }\r\n }\r\n var iConfig:InstanceConfig = {\r\n channel: InstanceMessageChannelEnum.METRICS,\r\n objects: InstanceConfigObjectEnum.PODS,\r\n action: InstanceMessageActionEnum.START,\r\n flow: InstanceMessageFlowEnum.REQUEST,\r\n instance: '',\r\n accessKey: accessKeySerialize(accessKey),\r\n scope: InstanceConfigScopeEnum.STREAM,\r\n view: (selectedContainerNames.length > 0 ? InstanceConfigViewEnum.CONTAINER : InstanceConfigViewEnum.POD),\r\n namespace: selectedNamespaces.join(','),\r\n group: '',\r\n pod: selectedPodNames.join(','),\r\n container: containers.join(','),\r\n data: {\r\n mode: MetricsConfigModeEnum.STREAM,\r\n aggregate: kwirthMetricsOptionsRef.current.aggregate,\r\n metrics: selectedMetrics,\r\n interval: kwirthMetricsOptionsRef.current.interval\r\n },\r\n type: InstanceMessageTypeEnum.SIGNAL\r\n }\r\n ws.send(JSON.stringify(iConfig))\r\n }\r\n else {\r\n addMessage(SignalMessageLevelEnum.ERROR, 'AccessKey has not been obtained')\r\n return\r\n }\r\n }\r\n\r\n const startMetricsViewer = () => {\r\n let cluster=clusterValidPods.find(cluster => cluster.name===selectedClusterName)\r\n if (!cluster) {\r\n addMessage(SignalMessageLevelEnum.ERROR, 'Cluster not found')\r\n return\r\n }\r\n\r\n try {\r\n let ws = new WebSocket(cluster.url)\r\n ws.onopen = () => websocketOnOpen(ws)\r\n ws.onmessage = (event) => websocketOnChunk(event)\r\n ws.onclose = (event) => websocketOnClose(event)\r\n setWebsocket(ws)\r\n }\r\n catch (err) {\r\n addMessage(SignalMessageLevelEnum.ERROR, 'Error starting websocket')\r\n }\r\n\r\n }\r\n\r\n const websocketOnClose = (_event:any) => {\r\n console.log(`WS disconnected from remote`)\r\n setStarted(false)\r\n paused.current=false\r\n setStopped(true)\r\n }\r\n\r\n const stopMetricsViewer = () => {\r\n websocket?.close()\r\n }\r\n\r\n const onChangeOptions = (options:MetricsOptions) => {\r\n kwirthMetricsOptionsRef.current=options\r\n setRefresh(Math.random())\r\n }\r\n \r\n const actionButtons = () => {\r\n let hasStreamKey = false, hasRestartKey = false\r\n let cluster=clusterValidPods.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n hasStreamKey = Boolean(cluster.accessKeys.has(InstanceConfigScopeEnum.STREAM))\r\n hasRestartKey = Boolean(cluster.accessKeys.get(InstanceConfigScopeEnum.RESTART))\r\n }\r\n\r\n return <>\r\n { props.enableRestart &&\r\n <IconButton title='Restart' onClick={onClickRestart} disabled={selectedPodNames.length === 0 || !hasRestartKey || !websocket || !started}>\r\n <RefreshIcon />\r\n </IconButton>\r\n }\r\n <IconButton onClick={clickStart} title=\"Play\" disabled={started || !paused || selectedPodNames.length === 0 || selectedMetrics.length==0 || !hasStreamKey}>\r\n <PlayIcon />\r\n </IconButton>\r\n <IconButton onClick={clickPause} title=\"Pause\" disabled={!((started && !paused.current) && selectedPodNames.length === 0)}>\r\n <PauseIcon />\r\n </IconButton>\r\n <IconButton onClick={clickStop} title=\"Stop\" disabled={stopped || selectedPodNames.length === 0}>\r\n <StopIcon />\r\n </IconButton>\r\n </>\r\n }\r\n\r\n const onMetricsChange = (event:any) => {\r\n setSelectedMetrics(event.target.value)\r\n }\r\n\r\n const metricsSelector = () => {\r\n let disabled = selectedClusterName === '' || selectedNamespaces.length === 0\r\n return (\r\n <FormControl style={{marginLeft:16, width:'300px'}} size='small'>\r\n <Select value={selectedMetrics} MenuProps={{variant:'menu'}} multiple onChange={onMetricsChange} renderValue={(selected) => (selected as string[]).join(', ')} disabled={disabled || started}>\r\n {\r\n allMetrics.map(m => \r\n <MenuItem key={m.metric} value={m.metric} style={{marginTop:'-6px', marginBottom:'-6px'}}>\r\n <Checkbox checked={selectedMetrics.includes(m.metric)} style={{marginTop:'-6px', marginBottom:'-6px'}}/>\r\n <Typography style={{marginTop:'-6px', marginBottom:'-6px'}}>{m.metric}</Typography>\r\n </MenuItem>\r\n )\r\n }\r\n </Select>\r\n </FormControl>\r\n )\r\n }\r\n\r\n const statusButtons = (title:string) => {\r\n const show = (level:SignalMessageLevelEnum) => {\r\n setShowStatusDialog(true)\r\n setStatusLevel(level)\r\n }\r\n\r\n return (\r\n <Grid container direction='row'>\r\n <Grid item>\r\n <Typography variant='h5'>{title}</Typography>\r\n </Grid>\r\n <Grid item style={{marginTop:'-8px'}}>\r\n <IconButton title=\"info\" disabled={!statusMessages.some(m=>m.type=== InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.INFO)} onClick={() => show(SignalMessageLevelEnum.INFO)}>\r\n <InfoIcon style={{ color:statusMessages.some(m=>m.type=== InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.INFO)?'blue':'#BDBDBD'}}/>\r\n </IconButton>\r\n <IconButton title=\"warning\" disabled={!statusMessages.some(m=>m.type=== InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.WARNING)} onClick={() => show(SignalMessageLevelEnum.WARNING)} style={{marginLeft:'-16px'}}>\r\n <WarningIcon style={{ color:statusMessages.some(m=>m.type=== InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.WARNING)?'gold':'#BDBDBD'}}/>\r\n </IconButton>\r\n <IconButton title=\"error\" disabled={!statusMessages.some(m=>m.type=== InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.ERROR)} onClick={() => show(SignalMessageLevelEnum.ERROR)} style={{marginLeft:'-16px'}}>\r\n <ErrorIcon style={{ color:statusMessages.some(m=>m.type=== InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.ERROR)?'red':'#BDBDBD'}}/>\r\n </IconButton>\r\n </Grid>\r\n <Grid item>\r\n {metricsSelector()}\r\n </Grid>\r\n </Grid>\r\n )\r\n }\r\n\r\n const statusClear = (level: SignalMessageLevelEnum) => {\r\n setStatusMessages(statusMessages.filter(m=> m.level!==level))\r\n setShowStatusDialog(false)\r\n }\r\n \r\n const mergeSeries = (names:string[], series:any[]) => {\r\n if (!names || names.length===0) return []\r\n var resultSeries:any[] = []\r\n\r\n for (var i=0; i<series[0].length; i++) {\r\n var item: { [key: string]: string|number } = {}\r\n for (var j=0; j<series.length; j++ ) {\r\n if (series[j][i]) {\r\n item['timestamp'] = series[0][i].timestamp\r\n item[names[j]] = series[j][i].value\r\n }\r\n }\r\n resultSeries.push(item)\r\n }\r\n return resultSeries\r\n }\r\n\r\n const addChart = (options: MetricsOptions, metric:string, names:string[], series:any[], colour:string) => {\r\n var result = <></>\r\n var mergedSeries = mergeSeries(names, series)\r\n\r\n const renderLabel = (data:any) => {\r\n var values:any[] = series.map (s => s[data.index])\r\n var total:number =values.reduce((acc,value) => acc+value.value, 0)\r\n return <text x={data.x + data.width/3.5} y={data.y-10}>{total.toPrecision(3).replace(/0+$/, \"\")}</text>\r\n }\r\n let height=300\r\n\r\n switch (options.chart) {\r\n case 'value':\r\n height=40+series.length*80\r\n result = (\r\n <Grid direction={'row'}>\r\n {\r\n <Typography>\r\n { series.map( (serie,index) => {\r\n return (<>\r\n <Typography >\r\n {serie[serie.length-1].value}\r\n </Typography>\r\n <Typography >\r\n {names[index]}\r\n </Typography>\r\n </>)\r\n })}\r\n </Typography>\r\n }\r\n </Grid>\r\n\r\n )\r\n break\r\n case 'line':\r\n result = (\r\n <LineChart data={mergedSeries}>\r\n <CartesianGrid strokeDasharray=\"3 3\"/>\r\n <XAxis dataKey=\"timestamp\" fontSize={8}/>\r\n <YAxis />\r\n <Tooltip />\r\n <Legend/>\r\n { series.map ((_serie,index) => <Line key={index} name={names[index]} type=\"monotone\" dataKey={names[index]} stroke={series.length===1?colour:colours[index]} activeDot={{ r: 8 }} />) }\r\n </LineChart>\r\n )\r\n break\r\n case 'area':\r\n result = (\r\n <AreaChart data={mergedSeries}>\r\n <defs>\r\n {\r\n series.map( (_serie,index) => {\r\n return (\r\n <linearGradient key={index} id={`color${series.length===1?colour:colours[index]}`} x1='0' y1='0' x2='0' y2='1'>\r\n <stop offset='7%' stopColor={series.length===1?colour:colours[index]} stopOpacity={0.8}/>\r\n <stop offset='93%' stopColor={series.length===1?colour:colours[index]} stopOpacity={0}/>\r\n </linearGradient>\r\n )\r\n })\r\n }\r\n </defs>\r\n <CartesianGrid strokeDasharray=\"3 3\"/>\r\n <XAxis dataKey=\"timestamp\" fontSize={8}/>\r\n <YAxis />\r\n <Tooltip />\r\n <Legend/>\r\n { series.map ((_serie,index) => \r\n <Area key={index} name={names[index]} type=\"monotone\" {...(options.stack? {stackId:\"1\"}:{})} dataKey={names[index]} stroke={series.length===1?colour:colours[index]} fill={`url(#color${series.length===1?colour:colours[index]})`}/> )}\r\n </AreaChart>\r\n )\r\n break\r\n case 'bar':\r\n result = (\r\n <BarChart data={mergedSeries}>\r\n <CartesianGrid strokeDasharray=\"3 3\"/>\r\n <XAxis dataKey=\"timestamp\" fontSize={8}/>\r\n <YAxis />\r\n <Tooltip/>\r\n <Legend/>\r\n { series.map ((_serie,index) =>\r\n <Bar name={names[index]} {...(options.stack? {stackId:\"1\"}:{})} dataKey={names[index]} stroke={series.length===1?colour:colours[index]} fill={series.length===1?colour:colours[index]}>\r\n { index === series.length-1 && series.length > 1 ? <LabelList dataKey={names[index]} position='insideTop' content={ renderLabel }/> : null }\r\n </Bar>\r\n )}\r\n </BarChart>\r\n )\r\n break\r\n default:\r\n break\r\n }\r\n\r\n return (\r\n <Grid direction='column' style={{width:'100%', marginBottom:8}}>\r\n <Typography align='center'>{metric}</Typography>\r\n <ResponsiveContainer height={height} key={metric+JSON.stringify(names)}>\r\n {result}\r\n </ResponsiveContainer> \r\n </Grid>\r\n )\r\n }\r\n\r\n const showMetrics = (options: MetricsOptions) => {\r\n if (!metricsMessages || metricsMessages.length === 0) {\r\n if (selectedNamespaces.length === 0) \r\n return <Typography>Select namespace chip on top.</Typography>\r\n else\r\n return <>\r\n {started?<Typography>Waiting for first data, be patient...</Typography>:<Typography>Configure <b>chart options</b>, select some <b>metrics on top</b>, and <b>press PLAY</b> on top-right button to start viewing.</Typography>}\r\n </>\r\n }\r\n\r\n let data:Map<string, Map<string, { timestamp:string, value:number}[]>> = new Map()\r\n for (let metricsMessage of metricsMessages) {\r\n let ts = new Date(metricsMessage.timestamp)\r\n let timestamp = `${ts.getHours().toString().padStart(2,'0')}:${ts.getMinutes().toString().padStart(2,'0')}:${ts.getSeconds().toString().padStart(2,'0')}`\r\n for (var i=0;i<metricsMessage.assets.length;i++) {\r\n var assetName=metricsMessage.assets[i].assetName\r\n for (var metrics of metricsMessage.assets[i].values) {\r\n if (!data.has(assetName)) data.set(assetName, new Map())\r\n if (!data.get(assetName)?.has(metrics.metricName)) data.get(assetName)?.set(metrics.metricName,[])\r\n data.get(assetName)?.get(metrics.metricName)?.push({timestamp, value:metrics.metricValue})\r\n }\r\n } \r\n }\r\n\r\n let allCharts:any[] = []\r\n if (options.merge) {\r\n var assetNames=Array.from(data.keys())\r\n var firstAsset=assetNames[0]\r\n var allMetrics:string[] = Array.from(new Set(data.get(firstAsset)!.keys()))\r\n\r\n for (let metric of allMetrics) {\r\n var series = assetNames.map(an => {\r\n return data.get(an)!.get(metric)\r\n })\r\n allCharts.push(<>{addChart(options, metric, assetNames, series, '')}</>)\r\n }\r\n\r\n let rows = []\r\n for (let i = 0; i < allCharts.length; i += options.width) {\r\n rows.push(allCharts.slice(i, i + options.width))\r\n }\r\n return (<>\r\n {rows.map((row, index) => (\r\n <div key={index} style={{ display: 'flex', justifyContent: 'space-around' }}>\r\n {row}\r\n </div>\r\n ))}\r\n </>)\r\n }\r\n else {\r\n let allCharts = Array.from(data.keys()!).map( (asset, index) => {\r\n return Array.from(data.get(asset)?.keys()!).map ( metric => {\r\n var serie:any=data.get(asset)?.get(metric)!\r\n return (<>{addChart(options, metric, [asset], [serie], colours[index])}</>)\r\n })\r\n })\r\n\r\n // convert allResults (a list of charts) into a series of rows of charts\r\n let rows = []\r\n for (var resultAsset of allCharts) {\r\n for (let i = 0; i < resultAsset.length; i += options.width) {\r\n rows.push(resultAsset.slice(i, i + options.width))\r\n }\r\n }\r\n return (<>\r\n {rows.map((row, index) => (\r\n <div key={index} style={{ display: 'flex', justifyContent: 'space-around' }}>\r\n {row}\r\n </div>\r\n ))}\r\n </>)\r\n }\r\n }\r\n\r\n const onSelectObject = (namespaces:string[], podNames:string[], containerNames:string[]) => {\r\n setSelectedNamespaces(namespaces)\r\n setSelectedPodNames(podNames)\r\n setSelectedContainerNames(containerNames)\r\n }\r\n\r\n const addMessage = (level:SignalMessageLevelEnum, text:string) => {\r\n setStatusMessages ((prev) => [...prev, {\r\n level,\r\n text,\r\n type: InstanceMessageTypeEnum.SIGNAL\r\n }])\r\n }\r\n\r\n const onClickRestart = () => {\r\n // we perform a route command from channel 'metrics' to channel 'ops'\r\n let cluster=clusterValidPods.find(cluster => cluster.name===selectedClusterName)\r\n if (!cluster) {\r\n addMessage(SignalMessageLevelEnum.ERROR,'No cluster selected')\r\n return\r\n }\r\n let restartKey = cluster.accessKeys.get(InstanceConfigScopeEnum.RESTART)\r\n if (!restartKey) {\r\n addMessage(SignalMessageLevelEnum.ERROR,'No access key present')\r\n return\r\n }\r\n if (!instance) {\r\n addMessage(SignalMessageLevelEnum.ERROR,'No instance has been established')\r\n return\r\n }\r\n\r\n\r\n let pods:PodData[] = (cluster.data as PodData[]).filter(pod => selectedNamespaces.includes(pod.namespace))\r\n for (let pod of pods) {\r\n let om:IOpsMessage = {\r\n msgtype: 'opsmessage',\r\n action: InstanceMessageActionEnum.COMMAND,\r\n flow: InstanceMessageFlowEnum.IMMEDIATE,\r\n type: InstanceMessageTypeEnum.DATA,\r\n channel: InstanceMessageChannelEnum.OPS,\r\n instance: '',\r\n id: '1',\r\n accessKey: accessKeySerialize(restartKey),\r\n command: OpsCommandEnum.RESTARTPOD,\r\n namespace: pod.namespace,\r\n group: '',\r\n pod: pod.name,\r\n container: ''\r\n }\r\n let rm: IRouteMessage = {\r\n msgtype: 'routemessage',\r\n accessKey: accessKeySerialize(restartKey),\r\n destChannel: InstanceMessageChannelEnum.OPS,\r\n action: InstanceMessageActionEnum.ROUTE,\r\n flow: InstanceMessageFlowEnum.IMMEDIATE,\r\n type: InstanceMessageTypeEnum.SIGNAL,\r\n channel: InstanceMessageChannelEnum.METRICS,\r\n instance: instance,\r\n data: om\r\n }\r\n websocket?.send(JSON.stringify(rm))\r\n }\r\n }\r\n\r\n return (<>\r\n { showError!=='' && <ShowError message={showError} onClose={() => setShowError('')}/> }\r\n\r\n { loading && <Progress/> }\r\n\r\n {!isKwirthAvailable(entity) && !loading && error && (\r\n <WarningPanel title={'An error has ocurred while obtaining data from kuebernetes clusters.'} message={error?.message} />\r\n )}\r\n\r\n {!isKwirthAvailable(entity) && !loading && (\r\n <MissingAnnotationEmptyState readMoreUrl='https://github.com/jfvilas/kwirth' annotation={ANNOTATION_KWIRTH_LOCATION}/>\r\n )}\r\n\r\n { isKwirthAvailable(entity) && !loading && clusterValidPods && clusterValidPods.length===0 &&\r\n <ComponentNotFound error={ErrorType.NO_CLUSTERS} entity={entity}/>\r\n }\r\n\r\n { isKwirthAvailable(entity) && !loading && clusterValidPods && clusterValidPods.length>0 && clusterValidPods.reduce((sum,cluster) => sum+cluster.data.length, 0)===0 &&\r\n <ComponentNotFound error={ErrorType.NO_PODS} entity={entity}/>\r\n }\r\n\r\n { isKwirthAvailable(entity) && !loading && clusterValidPods && clusterValidPods.length>0 && clusterValidPods.reduce((sum,cluster) => sum+cluster.data.length, 0)>0 &&\r\n <Box sx={{ display: 'flex'}}>\r\n <Box sx={{ width: '200px'}}>\r\n <Grid container direction='column'>\r\n <Grid item>\r\n <Card>\r\n <ClusterList resources={clusterValidPods} selectedClusterName={selectedClusterName} onSelect={onSelectCluster}/>\r\n </Card>\r\n </Grid>\r\n <Grid item>\r\n <Card>\r\n <Options options={kwirthMetricsOptionsRef.current!} selectedNamespaces={selectedNamespaces} selectedPodNames={selectedPodNames} selectedContainerNames={selectedContainerNames} onChange={onChangeOptions} disabled={selectedNamespaces.length === 0 || paused.current}/>\r\n </Card>\r\n </Grid>\r\n </Grid>\r\n\r\n </Box>\r\n <Box sx={{ flexGrow: 1, p:1 }}>\r\n\r\n { !selectedClusterName && \r\n <img src={KwirthMetricsLogo} alt=\"No cluster selected\" style={{ left:'40%', marginTop:'10%', width:'20%', position:'relative' }} />\r\n }\r\n\r\n { selectedClusterName && <>\r\n <Card style={{marginTop:-8}}>\r\n <CardHeader\r\n title={statusButtons(selectedClusterName)}\r\n style={{marginTop:-4, marginBottom:4, flexShrink:0}}\r\n action={actionButtons()}\r\n />\r\n \r\n <Typography style={{marginLeft:16, marginBottom:4}}>\r\n <ObjectSelector cluster={clusterValidPods.find(cluster => cluster.name === selectedClusterName)!} onSelect={onSelectObject} disabled={selectedClusterName === '' || started || paused.current} selectedNamespaces={selectedNamespaces} selectedPodNames={selectedPodNames} selectedContainerNames={selectedContainerNames} scope={InstanceConfigScopeEnum.STREAM}/>\r\n </Typography>\r\n <Divider/>\r\n <CardContent style={{ overflow: 'auto' }}>\r\n { showMetrics(kwirthMetricsOptionsRef.current) }\r\n </CardContent>\r\n </Card>\r\n </>}\r\n </Box> \r\n </Box>\r\n }\r\n\r\n { showStatusDialog && <StatusLog level={statusLevel} onClose={() => setShowStatusDialog(false)} statusMessages={statusMessages} onClear={statusClear}/>}\r\n </>)\r\n}\r\n"],"names":["cluster","p","allMetrics","i","allCharts"],"mappings":"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"}
1
+ {"version":3,"file":"EntityKwirthMetricsContent.esm.js","sources":["../../../src/components/EntityKwirthMetricsContent/EntityKwirthMetricsContent.tsx"],"sourcesContent":["/*\r\nCopyright 2025 Julio Fernandez\r\n\r\nLicensed under the Apache License, Version 2.0 (the \"License\");\r\nyou may not use this file except in compliance with the License.\r\nYou may obtain a copy of the License at\r\n\r\n http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nUnless required by applicable law or agreed to in writing, software\r\ndistributed under the License is distributed on an \"AS IS\" BASIS,\r\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\nSee the License for the specific language governing permissions and\r\nlimitations under the License.\r\n*/\r\nimport React, { useRef, useState } from 'react'\r\nimport useAsync from 'react-use/esm/useAsync'\r\n\r\nimport { Progress, WarningPanel } from '@backstage/core-components'\r\nimport { alertApiRef, useApi } from '@backstage/core-plugin-api'\r\nimport { isKwirthAvailable, ClusterValidPods, PodData, IStatusLine, MetricDefinition, ANNOTATION_BACKSTAGE_KUBERNETES_LABELID, ANNOTATION_BACKSTAGE_KUBERNETES_LABELSELECTOR } from '@jfvilas/plugin-kwirth-common'\r\nimport { MissingAnnotationEmptyState, useEntity } from '@backstage/plugin-catalog-react'\r\n\r\n// kwirthMetrics\r\nimport { kwirthMetricsApiRef } from '../../api'\r\nimport { accessKeySerialize, MetricsConfigModeEnum, MetricsMessage, InstanceMessageActionEnum, InstanceMessageFlowEnum, InstanceConfigScopeEnum, InstanceConfigViewEnum, InstanceMessage, InstanceMessageTypeEnum, SignalMessage, SignalMessageLevelEnum, InstanceConfigObjectEnum, InstanceConfig, InstanceMessageChannelEnum, OpsCommandEnum, IOpsMessageResponse, IOpsMessage, IRouteMessage } from '@jfvilas/kwirth-common'\r\n\r\n// kwirthMetrics components\r\nimport { ComponentNotFound, ErrorType } from '../ComponentNotFound'\r\nimport { Options, MetricsOptions } from '../Options'\r\nimport { ClusterList } from '../ClusterList'\r\nimport { ObjectSelector } from '../ObjectSelector'\r\nimport { ShowError } from '../ShowError'\r\nimport { StatusLog } from '../StatusLog'\r\n\r\n// Material-UI\r\nimport { Box, Checkbox, FormControl, Grid, MenuItem, Select } from '@material-ui/core'\r\nimport { Card, CardHeader, CardContent } from '@material-ui/core'\r\nimport Divider from '@material-ui/core/Divider'\r\nimport IconButton from '@material-ui/core/IconButton'\r\nimport Typography from '@material-ui/core/Typography'\r\n\r\n// Icons\r\nimport PlayIcon from '@material-ui/icons/PlayArrow'\r\nimport PauseIcon from '@material-ui/icons/Pause'\r\nimport StopIcon from '@material-ui/icons/Stop'\r\nimport InfoIcon from '@material-ui/icons/Info'\r\nimport WarningIcon from '@material-ui/icons/Warning'\r\nimport ErrorIcon from '@material-ui/icons/Error'\r\nimport RefreshIcon from '@material-ui/icons/Refresh'\r\nimport KwirthMetricsLogo from '../../assets/kwirthmetrics-logo.svg'\r\n\r\nimport { Area, AreaChart, Bar, BarChart, CartesianGrid, LabelList, Legend, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts'\r\n\r\nexport const EntityKwirthMetricsContent = (props:{\r\n allMetrics: boolean\r\n enableRestart: boolean\r\n }) => { \r\n const kwirthMetricsApi = useApi(kwirthMetricsApiRef)\r\n const alertApi = useApi(alertApiRef)\r\n const { entity } = useEntity()\r\n const [clusterValidPods, setClusterValidPods] = useState<ClusterValidPods[]>([])\r\n const [selectedClusterName, setSelectedClusterName] = useState('')\r\n const [selectedNamespaces, setSelectedNamespaces] = useState<string[]>([])\r\n const [selectedPodNames, setSelectedPodNames] = useState<string[]>([])\r\n const [selectedContainerNames, setSelectedContainerNames] = useState<string[]>([])\r\n const [selectedMetrics, setSelectedMetrics] = useState<string[]>([])\r\n const [showError, setShowError] = useState('')\r\n const [started, setStarted] = useState(false)\r\n const [stopped, setStopped] = useState(true)\r\n const paused=useRef<boolean>(false)\r\n const [metricsMessages, setMetricsMessages] = useState<MetricsMessage[]>([])\r\n const [statusMessages, setStatusMessages] = useState<IStatusLine[]>([])\r\n const [websocket, setWebsocket] = useState<WebSocket>()\r\n const [instance, setInstance] = useState<string>()\r\n const kwirthMetricsOptionsRef = useRef<MetricsOptions>({depth:10, width:3, interval:10, chart:'area', aggregate:false, merge:false, stack:false })\r\n const [showStatusDialog, setShowStatusDialog] = useState(false)\r\n const [statusLevel, setStatusLevel] = useState<SignalMessageLevelEnum>(SignalMessageLevelEnum.INFO)\r\n const [backendVersion, setBackendVersion ] = useState<string>('')\r\n const [_refresh,setRefresh] = useState(0)\r\n const [allMetrics, setAllMetrics] = useState<MetricDefinition[]>(\r\n [\r\n {metric:'kwirth_container_memory_percentage',help:'',eval:'',type:'counter'},\r\n {metric:'kwirth_container_cpu_percentage',help:'',eval:'',type:'counter'},\r\n {metric:'kwirth_container_transmit_percentage',help:'',eval:'',type:'counter'},\r\n {metric:'kwirth_container_receive_percentage',help:'',eval:'',type:'counter'},\r\n {metric:'kwirth_container_transmit_mbps',help:'',eval:'',type:'counter'},\r\n {metric:'kwirth_container_receive_mbps',help:'',eval:'',type:'counter'}\r\n ])\r\n const { loading, error } = useAsync ( async () => {\r\n if (backendVersion==='') setBackendVersion(await kwirthMetricsApi.getVersion())\r\n let reqScopes = [InstanceConfigScopeEnum.STREAM]\r\n if (props.enableRestart) reqScopes.push(InstanceConfigScopeEnum.RESTART)\r\n let data = await kwirthMetricsApi.requestAccess(entity,'metrics', reqScopes)\r\n setClusterValidPods(data)\r\n })\r\n\r\n const colours = [\r\n \"#6e5bb8\", // morado oscuro\r\n \"#4a9076\", // verde oscuro\r\n \"#b56c52\", // naranja oscuro\r\n \"#7f6b97\", // color lavanda oscuro\r\n \"#b0528f\", // rosa oscuro\r\n \"#b0b052\", // amarillo oscuro\r\n \"#b05252\", // rojo oscuro\r\n \"#5285b0\", // azul oscuro\r\n \"#a38ad6\", // morado pastel\r\n \"#89c1a0\", // verde pastel\r\n \"#e4a28a\", // naranja pastel\r\n \"#b09dbd\", // lavanda pastel\r\n \"#e2a4c6\", // rosa pastel\r\n \"#c5c89e\", // amarillo pastel\r\n \"#e2a4a4\", // rojo pastel\r\n \"#90b7e2\", // azul pastel\r\n \"#f8d5e1\", // rosa claro pastel\r\n \"#b2d7f0\", // azul muy claro pastel\r\n \"#f7e1b5\", // amarillo muy claro pastel\r\n \"#d0f0c0\", // verde muy claro pastel\r\n \"#f5b0a1\", // coral pastel\r\n \"#d8a7db\", // lavanda muy claro pastel\r\n \"#f4c2c2\", // rosa suave pastel\r\n \"#e6c7b9\", // marron claro pastel\r\n \"#f0e2b6\", // crema pastel\r\n \"#a7c7e7\", // azul palido pastel\r\n \"#f5e6a5\", // amarillo palido pastel\r\n \"#e3c8f5\", // lilas pastel\r\n \"#d0c4e8\", // lila palido pastel\r\n \"#b8d8b8\", // verde claro pastel\r\n \"#d2ebfa\", // azul muy claro pastel\r\n \"#f1c1d2\" // rosa bebe pastel\r\n ]\r\n \r\n const clickStart = () => {\r\n if (!paused.current) {\r\n setMetricsMessages([])\r\n setStarted(true)\r\n paused.current=false\r\n setStopped(false)\r\n startMetricsViewer()\r\n }\r\n else {\r\n paused.current=false\r\n setStarted(true)\r\n }\r\n }\r\n\r\n const clickPause = () => {\r\n setStarted(false)\r\n paused.current=true\r\n }\r\n\r\n const clickStop = () => {\r\n setStarted(false)\r\n setStopped(true)\r\n paused.current=false\r\n stopMetricsViewer()\r\n }\r\n\r\n const onSelectCluster = async (clusterName:string|undefined) => {\r\n if (clusterName) {\r\n setSelectedClusterName(clusterName)\r\n setSelectedNamespaces([])\r\n setSelectedPodNames([])\r\n setSelectedContainerNames([])\r\n setMetricsMessages([])\r\n setStatusMessages([])\r\n clickStop()\r\n let cluster = clusterValidPods.find(cluster => cluster.name === clusterName)\r\n if (cluster && cluster.metrics) {\r\n cluster.metrics.sort( (a,b) => a.metric.startsWith('kwirth')? -1:1)\r\n setAllMetrics(cluster.metrics)\r\n }\r\n }\r\n }\r\n\r\n const processMetricsMessage = (wsEvent:any) => {\r\n let instanceMessage = JSON.parse(wsEvent.data) as InstanceMessage\r\n switch (instanceMessage.type) {\r\n case InstanceMessageTypeEnum.DATA:\r\n let metricsMessage = instanceMessage as MetricsMessage\r\n if (metricsMessage.timestamp===0) { // initial metrics values\r\n metricsMessage.timestamp = Date.now()\r\n setMetricsMessages([metricsMessage])\r\n }\r\n else {\r\n setMetricsMessages((prev) => {\r\n while (prev.length>kwirthMetricsOptionsRef.current.depth) {\r\n prev.splice(0,1)\r\n }\r\n if (paused.current)\r\n return prev\r\n else\r\n return [ ...prev, metricsMessage ]\r\n })\r\n }\r\n break\r\n case InstanceMessageTypeEnum.SIGNAL:\r\n if (instanceMessage.flow === InstanceMessageFlowEnum.RESPONSE && instanceMessage.action === InstanceMessageActionEnum.START) {\r\n if (instanceMessage.instance!=='')\r\n setInstance(instanceMessage.instance)\r\n else {\r\n let signalMessage = instanceMessage as SignalMessage\r\n alertApi.post({ message: signalMessage.text, severity:'error', display:'transient' })\r\n }\r\n }\r\n else {\r\n let signalMessage = instanceMessage as SignalMessage\r\n addMessage(signalMessage.level, signalMessage.text)\r\n switch(signalMessage.level) {\r\n case SignalMessageLevelEnum.INFO:\r\n alertApi.post({ message: signalMessage.text, severity:'info', display:'transient' })\r\n break\r\n case SignalMessageLevelEnum.WARNING:\r\n alertApi.post({ message: signalMessage.text, severity:'warning', display:'transient' })\r\n break\r\n case SignalMessageLevelEnum.ERROR:\r\n alertApi.post({ message: signalMessage.text, severity:'error', display:'transient' })\r\n break\r\n default:\r\n alertApi.post({ message: signalMessage.text, severity:'success', display:'transient' })\r\n break\r\n }\r\n }\r\n break\r\n default:\r\n addMessage(SignalMessageLevelEnum.ERROR, 'Invalid message type received: ' + instanceMessage.type)\r\n alertApi.post({ message: 'Invalid message type received: ' + instanceMessage.type, severity:'error', display:'transient' })\r\n break\r\n }\r\n }\r\n \r\n const websocketOnChunk = (wsEvent:any) => {\r\n let instanceMessage:InstanceMessage\r\n try {\r\n instanceMessage = JSON.parse(wsEvent.data) as InstanceMessage\r\n }\r\n catch (err) {\r\n console.log(err)\r\n console.log(wsEvent.data)\r\n return\r\n }\r\n\r\n switch(instanceMessage.channel) {\r\n case InstanceMessageChannelEnum.METRICS:\r\n processMetricsMessage(wsEvent)\r\n break\r\n case InstanceMessageChannelEnum.OPS:\r\n let opsMessage = instanceMessage as IOpsMessageResponse\r\n if (opsMessage.data?.data) \r\n addMessage (SignalMessageLevelEnum.WARNING, 'Operations message: '+opsMessage.data.data)\r\n else\r\n addMessage (SignalMessageLevelEnum.WARNING, 'Operations message: '+JSON.stringify(opsMessage))\r\n break\r\n default:\r\n console.log('Invalid channel in message: ', instanceMessage)\r\n break\r\n }\r\n\r\n }\r\n\r\n const websocketOnOpen = (ws:WebSocket) => {\r\n let cluster=clusterValidPods.find(cluster => cluster.name===selectedClusterName)\r\n if (!cluster) {\r\n addMessage(SignalMessageLevelEnum.ERROR, 'Cluster not found')\r\n return\r\n }\r\n let pods = cluster.data.filter(p => selectedNamespaces.includes(p.namespace))\r\n if (!pods || pods.length===0) {\r\n addMessage(SignalMessageLevelEnum.ERROR, 'Pod not found')\r\n return\r\n }\r\n\r\n console.log(`WS connected`)\r\n let accessKey = cluster.accessKeys.get(InstanceConfigScopeEnum.STREAM)\r\n if (accessKey) {\r\n let containers:string[] = []\r\n if (selectedContainerNames.length>0) {\r\n for(var p of selectedPodNames) {\r\n for (var c of selectedContainerNames) {\r\n containers.push(p+'+'+c)\r\n }\r\n }\r\n }\r\n var iConfig:InstanceConfig = {\r\n channel: InstanceMessageChannelEnum.METRICS,\r\n objects: InstanceConfigObjectEnum.PODS,\r\n action: InstanceMessageActionEnum.START,\r\n flow: InstanceMessageFlowEnum.REQUEST,\r\n instance: '',\r\n accessKey: accessKeySerialize(accessKey),\r\n scope: InstanceConfigScopeEnum.STREAM,\r\n view: (selectedContainerNames.length > 0 ? InstanceConfigViewEnum.CONTAINER : InstanceConfigViewEnum.POD),\r\n namespace: selectedNamespaces.join(','),\r\n group: '',\r\n pod: selectedPodNames.join(','),\r\n container: containers.join(','),\r\n data: {\r\n mode: MetricsConfigModeEnum.STREAM,\r\n aggregate: kwirthMetricsOptionsRef.current.aggregate,\r\n metrics: selectedMetrics,\r\n interval: kwirthMetricsOptionsRef.current.interval\r\n },\r\n type: InstanceMessageTypeEnum.SIGNAL\r\n }\r\n ws.send(JSON.stringify(iConfig))\r\n }\r\n else {\r\n addMessage(SignalMessageLevelEnum.ERROR, 'AccessKey has not been obtained')\r\n return\r\n }\r\n }\r\n\r\n const startMetricsViewer = () => {\r\n let cluster=clusterValidPods.find(cluster => cluster.name===selectedClusterName)\r\n if (!cluster) {\r\n addMessage(SignalMessageLevelEnum.ERROR, 'Cluster not found')\r\n return\r\n }\r\n\r\n try {\r\n let ws = new WebSocket(cluster.url)\r\n ws.onopen = () => websocketOnOpen(ws)\r\n ws.onmessage = (event) => websocketOnChunk(event)\r\n ws.onclose = (event) => websocketOnClose(event)\r\n setWebsocket(ws)\r\n }\r\n catch (err) {\r\n addMessage(SignalMessageLevelEnum.ERROR, 'Error starting websocket')\r\n }\r\n\r\n }\r\n\r\n const websocketOnClose = (_event:any) => {\r\n console.log(`WS disconnected from remote`)\r\n setStarted(false)\r\n paused.current=false\r\n setStopped(true)\r\n }\r\n\r\n const stopMetricsViewer = () => {\r\n websocket?.close()\r\n }\r\n\r\n const onChangeOptions = (options:MetricsOptions) => {\r\n kwirthMetricsOptionsRef.current=options\r\n setRefresh(Math.random())\r\n }\r\n \r\n const actionButtons = () => {\r\n let hasStreamKey = false, hasRestartKey = false\r\n let cluster=clusterValidPods.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n hasStreamKey = Boolean(cluster.accessKeys.has(InstanceConfigScopeEnum.STREAM))\r\n hasRestartKey = Boolean(cluster.accessKeys.get(InstanceConfigScopeEnum.RESTART))\r\n }\r\n\r\n return <>\r\n { props.enableRestart &&\r\n <IconButton title='Restart' onClick={onClickRestart} disabled={selectedPodNames.length === 0 || !hasRestartKey || !websocket || !started}>\r\n <RefreshIcon />\r\n </IconButton>\r\n }\r\n <IconButton onClick={clickStart} title=\"Play\" disabled={started || !paused || selectedPodNames.length === 0 || selectedMetrics.length==0 || !hasStreamKey}>\r\n <PlayIcon />\r\n </IconButton>\r\n <IconButton onClick={clickPause} title=\"Pause\" disabled={!((started && !paused.current) && selectedPodNames.length === 0)}>\r\n <PauseIcon />\r\n </IconButton>\r\n <IconButton onClick={clickStop} title=\"Stop\" disabled={stopped || selectedPodNames.length === 0}>\r\n <StopIcon />\r\n </IconButton>\r\n </>\r\n }\r\n\r\n const onMetricsChange = (event:any) => {\r\n setSelectedMetrics(event.target.value)\r\n }\r\n\r\n const metricsSelector = () => {\r\n let disabled = selectedClusterName === '' || selectedNamespaces.length === 0\r\n return (\r\n <FormControl style={{marginLeft:16, width:'300px'}} size='small'>\r\n <Select value={selectedMetrics} MenuProps={{variant:'menu'}} multiple onChange={onMetricsChange} renderValue={(selected) => (selected as string[]).join(', ')} disabled={disabled || started}>\r\n {\r\n allMetrics.map(m => \r\n <MenuItem key={m.metric} value={m.metric} style={{marginTop:'-6px', marginBottom:'-6px'}}>\r\n <Checkbox checked={selectedMetrics.includes(m.metric)} style={{marginTop:'-6px', marginBottom:'-6px'}}/>\r\n <Typography style={{marginTop:'-6px', marginBottom:'-6px'}}>{m.metric}</Typography>\r\n </MenuItem>\r\n )\r\n }\r\n </Select>\r\n </FormControl>\r\n )\r\n }\r\n\r\n const statusButtons = (title:string) => {\r\n const show = (level:SignalMessageLevelEnum) => {\r\n setShowStatusDialog(true)\r\n setStatusLevel(level)\r\n }\r\n\r\n return (\r\n <Grid container direction='row'>\r\n <Grid item>\r\n <Typography variant='h5'>{title}</Typography>\r\n </Grid>\r\n <Grid item style={{marginTop:'-8px'}}>\r\n <IconButton title=\"info\" disabled={!statusMessages.some(m=>m.type=== InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.INFO)} onClick={() => show(SignalMessageLevelEnum.INFO)}>\r\n <InfoIcon style={{ color:statusMessages.some(m=>m.type=== InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.INFO)?'blue':'#BDBDBD'}}/>\r\n </IconButton>\r\n <IconButton title=\"warning\" disabled={!statusMessages.some(m=>m.type=== InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.WARNING)} onClick={() => show(SignalMessageLevelEnum.WARNING)} style={{marginLeft:'-16px'}}>\r\n <WarningIcon style={{ color:statusMessages.some(m=>m.type=== InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.WARNING)?'gold':'#BDBDBD'}}/>\r\n </IconButton>\r\n <IconButton title=\"error\" disabled={!statusMessages.some(m=>m.type=== InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.ERROR)} onClick={() => show(SignalMessageLevelEnum.ERROR)} style={{marginLeft:'-16px'}}>\r\n <ErrorIcon style={{ color:statusMessages.some(m=>m.type=== InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.ERROR)?'red':'#BDBDBD'}}/>\r\n </IconButton>\r\n </Grid>\r\n <Grid item>\r\n {metricsSelector()}\r\n </Grid>\r\n </Grid>\r\n )\r\n }\r\n\r\n const statusClear = (level: SignalMessageLevelEnum) => {\r\n setStatusMessages(statusMessages.filter(m=> m.level!==level))\r\n setShowStatusDialog(false)\r\n }\r\n \r\n const mergeSeries = (names:string[], series:any[]) => {\r\n if (!names || names.length===0) return []\r\n var resultSeries:any[] = []\r\n\r\n for (var i=0; i<series[0].length; i++) {\r\n var item: { [key: string]: string|number } = {}\r\n for (var j=0; j<series.length; j++ ) {\r\n if (series[j][i]) {\r\n item['timestamp'] = series[0][i].timestamp\r\n item[names[j]] = series[j][i].value\r\n }\r\n }\r\n resultSeries.push(item)\r\n }\r\n return resultSeries\r\n }\r\n\r\n const addChart = (options: MetricsOptions, metric:string, names:string[], series:any[], colour:string) => {\r\n var result = <></>\r\n var mergedSeries = mergeSeries(names, series)\r\n\r\n const renderLabel = (data:any) => {\r\n var values:any[] = series.map (s => s[data.index])\r\n var total:number =values.reduce((acc,value) => acc+value.value, 0)\r\n return <text x={data.x + data.width/3.5} y={data.y-10}>{total.toPrecision(3).replace(/0+$/, \"\")}</text>\r\n }\r\n let height=300\r\n\r\n switch (options.chart) {\r\n case 'value':\r\n height=40+series.length*80\r\n result = (\r\n <Grid direction={'row'}>\r\n {\r\n <Typography>\r\n { series.map( (serie,index) => {\r\n return (<>\r\n <Typography >\r\n {serie[serie.length-1].value}\r\n </Typography>\r\n <Typography >\r\n {names[index]}\r\n </Typography>\r\n </>)\r\n })}\r\n </Typography>\r\n }\r\n </Grid>\r\n\r\n )\r\n break\r\n case 'line':\r\n result = (\r\n <LineChart data={mergedSeries}>\r\n <CartesianGrid strokeDasharray=\"3 3\"/>\r\n <XAxis dataKey=\"timestamp\" fontSize={8}/>\r\n <YAxis />\r\n <Tooltip />\r\n <Legend/>\r\n { series.map ((_serie,index) => <Line key={index} name={names[index]} type=\"monotone\" dataKey={names[index]} stroke={series.length===1?colour:colours[index]} activeDot={{ r: 8 }} />) }\r\n </LineChart>\r\n )\r\n break\r\n case 'area':\r\n result = (\r\n <AreaChart data={mergedSeries}>\r\n <defs>\r\n {\r\n series.map( (_serie,index) => {\r\n return (\r\n <linearGradient key={index} id={`color${series.length===1?colour:colours[index]}`} x1='0' y1='0' x2='0' y2='1'>\r\n <stop offset='7%' stopColor={series.length===1?colour:colours[index]} stopOpacity={0.8}/>\r\n <stop offset='93%' stopColor={series.length===1?colour:colours[index]} stopOpacity={0}/>\r\n </linearGradient>\r\n )\r\n })\r\n }\r\n </defs>\r\n <CartesianGrid strokeDasharray=\"3 3\"/>\r\n <XAxis dataKey=\"timestamp\" fontSize={8}/>\r\n <YAxis />\r\n <Tooltip />\r\n <Legend/>\r\n { series.map ((_serie,index) => \r\n <Area key={index} name={names[index]} type=\"monotone\" {...(options.stack? {stackId:\"1\"}:{})} dataKey={names[index]} stroke={series.length===1?colour:colours[index]} fill={`url(#color${series.length===1?colour:colours[index]})`}/> )}\r\n </AreaChart>\r\n )\r\n break\r\n case 'bar':\r\n result = (\r\n <BarChart data={mergedSeries}>\r\n <CartesianGrid strokeDasharray=\"3 3\"/>\r\n <XAxis dataKey=\"timestamp\" fontSize={8}/>\r\n <YAxis />\r\n <Tooltip/>\r\n <Legend/>\r\n { series.map ((_serie,index) =>\r\n <Bar name={names[index]} {...(options.stack? {stackId:\"1\"}:{})} dataKey={names[index]} stroke={series.length===1?colour:colours[index]} fill={series.length===1?colour:colours[index]}>\r\n { index === series.length-1 && series.length > 1 ? <LabelList dataKey={names[index]} position='insideTop' content={ renderLabel }/> : null }\r\n </Bar>\r\n )}\r\n </BarChart>\r\n )\r\n break\r\n default:\r\n break\r\n }\r\n\r\n return (\r\n <Grid direction='column' style={{width:'100%', marginBottom:8}}>\r\n <Typography align='center'>{metric}</Typography>\r\n <ResponsiveContainer height={height} key={metric+JSON.stringify(names)}>\r\n {result}\r\n </ResponsiveContainer> \r\n </Grid>\r\n )\r\n }\r\n\r\n const showMetrics = (options: MetricsOptions) => {\r\n if (!metricsMessages || metricsMessages.length === 0) {\r\n if (selectedNamespaces.length === 0) \r\n return <Typography>Select namespace chip on top.</Typography>\r\n else\r\n return <>\r\n {started?<Typography>Waiting for first data, be patient...</Typography>:<Typography>Configure <b>chart options</b>, select some <b>metrics on top</b>, and <b>press PLAY</b> on top-right button to start viewing.</Typography>}\r\n </>\r\n }\r\n\r\n let data:Map<string, Map<string, { timestamp:string, value:number}[]>> = new Map()\r\n for (let metricsMessage of metricsMessages) {\r\n let ts = new Date(metricsMessage.timestamp)\r\n let timestamp = `${ts.getHours().toString().padStart(2,'0')}:${ts.getMinutes().toString().padStart(2,'0')}:${ts.getSeconds().toString().padStart(2,'0')}`\r\n for (var i=0;i<metricsMessage.assets.length;i++) {\r\n var assetName=metricsMessage.assets[i].assetName\r\n for (var metrics of metricsMessage.assets[i].values) {\r\n if (!data.has(assetName)) data.set(assetName, new Map())\r\n if (!data.get(assetName)?.has(metrics.metricName)) data.get(assetName)?.set(metrics.metricName,[])\r\n data.get(assetName)?.get(metrics.metricName)?.push({timestamp, value:metrics.metricValue})\r\n }\r\n } \r\n }\r\n\r\n let allCharts:any[] = []\r\n if (options.merge) {\r\n var assetNames=Array.from(data.keys())\r\n var firstAsset=assetNames[0]\r\n var allMetrics:string[] = Array.from(new Set(data.get(firstAsset)!.keys()))\r\n\r\n for (let metric of allMetrics) {\r\n var series = assetNames.map(an => {\r\n return data.get(an)!.get(metric)\r\n })\r\n allCharts.push(<>{addChart(options, metric, assetNames, series, '')}</>)\r\n }\r\n\r\n let rows = []\r\n for (let i = 0; i < allCharts.length; i += options.width) {\r\n rows.push(allCharts.slice(i, i + options.width))\r\n }\r\n return (<>\r\n {rows.map((row, index) => (\r\n <div key={index} style={{ display: 'flex', justifyContent: 'space-around' }}>\r\n {row}\r\n </div>\r\n ))}\r\n </>)\r\n }\r\n else {\r\n let allCharts = Array.from(data.keys()!).map( (asset, index) => {\r\n return Array.from(data.get(asset)?.keys()!).map ( metric => {\r\n var serie:any=data.get(asset)?.get(metric)!\r\n return (<>{addChart(options, metric, [asset], [serie], colours[index])}</>)\r\n })\r\n })\r\n\r\n // convert allResults (a list of charts) into a series of rows of charts\r\n let rows = []\r\n for (var resultAsset of allCharts) {\r\n for (let i = 0; i < resultAsset.length; i += options.width) {\r\n rows.push(resultAsset.slice(i, i + options.width))\r\n }\r\n }\r\n return (<>\r\n {rows.map((row, index) => (\r\n <div key={index} style={{ display: 'flex', justifyContent: 'space-around' }}>\r\n {row}\r\n </div>\r\n ))}\r\n </>)\r\n }\r\n }\r\n\r\n const onSelectObject = (namespaces:string[], podNames:string[], containerNames:string[]) => {\r\n setSelectedNamespaces(namespaces)\r\n setSelectedPodNames(podNames)\r\n setSelectedContainerNames(containerNames)\r\n }\r\n\r\n const addMessage = (level:SignalMessageLevelEnum, text:string) => {\r\n setStatusMessages ((prev) => [...prev, {\r\n level,\r\n text,\r\n type: InstanceMessageTypeEnum.SIGNAL\r\n }])\r\n }\r\n\r\n const onClickRestart = () => {\r\n // we perform a route command from channel 'metrics' to channel 'ops'\r\n let cluster=clusterValidPods.find(cluster => cluster.name===selectedClusterName)\r\n if (!cluster) {\r\n addMessage(SignalMessageLevelEnum.ERROR,'No cluster selected')\r\n return\r\n }\r\n let restartKey = cluster.accessKeys.get(InstanceConfigScopeEnum.RESTART)\r\n if (!restartKey) {\r\n addMessage(SignalMessageLevelEnum.ERROR,'No access key present')\r\n return\r\n }\r\n if (!instance) {\r\n addMessage(SignalMessageLevelEnum.ERROR,'No instance has been established')\r\n return\r\n }\r\n\r\n\r\n let pods:PodData[] = (cluster.data as PodData[]).filter(pod => selectedNamespaces.includes(pod.namespace))\r\n for (let pod of pods) {\r\n let om:IOpsMessage = {\r\n msgtype: 'opsmessage',\r\n action: InstanceMessageActionEnum.COMMAND,\r\n flow: InstanceMessageFlowEnum.IMMEDIATE,\r\n type: InstanceMessageTypeEnum.DATA,\r\n channel: InstanceMessageChannelEnum.OPS,\r\n instance: '',\r\n id: '1',\r\n accessKey: accessKeySerialize(restartKey),\r\n command: OpsCommandEnum.RESTARTPOD,\r\n namespace: pod.namespace,\r\n group: '',\r\n pod: pod.name,\r\n container: ''\r\n }\r\n let rm: IRouteMessage = {\r\n msgtype: 'routemessage',\r\n accessKey: accessKeySerialize(restartKey),\r\n destChannel: InstanceMessageChannelEnum.OPS,\r\n action: InstanceMessageActionEnum.ROUTE,\r\n flow: InstanceMessageFlowEnum.IMMEDIATE,\r\n type: InstanceMessageTypeEnum.SIGNAL,\r\n channel: InstanceMessageChannelEnum.METRICS,\r\n instance: instance,\r\n data: om\r\n }\r\n websocket?.send(JSON.stringify(rm))\r\n }\r\n }\r\n\r\n return (<>\r\n { showError!=='' && <ShowError message={showError} onClose={() => setShowError('')}/> }\r\n\r\n { loading && <Progress/> }\r\n\r\n {!isKwirthAvailable(entity) && !loading && error && (\r\n <WarningPanel title={'An error has ocurred while obtaining data from kuebernetes clusters.'} message={error?.message} />\r\n )}\r\n\r\n {!isKwirthAvailable(entity) && !loading && (\r\n <MissingAnnotationEmptyState readMoreUrl='https://github.com/jfvilas/kwirth' annotation={[ANNOTATION_BACKSTAGE_KUBERNETES_LABELID, ANNOTATION_BACKSTAGE_KUBERNETES_LABELSELECTOR]}/>\r\n )}\r\n\r\n { isKwirthAvailable(entity) && !loading && clusterValidPods && clusterValidPods.length===0 &&\r\n <ComponentNotFound error={ErrorType.NO_CLUSTERS} entity={entity}/>\r\n }\r\n\r\n { isKwirthAvailable(entity) && !loading && clusterValidPods && clusterValidPods.length>0 && clusterValidPods.reduce((sum,cluster) => sum+cluster.data.length, 0)===0 &&\r\n <ComponentNotFound error={ErrorType.NO_PODS} entity={entity}/>\r\n }\r\n\r\n { isKwirthAvailable(entity) && !loading && clusterValidPods && clusterValidPods.length>0 && clusterValidPods.reduce((sum,cluster) => sum+cluster.data.length, 0)>0 &&\r\n <Box sx={{ display: 'flex'}}>\r\n <Box sx={{ width: '200px'}}>\r\n <Grid container direction='column'>\r\n <Grid item>\r\n <Card>\r\n <ClusterList resources={clusterValidPods} selectedClusterName={selectedClusterName} onSelect={onSelectCluster}/>\r\n </Card>\r\n </Grid>\r\n <Grid item>\r\n <Card>\r\n <Options options={kwirthMetricsOptionsRef.current!} selectedNamespaces={selectedNamespaces} selectedPodNames={selectedPodNames} selectedContainerNames={selectedContainerNames} onChange={onChangeOptions} disabled={selectedNamespaces.length === 0 || paused.current}/>\r\n </Card>\r\n </Grid>\r\n </Grid>\r\n\r\n </Box>\r\n <Box sx={{ flexGrow: 1, p:1 }}>\r\n\r\n { !selectedClusterName && \r\n <img src={KwirthMetricsLogo} alt=\"No cluster selected\" style={{ left:'40%', marginTop:'10%', width:'20%', position:'relative' }} />\r\n }\r\n\r\n { selectedClusterName && <>\r\n <Card style={{marginTop:-8}}>\r\n <CardHeader\r\n title={statusButtons(selectedClusterName)}\r\n style={{marginTop:-4, marginBottom:4, flexShrink:0}}\r\n action={actionButtons()}\r\n />\r\n \r\n <Typography style={{marginLeft:16, marginBottom:4}}>\r\n <ObjectSelector cluster={clusterValidPods.find(cluster => cluster.name === selectedClusterName)!} onSelect={onSelectObject} disabled={selectedClusterName === '' || started || paused.current} selectedNamespaces={selectedNamespaces} selectedPodNames={selectedPodNames} selectedContainerNames={selectedContainerNames} scope={InstanceConfigScopeEnum.STREAM}/>\r\n </Typography>\r\n <Divider/>\r\n <CardContent style={{ overflow: 'auto' }}>\r\n { showMetrics(kwirthMetricsOptionsRef.current) }\r\n </CardContent>\r\n </Card>\r\n </>}\r\n </Box> \r\n </Box>\r\n }\r\n\r\n { showStatusDialog && <StatusLog level={statusLevel} onClose={() => setShowStatusDialog(false)} statusMessages={statusMessages} onClear={statusClear}/>}\r\n </>)\r\n}\r\n"],"names":["cluster","p","allMetrics","i","allCharts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsDa,MAAA,0BAAA,GAA6B,CAAC,KAGjC,KAAA;AACN,EAAM,MAAA,gBAAA,GAAmB,OAAO,mBAAmB,CAAA;AACnD,EAAM,MAAA,QAAA,GAAW,OAAO,WAAW,CAAA;AACnC,EAAM,MAAA,EAAE,MAAO,EAAA,GAAI,SAAU,EAAA;AAC7B,EAAA,MAAM,CAAC,gBAAkB,EAAA,mBAAmB,CAAI,GAAA,QAAA,CAA6B,EAAE,CAAA;AAC/E,EAAA,MAAM,CAAC,mBAAA,EAAqB,sBAAsB,CAAA,GAAI,SAAS,EAAE,CAAA;AACjE,EAAA,MAAM,CAAC,kBAAoB,EAAA,qBAAqB,CAAI,GAAA,QAAA,CAAmB,EAAE,CAAA;AACzE,EAAA,MAAM,CAAC,gBAAkB,EAAA,mBAAmB,CAAI,GAAA,QAAA,CAAmB,EAAE,CAAA;AACrE,EAAA,MAAM,CAAC,sBAAwB,EAAA,yBAAyB,CAAI,GAAA,QAAA,CAAmB,EAAE,CAAA;AACjF,EAAA,MAAM,CAAC,eAAiB,EAAA,kBAAkB,CAAI,GAAA,QAAA,CAAmB,EAAE,CAAA;AACnE,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,EAAE,CAAA;AAC7C,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,IAAI,CAAA;AAC3C,EAAM,MAAA,MAAA,GAAO,OAAgB,KAAK,CAAA;AAClC,EAAA,MAAM,CAAC,eAAiB,EAAA,kBAAkB,CAAI,GAAA,QAAA,CAA2B,EAAE,CAAA;AAC3E,EAAA,MAAM,CAAC,cAAgB,EAAA,iBAAiB,CAAI,GAAA,QAAA,CAAwB,EAAE,CAAA;AACtE,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,QAAoB,EAAA;AACtD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,QAAiB,EAAA;AACjD,EAAA,MAAM,0BAA0B,MAAuB,CAAA,EAAC,KAAM,EAAA,EAAA,EAAI,OAAM,CAAG,EAAA,QAAA,EAAS,EAAI,EAAA,KAAA,EAAM,QAAQ,SAAU,EAAA,KAAA,EAAO,OAAM,KAAO,EAAA,KAAA,EAAM,OAAO,CAAA;AACjJ,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAI,SAAS,KAAK,CAAA;AAC9D,EAAA,MAAM,CAAC,WAAa,EAAA,cAAc,CAAI,GAAA,QAAA,CAAiC,uBAAuB,IAAI,CAAA;AAClG,EAAA,MAAM,CAAC,cAAA,EAAgB,iBAAkB,CAAA,GAAI,SAAiB,EAAE,CAAA;AAChE,EAAA,MAAM,CAAC,QAAA,EAAS,UAAU,CAAA,GAAI,SAAS,CAAC,CAAA;AACxC,EAAM,MAAA,CAAC,UAAY,EAAA,aAAa,CAAI,GAAA,QAAA;AAAA,IACpC;AAAA,MACI,EAAC,QAAO,oCAAqC,EAAA,IAAA,EAAK,IAAG,IAAK,EAAA,EAAA,EAAG,MAAK,SAAS,EAAA;AAAA,MAC3E,EAAC,QAAO,iCAAkC,EAAA,IAAA,EAAK,IAAG,IAAK,EAAA,EAAA,EAAG,MAAK,SAAS,EAAA;AAAA,MACxE,EAAC,QAAO,sCAAuC,EAAA,IAAA,EAAK,IAAG,IAAK,EAAA,EAAA,EAAG,MAAK,SAAS,EAAA;AAAA,MAC7E,EAAC,QAAO,qCAAsC,EAAA,IAAA,EAAK,IAAG,IAAK,EAAA,EAAA,EAAG,MAAK,SAAS,EAAA;AAAA,MAC5E,EAAC,QAAO,gCAAiC,EAAA,IAAA,EAAK,IAAG,IAAK,EAAA,EAAA,EAAG,MAAK,SAAS,EAAA;AAAA,MACvE,EAAC,QAAO,+BAAgC,EAAA,IAAA,EAAK,IAAG,IAAK,EAAA,EAAA,EAAG,MAAK,SAAS;AAAA;AAC1E,GAAC;AACD,EAAA,MAAM,EAAE,OAAA,EAAS,KAAM,EAAA,GAAI,SAAW,YAAY;AAC9C,IAAA,IAAI,mBAAiB,EAAI,EAAA,iBAAA,CAAkB,MAAM,gBAAA,CAAiB,YAAY,CAAA;AAC9E,IAAI,IAAA,SAAA,GAAY,CAAC,uBAAA,CAAwB,MAAM,CAAA;AAC/C,IAAA,IAAI,KAAM,CAAA,aAAA,EAAyB,SAAA,CAAA,IAAA,CAAK,wBAAwB,OAAO,CAAA;AACvE,IAAA,IAAI,OAAO,MAAM,gBAAA,CAAiB,aAAc,CAAA,MAAA,EAAO,WAAW,SAAS,CAAA;AAC3E,IAAA,mBAAA,CAAoB,IAAI,CAAA;AAAA,GAC3B,CAAA;AAED,EAAA,MAAM,OAAU,GAAA;AAAA,IACZ,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA,SAAA;AAAA;AAAA,IACA;AAAA;AAAA,GACJ;AAEA,EAAA,MAAM,aAAa,MAAM;AACrB,IAAI,IAAA,CAAC,OAAO,OAAS,EAAA;AACjB,MAAA,kBAAA,CAAmB,EAAE,CAAA;AACrB,MAAA,UAAA,CAAW,IAAI,CAAA;AACf,MAAA,MAAA,CAAO,OAAQ,GAAA,KAAA;AACf,MAAA,UAAA,CAAW,KAAK,CAAA;AAChB,MAAmB,kBAAA,EAAA;AAAA,KAElB,MAAA;AACD,MAAA,MAAA,CAAO,OAAQ,GAAA,KAAA;AACf,MAAA,UAAA,CAAW,IAAI,CAAA;AAAA;AACnB,GACJ;AAEA,EAAA,MAAM,aAAa,MAAM;AACrB,IAAA,UAAA,CAAW,KAAK,CAAA;AAChB,IAAA,MAAA,CAAO,OAAQ,GAAA,IAAA;AAAA,GACnB;AAEA,EAAA,MAAM,YAAY,MAAM;AACpB,IAAA,UAAA,CAAW,KAAK,CAAA;AAChB,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,MAAA,CAAO,OAAQ,GAAA,KAAA;AACf,IAAkB,iBAAA,EAAA;AAAA,GACtB;AAEA,EAAM,MAAA,eAAA,GAAkB,OAAO,WAAiC,KAAA;AAC5D,IAAA,IAAI,WAAa,EAAA;AACb,MAAA,sBAAA,CAAuB,WAAW,CAAA;AAClC,MAAA,qBAAA,CAAsB,EAAE,CAAA;AACxB,MAAA,mBAAA,CAAoB,EAAE,CAAA;AACtB,MAAA,yBAAA,CAA0B,EAAE,CAAA;AAC5B,MAAA,kBAAA,CAAmB,EAAE,CAAA;AACrB,MAAA,iBAAA,CAAkB,EAAE,CAAA;AACpB,MAAU,SAAA,EAAA;AACV,MAAA,IAAI,UAAU,gBAAiB,CAAA,IAAA,CAAK,CAAAA,QAAWA,KAAAA,QAAAA,CAAQ,SAAS,WAAW,CAAA;AAC3E,MAAI,IAAA,OAAA,IAAW,QAAQ,OAAS,EAAA;AAC5B,QAAQ,OAAA,CAAA,OAAA,CAAQ,IAAM,CAAA,CAAC,CAAE,EAAA,CAAA,KAAM,CAAE,CAAA,MAAA,CAAO,UAAW,CAAA,QAAQ,CAAG,GAAA,EAAA,GAAG,CAAC,CAAA;AAClE,QAAA,aAAA,CAAc,QAAQ,OAAO,CAAA;AAAA;AACjC;AACJ,GACJ;AAEA,EAAM,MAAA,qBAAA,GAAwB,CAAC,OAAgB,KAAA;AAC3C,IAAA,IAAI,eAAkB,GAAA,IAAA,CAAK,KAAM,CAAA,OAAA,CAAQ,IAAI,CAAA;AAC7C,IAAA,QAAQ,gBAAgB,IAAM;AAAA,MAC1B,KAAK,uBAAwB,CAAA,IAAA;AACzB,QAAA,IAAI,cAAiB,GAAA,eAAA;AACrB,QAAI,IAAA,cAAA,CAAe,cAAY,CAAG,EAAA;AAC9B,UAAe,cAAA,CAAA,SAAA,GAAY,KAAK,GAAI,EAAA;AACpC,UAAmB,kBAAA,CAAA,CAAC,cAAc,CAAC,CAAA;AAAA,SAElC,MAAA;AACD,UAAA,kBAAA,CAAmB,CAAC,IAAS,KAAA;AACzB,YAAA,OAAO,IAAK,CAAA,MAAA,GAAO,uBAAwB,CAAA,OAAA,CAAQ,KAAO,EAAA;AACtD,cAAK,IAAA,CAAA,MAAA,CAAO,GAAE,CAAC,CAAA;AAAA;AAEnB,YAAA,IAAI,MAAO,CAAA,OAAA;AACP,cAAO,OAAA,IAAA;AAAA;AAEP,cAAO,OAAA,CAAE,GAAG,IAAA,EAAM,cAAe,CAAA;AAAA,WACxC,CAAA;AAAA;AAEL,QAAA;AAAA,MACJ,KAAK,uBAAwB,CAAA,MAAA;AACzB,QAAA,IAAI,gBAAgB,IAAS,KAAA,uBAAA,CAAwB,YAAY,eAAgB,CAAA,MAAA,KAAW,0BAA0B,KAAO,EAAA;AACzH,UAAA,IAAI,gBAAgB,QAAW,KAAA,EAAA;AAC3B,YAAA,WAAA,CAAY,gBAAgB,QAAQ,CAAA;AAAA,eACnC;AACD,YAAA,IAAI,aAAgB,GAAA,eAAA;AACpB,YAAS,QAAA,CAAA,IAAA,CAAK,EAAE,OAAS,EAAA,aAAA,CAAc,MAAM,QAAS,EAAA,OAAA,EAAS,OAAQ,EAAA,WAAA,EAAa,CAAA;AAAA;AACxF,SAEC,MAAA;AACD,UAAA,IAAI,aAAgB,GAAA,eAAA;AACpB,UAAW,UAAA,CAAA,aAAA,CAAc,KAAO,EAAA,aAAA,CAAc,IAAI,CAAA;AAClD,UAAA,QAAO,cAAc,KAAO;AAAA,YACxB,KAAK,sBAAuB,CAAA,IAAA;AACxB,cAAS,QAAA,CAAA,IAAA,CAAK,EAAE,OAAS,EAAA,aAAA,CAAc,MAAM,QAAS,EAAA,MAAA,EAAQ,OAAQ,EAAA,WAAA,EAAa,CAAA;AACnF,cAAA;AAAA,YACJ,KAAK,sBAAuB,CAAA,OAAA;AACxB,cAAS,QAAA,CAAA,IAAA,CAAK,EAAE,OAAS,EAAA,aAAA,CAAc,MAAM,QAAS,EAAA,SAAA,EAAW,OAAQ,EAAA,WAAA,EAAa,CAAA;AACtF,cAAA;AAAA,YACJ,KAAK,sBAAuB,CAAA,KAAA;AACxB,cAAS,QAAA,CAAA,IAAA,CAAK,EAAE,OAAS,EAAA,aAAA,CAAc,MAAM,QAAS,EAAA,OAAA,EAAS,OAAQ,EAAA,WAAA,EAAa,CAAA;AACpF,cAAA;AAAA,YACJ;AACI,cAAS,QAAA,CAAA,IAAA,CAAK,EAAE,OAAS,EAAA,aAAA,CAAc,MAAM,QAAS,EAAA,SAAA,EAAW,OAAQ,EAAA,WAAA,EAAa,CAAA;AACtF,cAAA;AAAA;AACR;AAEJ,QAAA;AAAA,MACJ;AACI,QAAA,UAAA,CAAW,sBAAuB,CAAA,KAAA,EAAO,iCAAoC,GAAA,eAAA,CAAgB,IAAI,CAAA;AACjG,QAAS,QAAA,CAAA,IAAA,CAAK,EAAE,OAAA,EAAS,iCAAoC,GAAA,eAAA,CAAgB,MAAM,QAAS,EAAA,OAAA,EAAS,OAAQ,EAAA,WAAA,EAAa,CAAA;AAC1H,QAAA;AAAA;AACR,GACJ;AAEA,EAAM,MAAA,gBAAA,GAAmB,CAAC,OAAgB,KAAA;AACtC,IAAI,IAAA,eAAA;AACJ,IAAI,IAAA;AACA,MAAkB,eAAA,GAAA,IAAA,CAAK,KAAM,CAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,aAEtC,GAAK,EAAA;AACR,MAAA,OAAA,CAAQ,IAAI,GAAG,CAAA;AACf,MAAQ,OAAA,CAAA,GAAA,CAAI,QAAQ,IAAI,CAAA;AACxB,MAAA;AAAA;AAGJ,IAAA,QAAO,gBAAgB,OAAS;AAAA,MAC5B,KAAK,0BAA2B,CAAA,OAAA;AAC5B,QAAA,qBAAA,CAAsB,OAAO,CAAA;AAC7B,QAAA;AAAA,MACJ,KAAK,0BAA2B,CAAA,GAAA;AAC5B,QAAA,IAAI,UAAa,GAAA,eAAA;AACjB,QAAA,IAAI,WAAW,IAAM,EAAA,IAAA;AACjB,UAAA,UAAA,CAAY,sBAAuB,CAAA,OAAA,EAAS,sBAAuB,GAAA,UAAA,CAAW,KAAK,IAAI,CAAA;AAAA;AAEvF,UAAA,UAAA,CAAY,uBAAuB,OAAS,EAAA,sBAAA,GAAuB,IAAK,CAAA,SAAA,CAAU,UAAU,CAAC,CAAA;AACjG,QAAA;AAAA,MACJ;AACI,QAAQ,OAAA,CAAA,GAAA,CAAI,gCAAgC,eAAe,CAAA;AAC3D,QAAA;AAAA;AACR,GAEJ;AAEA,EAAM,MAAA,eAAA,GAAkB,CAAC,EAAiB,KAAA;AACtC,IAAA,IAAI,UAAQ,gBAAiB,CAAA,IAAA,CAAK,CAAAA,QAAWA,KAAAA,QAAAA,CAAQ,SAAO,mBAAmB,CAAA;AAC/E,IAAA,IAAI,CAAC,OAAS,EAAA;AACV,MAAW,UAAA,CAAA,sBAAA,CAAuB,OAAO,mBAAmB,CAAA;AAC5D,MAAA;AAAA;AAEJ,IAAI,IAAA,IAAA,GAAO,OAAQ,CAAA,IAAA,CAAK,MAAO,CAAA,CAAAC,OAAK,kBAAmB,CAAA,QAAA,CAASA,EAAE,CAAA,SAAS,CAAC,CAAA;AAC5E,IAAA,IAAI,CAAC,IAAA,IAAQ,IAAK,CAAA,MAAA,KAAS,CAAG,EAAA;AAC1B,MAAW,UAAA,CAAA,sBAAA,CAAuB,OAAO,eAAe,CAAA;AACxD,MAAA;AAAA;AAGJ,IAAA,OAAA,CAAQ,IAAI,CAAc,YAAA,CAAA,CAAA;AAC1B,IAAA,IAAI,SAAY,GAAA,OAAA,CAAQ,UAAW,CAAA,GAAA,CAAI,wBAAwB,MAAM,CAAA;AACrE,IAAA,IAAI,SAAW,EAAA;AACX,MAAA,IAAI,aAAsB,EAAC;AAC3B,MAAI,IAAA,sBAAA,CAAuB,SAAO,CAAG,EAAA;AACjC,QAAA,KAAA,IAAQ,KAAK,gBAAkB,EAAA;AAC3B,UAAA,KAAA,IAAS,KAAK,sBAAwB,EAAA;AAClC,YAAW,UAAA,CAAA,IAAA,CAAK,CAAE,GAAA,GAAA,GAAI,CAAC,CAAA;AAAA;AAC3B;AACJ;AAEJ,MAAA,IAAI,OAAyB,GAAA;AAAA,QACzB,SAAS,0BAA2B,CAAA,OAAA;AAAA,QACpC,SAAS,wBAAyB,CAAA,IAAA;AAAA,QAClC,QAAQ,yBAA0B,CAAA,KAAA;AAAA,QAClC,MAAM,uBAAwB,CAAA,OAAA;AAAA,QAC9B,QAAU,EAAA,EAAA;AAAA,QACV,SAAA,EAAW,mBAAmB,SAAS,CAAA;AAAA,QACvC,OAAO,uBAAwB,CAAA,MAAA;AAAA,QAC/B,MAAO,sBAAuB,CAAA,MAAA,GAAS,CAAI,GAAA,sBAAA,CAAuB,YAAY,sBAAuB,CAAA,GAAA;AAAA,QACrG,SAAA,EAAW,kBAAmB,CAAA,IAAA,CAAK,GAAG,CAAA;AAAA,QACtC,KAAO,EAAA,EAAA;AAAA,QACP,GAAA,EAAK,gBAAiB,CAAA,IAAA,CAAK,GAAG,CAAA;AAAA,QAC9B,SAAA,EAAW,UAAW,CAAA,IAAA,CAAK,GAAG,CAAA;AAAA,QAC9B,IAAM,EAAA;AAAA,UACF,MAAM,qBAAsB,CAAA,MAAA;AAAA,UAC5B,SAAA,EAAW,wBAAwB,OAAQ,CAAA,SAAA;AAAA,UAC3C,OAAS,EAAA,eAAA;AAAA,UACT,QAAA,EAAU,wBAAwB,OAAQ,CAAA;AAAA,SAC9C;AAAA,QACA,MAAM,uBAAwB,CAAA;AAAA,OAClC;AACA,MAAA,EAAA,CAAG,IAAK,CAAA,IAAA,CAAK,SAAU,CAAA,OAAO,CAAC,CAAA;AAAA,KAE9B,MAAA;AACD,MAAW,UAAA,CAAA,sBAAA,CAAuB,OAAO,iCAAiC,CAAA;AAC1E,MAAA;AAAA;AACJ,GACJ;AAEA,EAAA,MAAM,qBAAqB,MAAM;AAC7B,IAAA,IAAI,UAAQ,gBAAiB,CAAA,IAAA,CAAK,CAAAD,QAAWA,KAAAA,QAAAA,CAAQ,SAAO,mBAAmB,CAAA;AAC/E,IAAA,IAAI,CAAC,OAAS,EAAA;AACV,MAAW,UAAA,CAAA,sBAAA,CAAuB,OAAO,mBAAmB,CAAA;AAC5D,MAAA;AAAA;AAGJ,IAAI,IAAA;AACA,MAAA,IAAI,EAAK,GAAA,IAAI,SAAU,CAAA,OAAA,CAAQ,GAAG,CAAA;AAClC,MAAG,EAAA,CAAA,MAAA,GAAS,MAAM,eAAA,CAAgB,EAAE,CAAA;AACpC,MAAA,EAAA,CAAG,SAAY,GAAA,CAAC,KAAU,KAAA,gBAAA,CAAiB,KAAK,CAAA;AAChD,MAAA,EAAA,CAAG,OAAU,GAAA,CAAC,KAAU,KAAA,gBAAA,CAAiB,KAAK,CAAA;AAC9C,MAAA,YAAA,CAAa,EAAE,CAAA;AAAA,aAEZ,GAAK,EAAA;AACR,MAAW,UAAA,CAAA,sBAAA,CAAuB,OAAO,0BAA0B,CAAA;AAAA;AACvE,GAEJ;AAEA,EAAM,MAAA,gBAAA,GAAmB,CAAC,MAAe,KAAA;AACvC,IAAA,OAAA,CAAQ,IAAI,CAA6B,2BAAA,CAAA,CAAA;AACzC,IAAA,UAAA,CAAW,KAAK,CAAA;AAChB,IAAA,MAAA,CAAO,OAAQ,GAAA,KAAA;AACf,IAAA,UAAA,CAAW,IAAI,CAAA;AAAA,GACjB;AAEA,EAAA,MAAM,oBAAoB,MAAM;AAC5B,IAAA,SAAA,EAAW,KAAM,EAAA;AAAA,GACrB;AAEA,EAAM,MAAA,eAAA,GAAkB,CAAC,OAA2B,KAAA;AAChD,IAAA,uBAAA,CAAwB,OAAQ,GAAA,OAAA;AAChC,IAAW,UAAA,CAAA,IAAA,CAAK,QAAQ,CAAA;AAAA,GAC5B;AAEA,EAAA,MAAM,gBAAgB,MAAM;AACxB,IAAI,IAAA,YAAA,GAAe,OAAO,aAAgB,GAAA,KAAA;AAC1C,IAAA,IAAI,UAAQ,gBAAiB,CAAA,IAAA,CAAK,CAAAA,QAAWA,KAAAA,QAAAA,CAAQ,SAAO,mBAAmB,CAAA;AAC/E,IAAA,IAAI,OAAS,EAAA;AACT,MAAA,YAAA,GAAe,QAAQ,OAAQ,CAAA,UAAA,CAAW,GAAI,CAAA,uBAAA,CAAwB,MAAM,CAAC,CAAA;AAC7E,MAAA,aAAA,GAAgB,QAAQ,OAAQ,CAAA,UAAA,CAAW,GAAI,CAAA,uBAAA,CAAwB,OAAO,CAAC,CAAA;AAAA;AAGnF,IAAA,iEACM,KAAM,CAAA,aAAA,oBACH,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,OAAM,SAAU,EAAA,OAAA,EAAS,cAAgB,EAAA,QAAA,EAAU,iBAAiB,MAAW,KAAA,CAAA,IAAK,CAAC,aAAA,IAAiB,CAAC,SAAa,IAAA,CAAC,OAC7H,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,iBAAY,CACjB,CAAA,kBAEH,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,SAAS,UAAY,EAAA,KAAA,EAAM,MAAO,EAAA,QAAA,EAAU,WAAW,CAAC,MAAA,IAAU,iBAAiB,MAAW,KAAA,CAAA,IAAK,gBAAgB,MAAQ,IAAA,CAAA,IAAK,CAAC,YAAA,EAAA,sCACxI,QAAS,EAAA,IAAA,CACd,CACA,kBAAA,KAAA,CAAA,aAAA,CAAC,cAAW,OAAS,EAAA,UAAA,EAAY,KAAM,EAAA,OAAA,EAAQ,UAAU,EAAG,OAAA,IAAW,CAAC,MAAA,CAAO,WAAY,gBAAiB,CAAA,MAAA,KAAW,CACnH,CAAA,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,eAAU,CACf,CAAA,kBACC,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,SAAS,SAAW,EAAA,KAAA,EAAM,MAAO,EAAA,QAAA,EAAU,WAAW,gBAAiB,CAAA,MAAA,KAAW,qBACzF,KAAA,CAAA,aAAA,CAAA,QAAA,EAAA,IAAS,CACd,CACJ,CAAA;AAAA,GACJ;AAEA,EAAM,MAAA,eAAA,GAAkB,CAAC,KAAc,KAAA;AACnC,IAAmB,kBAAA,CAAA,KAAA,CAAM,OAAO,KAAK,CAAA;AAAA,GACzC;AAEA,EAAA,MAAM,kBAAkB,MAAM;AAC1B,IAAA,IAAI,QAAW,GAAA,mBAAA,KAAwB,EAAM,IAAA,kBAAA,CAAmB,MAAW,KAAA,CAAA;AAC3E,IAAA,uBACK,KAAA,CAAA,aAAA,CAAA,WAAA,EAAA,EAAY,KAAO,EAAA,EAAC,YAAW,EAAI,EAAA,KAAA,EAAM,OAAO,EAAA,EAAG,MAAK,OACrD,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,MAAO,EAAA,EAAA,KAAA,EAAO,iBAAiB,SAAW,EAAA,EAAC,OAAQ,EAAA,MAAA,EAAS,EAAA,QAAA,EAAQ,IAAC,EAAA,QAAA,EAAU,iBAAiB,WAAa,EAAA,CAAC,QAAc,KAAA,QAAA,CAAsB,KAAK,IAAI,CAAA,EAAG,QAAU,EAAA,QAAA,IAAY,WAE7K,UAAW,CAAA,GAAA;AAAA,MAAI,uBACV,KAAA,CAAA,aAAA,CAAA,QAAA,EAAA,EAAS,KAAK,CAAE,CAAA,MAAA,EAAQ,OAAO,CAAE,CAAA,MAAA,EAAQ,OAAO,EAAC,SAAA,EAAU,QAAQ,YAAa,EAAA,MAAA,sBAC5E,KAAA,CAAA,aAAA,CAAA,QAAA,EAAA,EAAS,SAAS,eAAgB,CAAA,QAAA,CAAS,EAAE,MAAM,CAAA,EAAG,OAAO,EAAC,SAAA,EAAU,QAAQ,YAAa,EAAA,MAAA,IAAQ,CACtG,kBAAA,KAAA,CAAA,aAAA,CAAC,cAAW,KAAO,EAAA,EAAC,WAAU,MAAQ,EAAA,YAAA,EAAa,QAAU,EAAA,EAAA,CAAA,CAAE,MAAO,CAC1E;AAAA,KAGZ,CACJ,CAAA;AAAA,GAER;AAEA,EAAM,MAAA,aAAA,GAAgB,CAAC,KAAiB,KAAA;AACpC,IAAM,MAAA,IAAA,GAAO,CAAC,KAAiC,KAAA;AAC3C,MAAA,mBAAA,CAAoB,IAAI,CAAA;AACxB,MAAA,cAAA,CAAe,KAAK,CAAA;AAAA,KACxB;AAEA,IAAA,2CACK,IAAK,EAAA,EAAA,SAAA,EAAS,MAAC,SAAU,EAAA,KAAA,EAAA,sCACrB,IAAK,EAAA,EAAA,IAAA,EAAI,wBACL,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,SAAQ,IAAM,EAAA,EAAA,KAAM,CACpC,CACA,kBAAA,KAAA,CAAA,aAAA,CAAC,QAAK,IAAI,EAAA,IAAA,EAAC,KAAO,EAAA,EAAC,WAAU,MAAM,EAAA,EAAA,sCAC9B,UAAW,EAAA,EAAA,KAAA,EAAM,QAAO,QAAU,EAAA,CAAC,eAAe,IAAK,CAAA,CAAA,CAAA,KAAG,EAAE,IAAQ,KAAA,uBAAA,CAAwB,UAAU,CAAE,CAAA,KAAA,KAAS,uBAAuB,IAAI,CAAA,EAAG,OAAS,EAAA,MAAM,KAAK,sBAAuB,CAAA,IAAI,qBAC1L,KAAA,CAAA,aAAA,CAAA,QAAA,EAAA,EAAS,OAAO,EAAE,KAAA,EAAM,eAAe,IAAK,CAAA,CAAA,CAAA,KAAG,EAAE,IAAQ,KAAA,uBAAA,CAAwB,UAAU,CAAE,CAAA,KAAA,KAAS,uBAAuB,IAAI,CAAA,GAAE,MAAO,GAAA,SAAA,IAAW,CAC1J,CAAA,sCACC,UAAW,EAAA,EAAA,KAAA,EAAM,WAAU,QAAU,EAAA,CAAC,eAAe,IAAK,CAAA,CAAA,CAAA,KAAG,EAAE,IAAQ,KAAA,uBAAA,CAAwB,UAAU,CAAE,CAAA,KAAA,KAAS,uBAAuB,OAAO,CAAA,EAAG,OAAS,EAAA,MAAM,KAAK,sBAAuB,CAAA,OAAO,GAAG,KAAO,EAAA,EAAC,YAAW,OAAO,EAAA,EAAA,sCAChO,WAAY,EAAA,EAAA,KAAA,EAAO,EAAE,KAAM,EAAA,cAAA,CAAe,KAAK,CAAG,CAAA,KAAA,CAAA,CAAE,SAAQ,uBAAwB,CAAA,MAAA,IAAU,CAAE,CAAA,KAAA,KAAS,uBAAuB,OAAO,CAAA,GAAE,SAAO,SAAS,EAAA,EAAE,CAChK,CACA,kBAAA,KAAA,CAAA,aAAA,CAAC,cAAW,KAAM,EAAA,OAAA,EAAQ,UAAU,CAAC,cAAA,CAAe,KAAK,CAAG,CAAA,KAAA,CAAA,CAAE,SAAQ,uBAAwB,CAAA,MAAA,IAAU,CAAE,CAAA,KAAA,KAAS,uBAAuB,KAAK,CAAA,EAAG,SAAS,MAAM,IAAA,CAAK,uBAAuB,KAAK,CAAA,EAAG,OAAO,EAAC,UAAA,EAAW,SACpN,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,aAAU,KAAO,EAAA,EAAE,OAAM,cAAe,CAAA,IAAA,CAAK,OAAG,CAAE,CAAA,IAAA,KAAQ,wBAAwB,MAAU,IAAA,CAAA,CAAE,UAAS,sBAAuB,CAAA,KAAK,IAAE,KAAM,GAAA,SAAA,IAAW,CAC3J,CACJ,mBACC,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,MAAI,IACL,EAAA,EAAA,eAAA,EACL,CACJ,CAAA;AAAA,GAER;AAEA,EAAM,MAAA,WAAA,GAAc,CAAC,KAAkC,KAAA;AACnD,IAAA,iBAAA,CAAkB,eAAe,MAAO,CAAA,CAAA,CAAA,KAAI,CAAE,CAAA,KAAA,KAAQ,KAAK,CAAC,CAAA;AAC5D,IAAA,mBAAA,CAAoB,KAAK,CAAA;AAAA,GAC7B;AAEA,EAAM,MAAA,WAAA,GAAc,CAAC,KAAA,EAAgB,MAAiB,KAAA;AAClD,IAAA,IAAI,CAAC,KAAS,IAAA,KAAA,CAAM,MAAS,KAAA,CAAA,SAAU,EAAC;AACxC,IAAA,IAAI,eAAqB,EAAC;AAE1B,IAAA,KAAA,IAAS,IAAE,CAAG,EAAA,CAAA,GAAE,OAAO,CAAC,CAAA,CAAE,QAAQ,CAAK,EAAA,EAAA;AACnC,MAAA,IAAI,OAAyC,EAAC;AAC9C,MAAA,KAAA,IAAS,CAAE,GAAA,CAAA,EAAG,CAAE,GAAA,MAAA,CAAO,QAAQ,CAAM,EAAA,EAAA;AACjC,QAAA,IAAI,MAAO,CAAA,CAAC,CAAE,CAAA,CAAC,CAAG,EAAA;AACd,UAAA,IAAA,CAAK,WAAW,CAAK,GAAA,MAAA,CAAO,CAAC,CAAA,CAAE,CAAC,CAAE,CAAA,SAAA;AAClC,UAAK,IAAA,CAAA,KAAA,CAAM,CAAC,CAAC,CAAA,GAAI,OAAO,CAAC,CAAA,CAAE,CAAC,CAAE,CAAA,KAAA;AAAA;AAClC;AAEJ,MAAA,YAAA,CAAa,KAAK,IAAI,CAAA;AAAA;AAE1B,IAAO,OAAA,YAAA;AAAA,GACX;AAEA,EAAA,MAAM,WAAW,CAAC,OAAA,EAAyB,MAAe,EAAA,KAAA,EAAgB,QAAc,MAAkB,KAAA;AACtG,IAAA,IAAI,yBAAW,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,CAAA;AACf,IAAI,IAAA,YAAA,GAAe,WAAY,CAAA,KAAA,EAAO,MAAM,CAAA;AAE5C,IAAM,MAAA,WAAA,GAAc,CAAC,IAAa,KAAA;AAC9B,MAAA,IAAI,SAAe,MAAO,CAAA,GAAA,CAAK,OAAK,CAAE,CAAA,IAAA,CAAK,KAAK,CAAC,CAAA;AACjD,MAAI,IAAA,KAAA,GAAc,OAAO,MAAO,CAAA,CAAC,KAAI,KAAU,KAAA,GAAA,GAAI,KAAM,CAAA,KAAA,EAAO,CAAC,CAAA;AACjE,MAAA,2CAAQ,MAAK,EAAA,EAAA,CAAA,EAAG,KAAK,CAAI,GAAA,IAAA,CAAK,QAAM,GAAK,EAAA,CAAA,EAAG,KAAK,CAAE,GAAA,EAAA,EAAA,EAAK,MAAM,WAAY,CAAA,CAAC,EAAE,OAAQ,CAAA,KAAA,EAAO,EAAE,CAAE,CAAA;AAAA,KACpG;AACA,IAAA,IAAI,MAAO,GAAA,GAAA;AAEX,IAAA,QAAQ,QAAQ,KAAO;AAAA,MACnB,KAAK,OAAA;AACD,QAAO,MAAA,GAAA,EAAA,GAAG,OAAO,MAAO,GAAA,EAAA;AACxB,QACI,MAAA,mBAAA,KAAA,CAAA,aAAA,CAAC,IAAK,EAAA,EAAA,SAAA,EAAW,KAET,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,kBACK,MAAO,CAAA,GAAA,CAAK,CAAC,KAAA,EAAM,KAAU,KAAA;AAC3B,UAAA,uBACI,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,UACI,EAAA,IAAA,EAAA,KAAA,CAAM,MAAM,MAAO,GAAA,CAAC,CAAE,CAAA,KAC3B,mBACC,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,IAAA,EACI,KAAM,CAAA,KAAK,CAChB,CACJ,CAAA;AAAA,SACH,CACL,CAER,CAAA;AAGJ,QAAA;AAAA,MACJ,KAAK,MAAA;AACD,QACI,MAAA,mBAAA,KAAA,CAAA,aAAA,CAAC,SAAU,EAAA,EAAA,IAAA,EAAM,YACb,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,aAAc,EAAA,EAAA,eAAA,EAAgB,KAAK,EAAA,CAAA,kBACnC,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAM,OAAQ,EAAA,WAAA,EAAY,QAAU,EAAA,CAAA,EAAE,CACvC,kBAAA,KAAA,CAAA,aAAA,CAAC,KAAM,EAAA,IAAA,CAAA,kBACN,KAAA,CAAA,aAAA,CAAA,OAAA,EAAA,IAAQ,CACT,kBAAA,KAAA,CAAA,aAAA,CAAC,MAAM,EAAA,IAAA,CAAA,EACL,MAAO,CAAA,GAAA,CAAK,CAAC,MAAA,EAAO,0BAAW,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,GAAK,EAAA,KAAA,EAAO,IAAM,EAAA,KAAA,CAAM,KAAK,CAAA,EAAG,IAAK,EAAA,UAAA,EAAW,OAAS,EAAA,KAAA,CAAM,KAAK,CAAA,EAAG,MAAQ,EAAA,MAAA,CAAO,MAAS,KAAA,CAAA,GAAE,MAAO,GAAA,OAAA,CAAQ,KAAK,CAAA,EAAG,SAAW,EAAA,EAAE,CAAG,EAAA,CAAA,EAAK,EAAA,CAAE,CACzL,CAAA;AAEJ,QAAA;AAAA,MACJ,KAAK,MAAA;AACD,QACI,MAAA,mBAAA,KAAA,CAAA,aAAA,CAAC,SAAU,EAAA,EAAA,IAAA,EAAM,YACb,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,cAEO,MAAO,CAAA,GAAA,CAAK,CAAC,MAAA,EAAO,KAAU,KAAA;AAC1B,UACI,uBAAA,KAAA,CAAA,aAAA,CAAC,oBAAe,GAAK,EAAA,KAAA,EAAO,IAAI,CAAQ,KAAA,EAAA,MAAA,CAAO,MAAS,KAAA,CAAA,GAAE,MAAO,GAAA,OAAA,CAAQ,KAAK,CAAC,CAAA,CAAA,EAAI,EAAG,EAAA,GAAA,EAAI,EAAG,EAAA,GAAA,EAAI,IAAG,GAAI,EAAA,EAAA,EAAG,GACvG,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,MAAK,EAAA,EAAA,MAAA,EAAO,MAAK,SAAW,EAAA,MAAA,CAAO,MAAS,KAAA,CAAA,GAAE,MAAO,GAAA,OAAA,CAAQ,KAAK,CAAG,EAAA,WAAA,EAAa,GAAI,EAAA,CAAA,kBACtF,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA,EAAK,QAAO,KAAM,EAAA,SAAA,EAAW,MAAO,CAAA,MAAA,KAAS,CAAE,GAAA,MAAA,GAAO,QAAQ,KAAK,CAAA,EAAG,WAAa,EAAA,CAAA,EAAE,CAC1F,CAAA;AAAA,SAEP,CAET,CACA,kBAAA,KAAA,CAAA,aAAA,CAAC,iBAAc,eAAgB,EAAA,KAAA,EAAK,CACpC,kBAAA,KAAA,CAAA,aAAA,CAAC,KAAM,EAAA,EAAA,OAAA,EAAQ,WAAY,EAAA,QAAA,EAAU,GAAE,CACvC,kBAAA,KAAA,CAAA,aAAA,CAAC,KAAM,EAAA,IAAA,CAAA,kBACN,KAAA,CAAA,aAAA,CAAA,OAAA,EAAA,IAAQ,CACT,kBAAA,KAAA,CAAA,aAAA,CAAC,YAAM,CACL,EAAA,MAAA,CAAO,GAAK,CAAA,CAAC,QAAO,KAClB,qBAAA,KAAA,CAAA,aAAA,CAAC,IAAK,EAAA,EAAA,GAAA,EAAK,OAAO,IAAM,EAAA,KAAA,CAAM,KAAK,CAAA,EAAG,IAAK,EAAA,UAAA,EAAY,GAAI,OAAA,CAAQ,QAAO,EAAC,OAAA,EAAQ,GAAG,EAAA,GAAE,EAAK,EAAA,OAAA,EAAS,KAAM,CAAA,KAAK,GAAG,MAAQ,EAAA,MAAA,CAAO,MAAS,KAAA,CAAA,GAAE,MAAO,GAAA,OAAA,CAAQ,KAAK,CAAA,EAAG,MAAM,CAAa,UAAA,EAAA,MAAA,CAAO,MAAS,KAAA,CAAA,GAAE,SAAO,OAAQ,CAAA,KAAK,CAAC,CAAA,CAAA,CAAA,EAAI,CAAG,CAC9O,CAAA;AAEJ,QAAA;AAAA,MACJ,KAAK,KAAA;AACD,QACI,MAAA,mBAAA,KAAA,CAAA,aAAA,CAAC,QAAS,EAAA,EAAA,IAAA,EAAM,YACZ,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,iBAAc,eAAgB,EAAA,KAAA,EAAK,CACpC,kBAAA,KAAA,CAAA,aAAA,CAAC,KAAM,EAAA,EAAA,OAAA,EAAQ,aAAY,QAAU,EAAA,CAAA,EAAE,CACvC,kBAAA,KAAA,CAAA,aAAA,CAAC,KAAM,EAAA,IAAA,CAAA,kBACN,KAAA,CAAA,aAAA,CAAA,OAAA,EAAA,IAAO,CACR,kBAAA,KAAA,CAAA,aAAA,CAAC,MAAM,EAAA,IAAA,CAAA,EACL,MAAO,CAAA,GAAA;AAAA,UAAK,CAAC,MAAO,EAAA,KAAA,qBACjB,KAAA,CAAA,aAAA,CAAA,GAAA,EAAA,EAAI,IAAM,EAAA,KAAA,CAAM,KAAK,CAAA,EAAI,GAAI,OAAA,CAAQ,KAAO,GAAA,EAAC,SAAQ,GAAG,EAAA,GAAE,EAAC,EAAI,OAAS,EAAA,KAAA,CAAM,KAAK,CAAA,EAAG,MAAQ,EAAA,MAAA,CAAO,MAAS,KAAA,CAAA,GAAE,MAAO,GAAA,OAAA,CAAQ,KAAK,CAAG,EAAA,IAAA,EAAM,MAAO,CAAA,MAAA,KAAS,CAAE,GAAA,MAAA,GAAO,OAAQ,CAAA,KAAK,CAC9K,EAAA,EAAA,KAAA,KAAU,MAAO,CAAA,MAAA,GAAO,CAAK,IAAA,MAAA,CAAO,SAAS,CAAI,mBAAA,KAAA,CAAA,aAAA,CAAC,SAAU,EAAA,EAAA,OAAA,EAAS,KAAM,CAAA,KAAK,CAAG,EAAA,QAAA,EAAS,WAAY,EAAA,OAAA,EAAU,WAAa,EAAA,CAAA,GAAK,IAC1I;AAAA,SAER,CAAA;AAEJ,QAAA;AAEA;AAGR,IACI,uBAAA,KAAA,CAAA,aAAA,CAAC,IAAK,EAAA,EAAA,SAAA,EAAU,QAAS,EAAA,KAAA,EAAO,EAAC,KAAA,EAAM,MAAQ,EAAA,YAAA,EAAa,CAAC,EAAA,EAAA,kBACxD,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,KAAM,EAAA,QAAA,EAAA,EAAU,MAAO,CAAA,kBAClC,KAAA,CAAA,aAAA,CAAA,mBAAA,EAAA,EAAoB,MAAgB,EAAA,GAAA,EAAK,MAAO,GAAA,IAAA,CAAK,SAAU,CAAA,KAAK,CAChE,EAAA,EAAA,MACL,CACJ,CAAA;AAAA,GAER;AAEA,EAAM,MAAA,WAAA,GAAc,CAAC,OAA4B,KAAA;AAC7C,IAAA,IAAI,CAAC,eAAA,IAAmB,eAAgB,CAAA,MAAA,KAAW,CAAG,EAAA;AAClD,MAAA,IAAI,mBAAmB,MAAW,KAAA,CAAA;AAC9B,QAAO,uBAAA,KAAA,CAAA,aAAA,CAAC,kBAAW,+BAA6B,CAAA;AAAA;AAEhD,QAAO,uBAAA,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,EACF,OAAQ,mBAAA,KAAA,CAAA,aAAA,CAAC,UAAW,EAAA,IAAA,EAAA,uCAAqC,oBAAe,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,IAAA,EAAW,YAAU,kBAAA,KAAA,CAAA,aAAA,CAAC,GAAE,EAAA,IAAA,EAAA,eAAa,GAAI,gBAAc,kBAAA,KAAA,CAAA,aAAA,CAAC,GAAE,EAAA,IAAA,EAAA,gBAAc,CAAI,EAAA,QAAA,sCAAO,GAAE,EAAA,IAAA,EAAA,YAAU,CAAI,EAAA,wCAAsC,CACtN,CAAA;AAAA;AAGR,IAAI,IAAA,IAAA,uBAAyE,GAAI,EAAA;AACjF,IAAA,KAAA,IAAS,kBAAkB,eAAiB,EAAA;AACxC,MAAA,IAAI,EAAK,GAAA,IAAI,IAAK,CAAA,cAAA,CAAe,SAAS,CAAA;AAC1C,MAAA,IAAI,SAAY,GAAA,CAAA,EAAG,EAAG,CAAA,QAAA,EAAW,CAAA,QAAA,EAAW,CAAA,QAAA,CAAS,CAAE,EAAA,GAAG,CAAC,CAAA,CAAA,EAAI,GAAG,UAAW,EAAA,CAAE,QAAS,EAAA,CAAE,QAAS,CAAA,CAAA,EAAE,GAAG,CAAC,CAAI,CAAA,EAAA,EAAA,CAAG,UAAW,EAAA,CAAE,QAAS,EAAA,CAAE,QAAS,CAAA,CAAA,EAAE,GAAG,CAAC,CAAA,CAAA;AACvJ,MAAA,KAAA,IAAS,IAAE,CAAE,EAAA,CAAA,GAAE,cAAe,CAAA,MAAA,CAAO,QAAO,CAAK,EAAA,EAAA;AAC7C,QAAA,IAAI,SAAU,GAAA,cAAA,CAAe,MAAO,CAAA,CAAC,CAAE,CAAA,SAAA;AACvC,QAAA,KAAA,IAAS,OAAW,IAAA,cAAA,CAAe,MAAO,CAAA,CAAC,EAAE,MAAQ,EAAA;AACjD,UAAI,IAAA,CAAC,IAAK,CAAA,GAAA,CAAI,SAAS,CAAA,OAAQ,GAAI,CAAA,SAAA,kBAAe,IAAA,GAAA,EAAK,CAAA;AACvD,UAAA,IAAI,CAAC,IAAK,CAAA,GAAA,CAAI,SAAS,CAAA,EAAG,IAAI,OAAQ,CAAA,UAAU,CAAG,EAAA,IAAA,CAAK,IAAI,SAAS,CAAA,EAAG,IAAI,OAAQ,CAAA,UAAA,EAAW,EAAE,CAAA;AACjG,UAAA,IAAA,CAAK,GAAI,CAAA,SAAS,CAAG,EAAA,GAAA,CAAI,OAAQ,CAAA,UAAU,CAAG,EAAA,IAAA,CAAK,EAAC,SAAA,EAAW,KAAM,EAAA,OAAA,CAAQ,aAAY,CAAA;AAAA;AAC7F;AACJ;AAGJ,IAAA,IAAI,YAAkB,EAAC;AACvB,IAAA,IAAI,QAAQ,KAAO,EAAA;AACf,MAAA,IAAI,UAAW,GAAA,KAAA,CAAM,IAAK,CAAA,IAAA,CAAK,MAAM,CAAA;AACrC,MAAI,IAAA,UAAA,GAAW,WAAW,CAAC,CAAA;AAC3B,MAAIE,IAAAA,WAAAA,GAAsB,KAAM,CAAA,IAAA,CAAK,IAAI,GAAA,CAAI,IAAK,CAAA,GAAA,CAAI,UAAU,CAAA,CAAG,IAAK,EAAC,CAAC,CAAA;AAE1E,MAAA,KAAA,IAAS,UAAUA,WAAY,EAAA;AAC3B,QAAI,IAAA,MAAA,GAAS,UAAW,CAAA,GAAA,CAAI,CAAM,EAAA,KAAA;AAC9B,UAAA,OAAO,IAAK,CAAA,GAAA,CAAI,EAAE,CAAA,CAAG,IAAI,MAAM,CAAA;AAAA,SAClC,CAAA;AACD,QAAU,SAAA,CAAA,IAAA,2DAAQ,QAAS,CAAA,OAAA,EAAS,QAAQ,UAAY,EAAA,MAAA,EAAQ,EAAE,CAAE,CAAG,CAAA;AAAA;AAG3E,MAAA,IAAI,OAAO,EAAC;AACZ,MAAA,KAAA,IAASC,KAAI,CAAGA,EAAAA,EAAAA,GAAI,UAAU,MAAQA,EAAAA,EAAAA,IAAK,QAAQ,KAAO,EAAA;AACtD,QAAA,IAAA,CAAK,KAAK,SAAU,CAAA,KAAA,CAAMA,IAAGA,EAAI,GAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA;AAEnD,MAAA,iEACK,IAAK,CAAA,GAAA,CAAI,CAAC,GAAK,EAAA,KAAA,yCACX,KAAI,EAAA,EAAA,GAAA,EAAK,OAAO,KAAO,EAAA,EAAE,SAAS,MAAQ,EAAA,cAAA,EAAgB,gBACtD,EAAA,EAAA,GACL,CACH,CACL,CAAA;AAAA,KAEC,MAAA;AACD,MAAIC,IAAAA,UAAAA,GAAY,KAAM,CAAA,IAAA,CAAK,IAAK,CAAA,IAAA,EAAO,CAAE,CAAA,GAAA,CAAK,CAAC,KAAA,EAAO,KAAY,KAAA;AAC9D,QAAO,OAAA,KAAA,CAAM,IAAK,CAAA,IAAA,CAAK,GAAI,CAAA,KAAK,GAAG,IAAK,EAAE,CAAE,CAAA,GAAA,CAAM,CAAU,MAAA,KAAA;AACxD,UAAA,IAAI,QAAU,IAAK,CAAA,GAAA,CAAI,KAAK,CAAA,EAAG,IAAI,MAAM,CAAA;AACzC,UAAA,uBAAW,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,EAAA,QAAA,CAAS,OAAS,EAAA,MAAA,EAAQ,CAAC,KAAK,CAAG,EAAA,CAAC,KAAK,CAAA,EAAG,OAAQ,CAAA,KAAK,CAAC,CAAE,CAAA;AAAA,SAC1E,CAAA;AAAA,OACJ,CAAA;AAGD,MAAA,IAAI,OAAO,EAAC;AACZ,MAAA,KAAA,IAAS,eAAeA,UAAW,EAAA;AAC/B,QAAA,KAAA,IAASD,KAAI,CAAGA,EAAAA,EAAAA,GAAI,YAAY,MAAQA,EAAAA,EAAAA,IAAK,QAAQ,KAAO,EAAA;AACxD,UAAA,IAAA,CAAK,KAAK,WAAY,CAAA,KAAA,CAAMA,IAAGA,EAAI,GAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA;AACrD;AAEJ,MAAA,iEACK,IAAK,CAAA,GAAA,CAAI,CAAC,GAAK,EAAA,KAAA,yCACX,KAAI,EAAA,EAAA,GAAA,EAAK,OAAO,KAAO,EAAA,EAAE,SAAS,MAAQ,EAAA,cAAA,EAAgB,gBACtD,EAAA,EAAA,GACL,CACH,CACL,CAAA;AAAA;AACJ,GACJ;AAEA,EAAA,MAAM,cAAiB,GAAA,CAAC,UAAqB,EAAA,QAAA,EAAmB,cAA4B,KAAA;AACxF,IAAA,qBAAA,CAAsB,UAAU,CAAA;AAChC,IAAA,mBAAA,CAAoB,QAAQ,CAAA;AAC5B,IAAA,yBAAA,CAA0B,cAAc,CAAA;AAAA,GAC5C;AAEA,EAAM,MAAA,UAAA,GAAa,CAAC,KAAA,EAA8B,IAAgB,KAAA;AAC9D,IAAA,iBAAA,CAAmB,CAAC,IAAA,KAAS,CAAC,GAAG,IAAM,EAAA;AAAA,MACnC,KAAA;AAAA,MACA,IAAA;AAAA,MACA,MAAM,uBAAwB,CAAA;AAAA,KACjC,CAAC,CAAA;AAAA,GACN;AAEA,EAAA,MAAM,iBAAiB,MAAM;AAEzB,IAAA,IAAI,UAAQ,gBAAiB,CAAA,IAAA,CAAK,CAAAH,QAAWA,KAAAA,QAAAA,CAAQ,SAAO,mBAAmB,CAAA;AAC/E,IAAA,IAAI,CAAC,OAAS,EAAA;AACV,MAAW,UAAA,CAAA,sBAAA,CAAuB,OAAM,qBAAqB,CAAA;AAC7D,MAAA;AAAA;AAEJ,IAAA,IAAI,UAAa,GAAA,OAAA,CAAQ,UAAW,CAAA,GAAA,CAAI,wBAAwB,OAAO,CAAA;AACvE,IAAA,IAAI,CAAC,UAAY,EAAA;AACb,MAAW,UAAA,CAAA,sBAAA,CAAuB,OAAM,uBAAuB,CAAA;AAC/D,MAAA;AAAA;AAEJ,IAAA,IAAI,CAAC,QAAU,EAAA;AACX,MAAW,UAAA,CAAA,sBAAA,CAAuB,OAAM,kCAAkC,CAAA;AAC1E,MAAA;AAAA;AAIJ,IAAI,IAAA,IAAA,GAAkB,QAAQ,IAAmB,CAAA,MAAA,CAAO,SAAO,kBAAmB,CAAA,QAAA,CAAS,GAAI,CAAA,SAAS,CAAC,CAAA;AACzG,IAAA,KAAA,IAAS,OAAO,IAAM,EAAA;AAClB,MAAA,IAAI,EAAiB,GAAA;AAAA,QACjB,OAAS,EAAA,YAAA;AAAA,QACT,QAAQ,yBAA0B,CAAA,OAAA;AAAA,QAClC,MAAM,uBAAwB,CAAA,SAAA;AAAA,QAC9B,MAAM,uBAAwB,CAAA,IAAA;AAAA,QAC9B,SAAS,0BAA2B,CAAA,GAAA;AAAA,QACpC,QAAU,EAAA,EAAA;AAAA,QACV,EAAI,EAAA,GAAA;AAAA,QACJ,SAAA,EAAW,mBAAmB,UAAU,CAAA;AAAA,QACxC,SAAS,cAAe,CAAA,UAAA;AAAA,QACxB,WAAW,GAAI,CAAA,SAAA;AAAA,QACf,KAAO,EAAA,EAAA;AAAA,QACP,KAAK,GAAI,CAAA,IAAA;AAAA,QACT,SAAW,EAAA;AAAA,OACf;AACA,MAAA,IAAI,EAAoB,GAAA;AAAA,QACpB,OAAS,EAAA,cAAA;AAAA,QACT,SAAA,EAAW,mBAAmB,UAAU,CAAA;AAAA,QACxC,aAAa,0BAA2B,CAAA,GAAA;AAAA,QACxC,QAAQ,yBAA0B,CAAA,KAAA;AAAA,QAClC,MAAM,uBAAwB,CAAA,SAAA;AAAA,QAC9B,MAAM,uBAAwB,CAAA,MAAA;AAAA,QAC9B,SAAS,0BAA2B,CAAA,OAAA;AAAA,QACpC,QAAA;AAAA,QACA,IAAM,EAAA;AAAA,OACV;AACA,MAAA,SAAA,EAAW,IAAK,CAAA,IAAA,CAAK,SAAU,CAAA,EAAE,CAAC,CAAA;AAAA;AACtC,GACJ;AAEA,EAAQ,uBAAA,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,EACF,cAAY,EAAM,oBAAA,KAAA,CAAA,aAAA,CAAC,aAAU,OAAS,EAAA,SAAA,EAAW,OAAS,EAAA,MAAM,YAAa,CAAA,EAAE,GAAE,CAEjF,EAAA,OAAA,oBAAY,KAAA,CAAA,aAAA,CAAA,QAAA,EAAA,IAAQ,CAErB,EAAA,CAAC,kBAAkB,MAAM,CAAA,IAAK,CAAC,OAAA,IAAW,KACvC,oBAAA,KAAA,CAAA,aAAA,CAAC,gBAAa,KAAO,EAAA,sEAAA,EAAwE,SAAS,KAAO,EAAA,OAAA,EAAS,GAGzH,CAAC,iBAAA,CAAkB,MAAM,CAAA,IAAK,CAAC,OAAA,wCAC3B,2BAA4B,EAAA,EAAA,WAAA,EAAY,mCAAoC,EAAA,UAAA,EAAY,CAAC,uCAAA,EAAyC,6CAA6C,CAAE,EAAA,CAAA,EAGpL,iBAAkB,CAAA,MAAM,CAAK,IAAA,CAAC,WAAW,gBAAoB,IAAA,gBAAA,CAAiB,WAAS,CACrF,oBAAA,KAAA,CAAA,aAAA,CAAC,qBAAkB,KAAO,EAAA,SAAA,CAAU,WAAa,EAAA,MAAA,EAAe,CAGlE,EAAA,iBAAA,CAAkB,MAAM,CAAK,IAAA,CAAC,OAAW,IAAA,gBAAA,IAAoB,gBAAiB,CAAA,MAAA,GAAO,KAAK,gBAAiB,CAAA,MAAA,CAAO,CAAC,GAAA,EAAI,OAAY,KAAA,GAAA,GAAI,QAAQ,IAAK,CAAA,MAAA,EAAQ,CAAC,CAAI,KAAA,CAAA,wCAC9J,iBAAkB,EAAA,EAAA,KAAA,EAAO,SAAU,CAAA,OAAA,EAAS,MAAe,EAAA,CAAA,EAG9D,kBAAkB,MAAM,CAAA,IAAK,CAAC,OAAA,IAAW,gBAAoB,IAAA,gBAAA,CAAiB,SAAO,CAAK,IAAA,gBAAA,CAAiB,MAAO,CAAA,CAAC,GAAI,EAAA,OAAA,KAAY,MAAI,OAAQ,CAAA,IAAA,CAAK,QAAQ,CAAC,CAAA,GAAE,qBAC5J,KAAA,CAAA,aAAA,CAAA,GAAA,EAAA,EAAI,EAAI,EAAA,EAAE,OAAS,EAAA,MAAA,sBACf,KAAA,CAAA,aAAA,CAAA,GAAA,EAAA,EAAI,EAAI,EAAA,EAAE,KAAO,EAAA,OAAA,sBACb,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,SAAS,EAAA,IAAA,EAAC,SAAU,EAAA,QAAA,EAAA,sCACrB,IAAK,EAAA,EAAA,IAAA,EAAI,wBACL,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,IAAA,sCACI,WAAY,EAAA,EAAA,SAAA,EAAW,gBAAkB,EAAA,mBAAA,EAA0C,QAAU,EAAA,eAAA,EAAgB,CAClH,CACJ,CAAA,kBACC,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,IAAI,EAAA,IAAA,EAAA,sCACL,IACG,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,OAAQ,EAAA,EAAA,OAAA,EAAS,uBAAwB,CAAA,OAAA,EAAU,oBAAwC,gBAAoC,EAAA,sBAAA,EAAgD,UAAU,eAAiB,EAAA,QAAA,EAAU,mBAAmB,MAAW,KAAA,CAAA,IAAK,MAAO,CAAA,OAAA,EAAQ,CAC3Q,CACJ,CACJ,CAEJ,CAAA,kBACC,KAAA,CAAA,aAAA,CAAA,GAAA,EAAA,EAAI,EAAI,EAAA,EAAE,UAAU,CAAG,EAAA,CAAA,EAAE,CAAE,EAAA,EAAA,EAEtB,CAAC,mBAAA,wCACE,KAAI,EAAA,EAAA,GAAA,EAAK,iBAAmB,EAAA,GAAA,EAAI,qBAAsB,EAAA,KAAA,EAAO,EAAE,IAAK,EAAA,KAAA,EAAO,SAAU,EAAA,KAAA,EAAO,KAAM,EAAA,KAAA,EAAO,UAAS,UAAW,EAAA,EAAG,CAGnI,EAAA,mBAAA,oBACE,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,QAAK,KAAO,EAAA,EAAC,SAAU,EAAA,EAAA,EACpB,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACG,KAAA,EAAO,cAAc,mBAAmB,CAAA;AAAA,MACxC,OAAO,EAAC,SAAA,EAAU,IAAI,YAAa,EAAA,CAAA,EAAG,YAAW,CAAC,EAAA;AAAA,MAClD,QAAQ,aAAc;AAAA;AAAA,GAG1B,kBAAA,KAAA,CAAA,aAAA,CAAC,UAAW,EAAA,EAAA,KAAA,EAAO,EAAC,UAAW,EAAA,EAAA,EAAI,YAAa,EAAA,CAAA,EAC5C,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,cAAe,EAAA,EAAA,OAAA,EAAS,iBAAiB,IAAK,CAAA,CAAA,OAAA,KAAW,OAAQ,CAAA,IAAA,KAAS,mBAAmB,CAAA,EAAI,QAAU,EAAA,cAAA,EAAgB,UAAU,mBAAwB,KAAA,EAAA,IAAM,OAAW,IAAA,MAAA,CAAO,OAAS,EAAA,kBAAA,EAAwC,gBAAoC,EAAA,sBAAA,EAAgD,OAAO,uBAAwB,CAAA,MAAA,EAAO,CACrW,CAAA,kBACC,KAAA,CAAA,aAAA,CAAA,OAAA,EAAA,IAAO,CACR,kBAAA,KAAA,CAAA,aAAA,CAAC,eAAY,KAAO,EAAA,EAAE,QAAU,EAAA,MAAA,EAC1B,EAAA,EAAA,WAAA,CAAY,uBAAwB,CAAA,OAAO,CACjD,CACJ,CACJ,CACJ,CACJ,CAGF,EAAA,gBAAA,oBAAqB,KAAA,CAAA,aAAA,CAAA,SAAA,EAAA,EAAU,OAAO,WAAa,EAAA,OAAA,EAAS,MAAM,mBAAA,CAAoB,KAAK,CAAA,EAAG,cAAgC,EAAA,OAAA,EAAS,aAAY,CACzJ,CAAA;AACJ;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jfvilas/plugin-kwirth-metrics",
3
- "version": "0.12.5",
3
+ "version": "0.12.7",
4
4
  "description": "Frontend plugin for viewing Kubernetes resource usage (metrics) in Backstage",
5
5
  "keywords": [
6
6
  "Backstage",