@kubed.io/cdn 0.0.3 → 0.0.5
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 +33 -5
- package/dist/chunks/define-BSZoKakE.js +10 -0
- package/dist/chunks/define-BSZoKakE.js.map +1 -0
- package/dist/chunks/element-ChNBLJ5X.js +632 -0
- package/dist/chunks/element-ChNBLJ5X.js.map +1 -0
- package/dist/chunks/kd-BeZbw7cp.js +1149 -0
- package/dist/chunks/kd-BeZbw7cp.js.map +1 -0
- package/dist/chunks/scene-CUr0fSXC.js +240 -0
- package/dist/chunks/scene-CUr0fSXC.js.map +1 -0
- package/dist/k8s/elements/events.d.ts +54 -0
- package/dist/k8s/elements/object.d.ts +47 -0
- package/dist/k8s/elements/ref.d.ts +45 -0
- package/dist/k8s/events.d.ts +63 -0
- package/dist/k8s/icons.d.ts +18 -0
- package/dist/k8s/index.d.ts +13 -0
- package/dist/k8s/links.d.ts +72 -0
- package/dist/k8s/map.d.ts +114 -0
- package/dist/k8s.js +909 -0
- package/dist/k8s.js.map +1 -0
- package/dist/kd/cell.d.ts +45 -0
- package/dist/kd/element.d.ts +32 -0
- package/dist/kd/elements/bar.d.ts +33 -0
- package/dist/kd/elements/data.d.ts +27 -0
- package/dist/kd/elements/groups.d.ts +32 -0
- package/dist/kd/elements/link.d.ts +67 -0
- package/dist/kd/elements/mask.d.ts +22 -0
- package/dist/kd/elements/meter.d.ts +37 -0
- package/dist/kd/elements/pill.d.ts +15 -0
- package/dist/kd/elements/sheet.d.ts +28 -0
- package/dist/kd/elements/steps.d.ts +30 -0
- package/dist/kd/elements/table.d.ts +38 -0
- package/dist/kd/elements/tabs.d.ts +27 -0
- package/dist/kd/elements/tile.d.ts +19 -0
- package/dist/kd/helpers.d.ts +12 -0
- package/dist/kd/index.d.ts +30 -0
- package/dist/kd/parts.d.ts +15 -0
- package/dist/kd/scene.d.ts +178 -0
- package/dist/kd/theme.d.ts +2 -0
- package/dist/kd/yaml.d.ts +17 -0
- package/dist/kd.js +5 -64
- package/dist/n8n/config.d.ts +58 -0
- package/dist/n8n/fetch.d.ts +35 -0
- package/dist/n8n/history.d.ts +8 -0
- package/dist/n8n/index.d.ts +8 -0
- package/dist/n8n/metadata.d.ts +10 -0
- package/dist/n8n/mount.d.ts +29 -0
- package/dist/n8n/state.d.ts +44 -0
- package/dist/n8n/stream.d.ts +17 -0
- package/dist/n8n/styles.d.ts +1 -0
- package/dist/n8n.js +384 -0
- package/dist/n8n.js.map +1 -0
- package/dist/openapi/describe.d.ts +20 -0
- package/dist/openapi/index.d.ts +6 -0
- package/dist/openapi/model.d.ts +154 -0
- package/dist/openapi/schema.d.ts +52 -0
- package/dist/openapi.js +504 -0
- package/dist/openapi.js.map +1 -0
- package/package.json +26 -2
- package/dist/kd.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kd-BeZbw7cp.js","names":["o","t","nothing","nothing","ifDefined","nothing","ifDefined","nothing","nothing","i","r","t","s","nothing","styleMap","nothing","nothing","ifDefined","nothing","LitElement","nothing","ifDefined","i$3","b","i$2","base","A","json","E","KdElement","define","kdjson","value","registerHelpers","o$1","o","RESERVED","NUMBER","DATE","INDICATOR","CONTROL","needsQuotes","s","quote","token","isBlock","v","isLiteral","scalar","literal","chomp","lines","l","inline","gap","head","header","inner","block","item","sub","indent","out","key","yamlLines","toYaml","line","t","KdData","pre","i","n","summary","TONES","tone","fallback","tones","IMAGE","renderIcon","cls","safeHref","href","here","loc","win","m","linkUrl","link","at","cut","path","params","name","vars","k","query","runtimes","preload","rt","navigate","event","service","to","url","prefix","KdLink","d","body","title","#click","#refresh","KdPill","isEmpty","cell","renderCell","c","cellStyles","KdBar","chips","chain","group","groups","raw","data","g","a","jsonValue","parsed","CLIP","KdGroups","#tree","#pills","e","KdMask","changed","i$1","t$1","r","number","KdMeter","marks","unit","largest","scale","clamp","f","fill","KdSheet","rows","row","STATUS","glyph","KdSteps","steps","step","KdTable","cols","columns","align","col","label","pane","KdTabs","#observer","#storage","stored","selected","byLabel","panes","index","#panes","open","#index","count","#select","slots","KdTile","external"],"sources":["../../src/kd/helpers.ts","../../node_modules/lit-html/directives/if-defined.js","../../src/kd/yaml.ts","../../src/kd/elements/data.ts","../../src/kd/parts.ts","../../src/kd/elements/link.ts","../../src/kd/elements/pill.ts","../../src/kd/cell.ts","../../src/kd/elements/bar.ts","../../src/kd/elements/groups.ts","../../src/kd/elements/mask.ts","../../node_modules/lit-html/directive.js","../../node_modules/lit-html/directives/style-map.js","../../src/kd/elements/meter.ts","../../src/kd/elements/sheet.ts","../../src/kd/elements/steps.ts","../../src/kd/elements/table.ts","../../src/kd/elements/tabs.ts","../../src/kd/elements/tile.ts"],"sourcesContent":["/**\n * Data for a JSON attribute. Double-stash it so Handlebars escapes the quotes:\n * `<kd-table data=\"{{kdjson rows}}\">`. Never triple-stash JSON into an\n * attribute: one `'` in the data turns the whole tag into escaped text.\n */\nexport function kdjson(value: unknown): string {\n return JSON.stringify(value ?? null);\n}\n\ninterface Handlebars {\n registerHelper(name: string, helper: (...args: unknown[]) => unknown): void;\n}\n\n/** Registers `kdjson` on Business Text's `context.handlebars`. */\nexport function registerHelpers(handlebars: Handlebars): void {\n handlebars.registerHelper('kdjson', (value) => kdjson(value));\n}\n","import{nothing as t}from\"../lit-html.js\";\n/**\n * @license\n * Copyright 2018 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const o=o=>o??t;export{o as ifDefined};\n//# sourceMappingURL=if-defined.js.map\n","// A small YAML dumper for JSON values: block style, kubectl's layout (a list\n// sits at its key's indent), quotes only where a plain scalar would be misread.\n\n/** What a token is, for highlighting. Punctuation and indentation are `plain`. */\nexport type YamlKind = 'key' | 'str' | 'num' | 'bool' | 'null' | 'plain';\n\nexport interface YamlToken {\n kind: YamlKind;\n text: string;\n}\n\n/** One output line: its indentation (with any `- ` markers), then its tokens. */\nexport interface YamlLine {\n prefix: string;\n tokens: YamlToken[];\n}\n\nconst RESERVED = /^(~|null|true|false|yes|no|on|off|y|n)$/i;\nconst NUMBER =\n /^([-+]?(\\.\\d+|\\d[\\d_]*(\\.\\d*)?)([eE][-+]?\\d+)?|0x[0-9a-f]+|0o[0-7]+|[-+]?\\.(inf|nan)|[-+]?\\d+(:[0-5]?\\d)+(\\.\\d*)?)$/i;\nconst DATE = /^\\d{4}-\\d\\d?-\\d\\d?([Tt ]|$)/;\nconst INDICATOR = /^([,[\\]{}#&*!|>'\"%@`]|[-?:](\\s|$))/;\nconst CONTROL = /[\\u0000-\\u0008\\u000b-\\u001f\\u007f]/;\n\nfunction needsQuotes(s: string): boolean {\n return (\n s === '' ||\n RESERVED.test(s) ||\n NUMBER.test(s) ||\n DATE.test(s) ||\n INDICATOR.test(s) ||\n /^\\s|\\s$/.test(s) ||\n s.includes(': ') ||\n s.includes(' #') ||\n s.endsWith(':') ||\n s.includes('\\n') ||\n s.includes('\\t') ||\n CONTROL.test(s)\n );\n}\n\n/** A string as a YAML scalar, double-quoted (JSON's escapes are YAML's) only when it must be. */\nexport function quote(s: string): string {\n return needsQuotes(s) ? JSON.stringify(s) : s;\n}\n\nconst token = (kind: YamlKind, text: string): YamlToken => ({ kind, text });\n\nfunction isBlock(value: unknown): value is object {\n if (Array.isArray(value)) return value.length > 0;\n return value !== null && typeof value === 'object' && Object.values(value).some((v) => v !== undefined);\n}\n\nfunction isLiteral(value: unknown): value is string {\n return typeof value === 'string' && value.includes('\\n') && !CONTROL.test(value);\n}\n\nfunction scalar(value: unknown): YamlToken {\n if (value === null || value === undefined) return token('null', 'null');\n if (typeof value === 'boolean') return token('bool', String(value));\n if (typeof value === 'number' || typeof value === 'bigint') return token('num', String(value));\n if (Array.isArray(value)) return token('plain', '[]');\n if (typeof value === 'object') return token('plain', '{}');\n return token('str', quote(String(value)));\n}\n\n// A multi-line string as a literal block: `|` keeps one final newline, `|-`\n// none and `|+` all; a leading space on the first line needs the indent stated.\nfunction literal(s: string): { header: string; lines: string[] } {\n const chomp = s.endsWith('\\n') ? (s.endsWith('\\n\\n') ? '+' : '') : '-';\n const body = chomp === '-' ? s : s.slice(0, -1);\n const lines = body.split('\\n');\n const first = lines.find((l) => l !== '');\n return { header: `|${first?.startsWith(' ') ? '2' : ''}${chomp}`, lines };\n}\n\n// A scalar, an empty collection or a literal block after `head` (`key:` or nothing).\nfunction inline(prefix: string, head: YamlToken[], value: unknown, inner: string): YamlLine[] {\n const gap = head.length ? [token('plain', ' ')] : [];\n if (isLiteral(value)) {\n const { header, lines } = literal(value);\n return [\n { prefix, tokens: [...head, ...gap, token('plain', header)] },\n ...lines.map((l) => ({ prefix: l ? inner : '', tokens: [token('str', l)] })),\n ];\n }\n return [{ prefix, tokens: [...head, ...gap, scalar(value)] }];\n}\n\n// A non-empty object or array at `indent`.\nfunction block(value: object, indent: string, out: YamlLine[]): void {\n if (Array.isArray(value)) {\n for (const item of value) {\n if (isBlock(item)) {\n const sub: YamlLine[] = [];\n block(item, `${indent} `, sub);\n sub[0].prefix = `${indent}- ${sub[0].prefix.slice(indent.length + 2)}`;\n out.push(...sub);\n } else {\n out.push(...inline(`${indent}- `, [], item, `${indent} `));\n }\n }\n return;\n }\n for (const [key, item] of Object.entries(value)) {\n if (item === undefined) continue;\n const head = [token('key', quote(key)), token('plain', ':')];\n if (isBlock(item)) {\n out.push({ prefix: indent, tokens: head });\n block(item, Array.isArray(item) ? indent : `${indent} `, out);\n } else {\n out.push(...inline(indent, head, item, `${indent} `));\n }\n }\n}\n\n/** A JSON value as YAML lines of tokens, for rendering with highlighting. */\nexport function yamlLines(value: unknown): YamlLine[] {\n const out: YamlLine[] = [];\n if (isBlock(value)) block(value, '', out);\n else out.push(...inline('', [], value, ' '));\n return out;\n}\n\n/** A JSON value as YAML text. */\nexport function toYaml(value: unknown): string {\n return yamlLines(value)\n .map((line) => line.prefix + line.tokens.map((t) => t.text).join(''))\n .join('\\n');\n}\n","import { css, html, nothing } from 'lit';\n\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\nimport { yamlLines } from '../yaml';\n\n/**\n * Any JSON value as YAML. An object or array longer than `fold` lines (default\n * 10; 0 never folds) collapses under a \"{ } n keys\" / \"[ ] n items\" line.\n *\n * `<kd-data data=\"{{kdjson spec}}\" fold=\"20\">`\n */\nexport class KdData extends KdElement {\n static override properties = {\n data: { attribute: 'data', converter: json },\n fold: { type: Number },\n };\n static override styles = [\n base,\n css`\n pre {\n margin: 0;\n font-family: var(--kd-font-mono, monospace);\n font-size: 12px;\n line-height: 1.5;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n }\n .key {\n color: color-mix(in srgb, var(--kd-info, currentColor) 75%, var(--kd-text, currentColor));\n }\n .str {\n color: color-mix(in srgb, var(--kd-success, currentColor) 70%, var(--kd-text, currentColor));\n }\n .num {\n color: color-mix(in srgb, var(--kd-warning, currentColor) 55%, var(--kd-text, currentColor));\n }\n .bool,\n .null {\n color: color-mix(in srgb, var(--kd-primary, currentColor) 70%, var(--kd-text, currentColor));\n }\n summary {\n width: max-content;\n color: var(--kd-text-2, inherit);\n font-family: var(--kd-font-mono, monospace);\n font-size: 12px;\n cursor: pointer;\n list-style: none;\n }\n summary::-webkit-details-marker {\n display: none;\n }\n summary::before {\n content: '▸ ';\n }\n details[open] > summary::before {\n content: '▾ ';\n }\n details > pre {\n margin-top: 2px;\n }\n `,\n ];\n\n declare data: unknown;\n declare fold: number;\n\n constructor() {\n super();\n this.fold = 10;\n }\n\n override render() {\n const value = this.data;\n if (value === undefined) return nothing;\n const lines = yamlLines(value);\n const pre = html`<pre>${lines.map(\n (line, i) =>\n html`${i ? '\\n' : ''}${line.prefix}${line.tokens.map((t) =>\n t.kind === 'plain' ? t.text : html`<span class=${t.kind}>${t.text}</span>`,\n )}`,\n )}</pre>`;\n if (!(this.fold > 0 && lines.length > this.fold && value !== null && typeof value === 'object')) return pre;\n const n = Object.keys(value).length;\n const summary = Array.isArray(value) ? `[ ] ${n} item${n === 1 ? '' : 's'}` : `{ } ${n} key${n === 1 ? '' : 's'}`;\n return html`<details><summary>${summary}</summary>${pre}</details>`;\n }\n}\n\ndefine('kd-data', KdData);\n","// Small pieces several elements share: tones, icons and link safety.\nimport { css, html, nothing, type TemplateResult } from 'lit';\n\n/** A semantic colour. Each maps to `--kd-<tone>`; neutral is the secondary text colour. */\nexport type Tone = 'primary' | 'success' | 'warning' | 'error' | 'info' | 'neutral';\n\nconst TONES = new Set<string>(['primary', 'success', 'warning', 'error', 'info', 'neutral']);\n\n/** `value` when it names a tone, else `fallback`. */\nexport function tone(value: unknown, fallback: Tone = 'neutral'): Tone {\n return typeof value === 'string' && TONES.has(value) ? (value as Tone) : fallback;\n}\n\n/**\n * Tone classes. Each sets `--tone` (the colour), `--tone-ink` (text in that\n * colour, pulled towards the text colour so it reads on either theme) and\n * `--tone-line` (a border in that colour).\n */\nexport const tones = css`\n .primary {\n --tone: var(--kd-primary, currentColor);\n }\n .success {\n --tone: var(--kd-success, currentColor);\n }\n .warning {\n --tone: var(--kd-warning, currentColor);\n }\n .error {\n --tone: var(--kd-error, currentColor);\n }\n .info {\n --tone: var(--kd-info, currentColor);\n }\n .primary,\n .success,\n .warning,\n .error,\n .info {\n --tone-ink: color-mix(in srgb, var(--tone) 75%, var(--kd-text, currentColor));\n --tone-line: color-mix(in srgb, var(--tone) 50%, transparent);\n }\n .neutral {\n --tone: var(--kd-text-2, currentColor);\n --tone-ink: var(--kd-text-2, currentColor);\n --tone-line: var(--kd-border-strong, currentColor);\n }\n`;\n\nconst IMAGE = /^(https?:|data:image\\/|\\/|\\.\\.?\\/)/i;\n\n/** An icon that is either an image URL or a short text such as an emoji. */\nexport function renderIcon(value: string | null | undefined, cls = 'icon'): TemplateResult | typeof nothing {\n if (!value) return nothing;\n return IMAGE.test(value) ? html`<img class=${cls} src=${value} alt=\"\" />` : html`<span class=${cls}>${value}</span>`;\n}\n\n/** `href` unless it is a script or data URL, which data must never smuggle into a link. */\nexport function safeHref(href: string | null | undefined): string | undefined {\n if (href == null || href === '') return undefined;\n return /^\\s*(javascript|vbscript|data):/i.test(href) ? undefined : href;\n}\n","import { css, html } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\nimport { renderIcon, safeHref } from '../parts';\n\n/** Dashboard variables, without the `var-` prefix (one is added when missing). A list repeats the variable. */\nexport type Vars = Record<string, string | number | boolean | null | undefined | readonly (string | number | boolean)[]>;\n\nexport interface LinkData {\n /** A dashboard uid (optionally `uid/slug`, optionally followed by `?query`, as a `back` value is). */\n dashboard?: string;\n /** A plain URL, used when there is no `dashboard`. */\n href?: string;\n vars?: Vars;\n text?: string;\n /** An image URL or an emoji. */\n icon?: string;\n /** Tooltip. */\n title?: string;\n /** Pass this dashboard and its variables as `var-back`, so the target can link back. */\n back?: boolean;\n}\n\ninterface Here {\n /** Grafana's sub-path, the part of the path before `/d/`. */\n prefix: string;\n uid?: string;\n params: URLSearchParams;\n}\n\n// The current dashboard, read from the page URL. Outside a dashboard (or\n// outside Grafana) there is no uid and no time range to keep.\nfunction here(win: Window | null | undefined): Here {\n try {\n const loc = win?.location;\n const m = /^(.*?)\\/d\\/([^/?#]+)/.exec(loc?.pathname ?? '');\n return {\n prefix: m?.[1] ?? '',\n uid: m ? decodeURIComponent(m[2]) : undefined,\n params: new URLSearchParams(loc?.search ?? ''),\n };\n } catch {\n return { prefix: '', params: new URLSearchParams() };\n }\n}\n\n/**\n * The URL a link goes to: `<sub-path>/d/<dashboard>?var-k=v…` keeping the\n * current `from`/`to`, plus `var-back=<this uid>?<this page's var-* query>`\n * when `back` is set; or the plain `href`. Undefined when there is neither.\n */\nexport function linkUrl(link: LinkData, win?: Window | null): string | undefined {\n if (!link.dashboard) return safeHref(link.href);\n const at = here(win);\n const cut = link.dashboard.indexOf('?');\n const path = cut < 0 ? link.dashboard : link.dashboard.slice(0, cut);\n const params = new URLSearchParams(cut < 0 ? '' : link.dashboard.slice(cut + 1));\n for (const [name, value] of Object.entries(link.vars ?? {})) {\n if (value === null || value === undefined) continue;\n const key = name.startsWith('var-') ? name : `var-${name}`;\n params.delete(key);\n for (const v of Array.isArray(value) ? value : [value]) params.append(key, String(v));\n }\n for (const name of ['from', 'to']) {\n const value = at.params.get(name);\n if (value !== null && !params.has(name)) params.set(name, value);\n }\n if (link.back && at.uid) {\n const vars = new URLSearchParams([...at.params].filter(([k]) => k.startsWith('var-'))).toString();\n params.set('var-back', vars ? `${at.uid}?${vars}` : at.uid);\n }\n const query = params.toString();\n return `${at.prefix}/d/${path}${query ? `?${query}` : ''}`;\n}\n\ninterface Runtime {\n locationService?: { push(to: string): void };\n}\ntype GrafanaWindow = Window & { System?: { import?(id: string): Promise<unknown> } };\n\nconst runtimes = new WeakMap<Window, Runtime | null>();\n\n// Grafana turns clicks on its own links into in-app navigation, but it finds\n// the anchor from the event target, which a shadow root retargets to the host.\n// So a kd-link does it itself, through the same location service; until the\n// runtime has loaded (or outside Grafana) the browser simply follows the link.\nfunction preload(win: GrafanaWindow | null | undefined): void {\n if (!win || runtimes.has(win) || !win.System?.import) return;\n runtimes.set(win, null);\n win.System.import('@grafana/runtime').then(\n (rt) => runtimes.set(win, rt as Runtime),\n () => {},\n );\n}\n\nfunction navigate(win: Window | null | undefined, url: string, event: MouseEvent): void {\n if (!win || event.defaultPrevented || event.button !== 0) return;\n if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;\n const service = runtimes.get(win)?.locationService;\n if (!service) return;\n const to = new URL(url, win.location.href);\n if (to.origin !== win.location.origin) return;\n const { prefix } = here(win);\n const path = prefix && to.pathname.startsWith(prefix) ? to.pathname.slice(prefix.length) : to.pathname;\n event.preventDefault();\n service.push(path + to.search + to.hash);\n}\n\n/**\n * A link to a dashboard (or any URL) with an optional icon. Set `data`, or the\n * attributes of the same names (`vars` as JSON, `back` as a boolean). Without\n * `text`, the slot is the label.\n *\n * `<kd-link dashboard=\"k8s-pod\" vars='{\"pod\":\"web-0\"}' back>web-0</kd-link>`\n */\nexport class KdLink extends KdElement {\n static override properties = {\n data: { attribute: 'data', converter: json },\n dashboard: {},\n href: {},\n vars: { converter: json },\n text: {},\n icon: {},\n back: { type: Boolean },\n };\n static override styles = [\n base,\n css`\n :host {\n display: inline;\n }\n /* One line: a long name ends in an ellipsis with the full text on hover.\n A table caps links with --kd-link-max, since 100% means nothing to an\n auto-layout column. */\n a,\n span.link {\n display: inline-flex;\n align-items: baseline;\n max-width: var(--kd-link-max, 100%);\n min-width: 0;\n vertical-align: bottom;\n }\n .text {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n a {\n color: var(--kd-link, inherit);\n text-decoration: none;\n }\n a:hover {\n text-decoration: underline;\n }\n .icon {\n width: 16px;\n height: 16px;\n margin-right: 4px;\n vertical-align: -3px;\n }\n `,\n ];\n\n declare data: LinkData | undefined;\n declare dashboard: string | undefined;\n declare href: string | undefined;\n declare vars: Vars | undefined;\n declare text: string | undefined;\n declare icon: string | undefined;\n declare back: boolean | undefined;\n\n /** The link, `data` taking precedence over the attributes field by field. */\n get link(): LinkData {\n const d = this.data ?? {};\n return {\n dashboard: d.dashboard ?? this.dashboard,\n href: d.href ?? this.href,\n vars: d.vars ?? this.vars,\n text: d.text ?? this.text,\n icon: d.icon ?? this.icon,\n title: d.title,\n back: d.back ?? this.back,\n };\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n preload(this.ownerDocument?.defaultView);\n }\n\n // Variables can change without the panel re-rendering this element, so the\n // URL is rebuilt when the pointer or focus arrives and again on the click.\n #refresh = () => this.requestUpdate();\n\n #click = (event: MouseEvent) => {\n const win = this.ownerDocument?.defaultView;\n const url = linkUrl(this.link, win);\n if (url === undefined) return;\n (event.currentTarget as HTMLAnchorElement).setAttribute('href', url);\n navigate(win, url, event);\n };\n\n override render() {\n const link = this.link;\n const url = linkUrl(link, this.ownerDocument?.defaultView);\n // The text carries its full self on hover (it may be cut short); the link's\n // own title (a kind, say) shows over the icon.\n const body = html`${renderIcon(link.icon)}<span class=\"text\" title=${ifDefined(link.text)}\n ><slot>${link.text ?? ''}</slot></span\n >`;\n const title = link.title ?? link.text;\n if (url === undefined) return html`<span class=\"link\" title=${ifDefined(title)}>${body}</span>`;\n return html`<a\n href=${url}\n title=${ifDefined(title)}\n @click=${this.#click}\n @mouseenter=${this.#refresh}\n @focus=${this.#refresh}\n >${body}</a\n >`;\n }\n}\n\ndefine('kd-link', KdLink);\n","import { css, html } from 'lit';\n\nimport { define } from '../define';\nimport { KdElement, base } from '../element';\nimport { tone, tones, type Tone } from '../parts';\n\n/**\n * A pill or badge. The slot is its text; `title` is the native tooltip.\n *\n * `<kd-pill tone=\"success\" title=\"all containers ready\">Running</kd-pill>`\n */\nexport class KdPill extends KdElement {\n static override properties = { tone: {} };\n static override styles = [\n base,\n tones,\n css`\n :host {\n display: inline-block;\n margin: 1px 4px 1px 0;\n vertical-align: baseline;\n }\n span {\n display: inline-block;\n padding: 0 8px;\n border: 1px solid var(--tone-line);\n border-radius: 10px;\n background: color-mix(in srgb, var(--tone) 14%, transparent);\n color: var(--tone-ink);\n font-size: 11px;\n line-height: 18px;\n white-space: nowrap;\n }\n `,\n ];\n\n declare tone: Tone | undefined;\n\n override render() {\n return html`<span class=${tone(this.tone)}><slot></slot></span>`;\n }\n}\n\ndefine('kd-pill', KdPill);\n","// What a sheet value or a table cell may be, and how each shape renders.\nimport { css, html, nothing, type TemplateResult } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nimport './elements/data';\nimport './elements/link';\nimport './elements/pill';\nimport type { Vars } from './elements/link';\nimport type { Tone } from './parts';\n\nexport type { Tone };\n\n/** A pill: `<kd-pill>`. */\nexport interface PillCell {\n text: string;\n tone?: Tone;\n title?: string;\n}\n\n/** A plain link: `<kd-link>` with an `href`. */\nexport interface HrefCell {\n href: string;\n text: string;\n icon?: string;\n title?: string;\n}\n\n/** A dashboard link: `<kd-link>`. */\nexport interface DashboardCell {\n dashboard: string;\n vars?: Vars;\n text: string;\n icon?: string;\n title?: string;\n back?: boolean;\n}\n\n/** Any JSON value as YAML: `<kd-data>`. */\nexport interface DataCell {\n data: unknown;\n}\n\n/** Monospace text. */\nexport interface CodeCell {\n code: string;\n}\n\n/** A scalar is text; an array renders its cells inline, wrapped. */\nexport type Cell =\n | string\n | number\n | boolean\n | null\n | undefined\n | PillCell\n | HrefCell\n | DashboardCell\n | DataCell\n | CodeCell\n | Cell[];\n\n/** Whether a cell has nothing to show. */\nexport function isEmpty(cell: Cell): boolean {\n return cell === null || cell === undefined || cell === '' || (Array.isArray(cell) && cell.every(isEmpty));\n}\n\n/** One cell. An object of no known shape is shown as data. */\nexport function renderCell(cell: Cell): TemplateResult | string | typeof nothing {\n if (cell === null || cell === undefined) return nothing;\n if (Array.isArray(cell)) {\n return html`<span class=\"cells\">${cell.filter((c) => !isEmpty(c)).map((c) => html`<span>${renderCell(c)}</span>`)}</span>`;\n }\n if (typeof cell !== 'object') return String(cell);\n if ('dashboard' in cell || 'href' in cell) return html`<kd-link .data=${cell}></kd-link>`;\n if ('data' in cell) return html`<kd-data .data=${cell.data}></kd-data>`;\n if ('code' in cell) return html`<code>${String(cell.code)}</code>`;\n if ('text' in cell) {\n return html`<kd-pill tone=${ifDefined(cell.tone)} title=${ifDefined(cell.title)}>${String(cell.text)}</kd-pill>`;\n }\n return html`<kd-data .data=${cell}></kd-data>`;\n}\n\n/** Styles an element that renders cells adds to its own. */\nexport const cellStyles = css`\n .cells {\n display: inline-flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: 2px 6px;\n }\n code {\n font-family: var(--kd-font-mono, monospace);\n font-size: 12px;\n overflow-wrap: anywhere;\n }\n`;\n","import { css, html, nothing } from 'lit';\n\nimport { cellStyles, isEmpty, renderCell, type Cell } from '../cell';\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\nimport { renderIcon } from '../parts';\n\nexport interface BarData {\n /** An image URL or an emoji. */\n icon?: string;\n /** The line above the title, e.g. the kind and namespace. */\n eyebrow?: Cell;\n title: string;\n /** Pills beside the title. */\n chips?: Cell[];\n /** A breadcrumb at the far end, e.g. the owner chain. */\n chain?: Cell[];\n}\n\n/**\n * A title bar or masthead.\n *\n * `el.data = { icon: '🐘', eyebrow: 'StatefulSet', title: 'postgresql', chips: [{ text: '1/1', tone: 'success' }] }`\n */\nexport class KdBar extends KdElement {\n static override properties = { data: { attribute: 'data', converter: json } };\n static override styles = [\n base,\n cellStyles,\n css`\n .bar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px 16px;\n padding: 0 4px;\n }\n img.icon {\n width: 42px;\n height: 42px;\n }\n span.icon {\n font-size: 34px;\n line-height: 1;\n }\n .eyebrow {\n color: var(--kd-text-2, inherit);\n font-size: 11px;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n }\n .title {\n font-size: 22px;\n font-weight: 500;\n line-height: 1.2;\n overflow-wrap: anywhere;\n }\n .grow {\n flex: 1;\n }\n .chain {\n font-size: 13px;\n }\n .sep {\n margin: 0 6px;\n color: var(--kd-text-dim, inherit);\n }\n `,\n ];\n\n declare data: BarData | undefined;\n\n override render() {\n const d = this.data;\n if (!d) return nothing;\n const chips = (d.chips ?? []).filter((c) => !isEmpty(c));\n const chain = (d.chain ?? []).filter((c) => !isEmpty(c));\n return html`<div class=\"bar\">\n ${renderIcon(d.icon)}\n <div class=\"id\">\n ${isEmpty(d.eyebrow) ? nothing : html`<div class=\"eyebrow\">${renderCell(d.eyebrow)}</div>`}\n <div class=\"title\">${d.title ?? ''}</div>\n </div>\n ${chips.length ? html`<div class=\"chips\">${chips.map((c) => renderCell(c))}</div>` : nothing}\n <div class=\"grow\"></div>\n ${chain.length\n ? html`<nav class=\"chain\">\n ${chain.map((c, i) => html`${i ? html`<span class=\"sep\">›</span>` : nothing}${renderCell(c)}`)}\n </nav>`\n : nothing}\n </div>`;\n }\n}\n\ndefine('kd-bar', KdBar);\n","import { css, html, nothing } from 'lit';\n\nimport './data';\nimport './pill';\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\n\n/** A string map, such as labels or annotations. */\nexport type GroupsData = Record<string, string>;\n\ninterface Group {\n prefix: string;\n entries: { key: string; name: string; value: string }[];\n}\n\n// Grouped by the prefix before \"/\"; unprefixed keys first, then by prefix.\nfunction group(data: GroupsData): Group[] {\n const groups = new Map<string, Group>();\n for (const [key, raw] of Object.entries(data)) {\n const cut = key.indexOf('/');\n const prefix = cut < 0 ? '' : key.slice(0, cut);\n const value = raw === null || raw === undefined ? '' : typeof raw === 'string' ? raw : JSON.stringify(raw);\n let g = groups.get(prefix);\n if (!g) groups.set(prefix, (g = { prefix, entries: [] }));\n g.entries.push({ key, name: key.slice(cut + 1), value });\n }\n return [...groups.values()].sort((a, b) => (a.prefix < b.prefix ? -1 : a.prefix > b.prefix ? 1 : 0));\n}\n\n/** A value that is a JSON object or array, parsed; undefined for anything else. */\nexport function jsonValue(value: string): object | undefined {\n if (!/^\\s*[[{]/.test(value)) return undefined;\n try {\n const parsed: unknown = JSON.parse(value);\n return parsed !== null && typeof parsed === 'object' ? parsed : undefined;\n } catch {\n return undefined;\n }\n}\n\nconst CLIP = 600;\n\n/**\n * A string map grouped by key prefix: as pills (`mode=\"pills\"`, the default,\n * for labels) or as a key/value tree (`mode=\"tree\"`, for annotations, where a\n * value holding a JSON object or array is shown as folded YAML).\n *\n * `<kd-groups mode=\"tree\" data=\"{{kdjson metadata.annotations}}\">`\n */\nexport class KdGroups extends KdElement {\n static override properties = {\n data: { attribute: 'data', converter: json },\n mode: {},\n };\n static override styles = [\n base,\n css`\n .group + .group {\n margin-top: 12px;\n }\n div.head,\n tr.head td {\n padding-bottom: 3px;\n border-bottom: 1px solid var(--kd-border, transparent);\n color: var(--kd-text-2, inherit);\n font-family: var(--kd-font-mono, monospace);\n font-size: 11px;\n }\n div.head {\n margin-bottom: 6px;\n }\n table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n }\n td {\n padding: 2px 12px 2px 0;\n vertical-align: top;\n }\n tr.head td {\n padding-top: 12px;\n }\n tr.head:first-child td {\n padding-top: 0;\n }\n tr.head + tr td {\n padding-top: 6px;\n }\n .k {\n white-space: nowrap;\n }\n code {\n font-family: var(--kd-font-mono, monospace);\n font-size: 12px;\n }\n .twig {\n margin: 0 8px 0 4px;\n color: var(--kd-text-dim, inherit);\n font-family: var(--kd-font-mono, monospace);\n }\n .v {\n width: 100%;\n color: color-mix(in srgb, var(--kd-success, currentColor) 70%, var(--kd-text, currentColor));\n font-family: var(--kd-font-mono, monospace);\n font-size: 12px;\n overflow-wrap: anywhere;\n word-break: break-word;\n }\n .none {\n padding: 8px 0;\n color: var(--kd-text-dim, inherit);\n }\n `,\n ];\n\n declare data: GroupsData | undefined;\n declare mode: 'pills' | 'tree' | undefined;\n\n override render() {\n const d = this.data;\n if (!d || typeof d !== 'object') return nothing;\n const groups = group(d);\n if (!groups.length) return html`<div class=\"none\">none</div>`;\n return this.mode === 'tree' ? this.#tree(groups) : this.#pills(groups);\n }\n\n #pills(groups: Group[]) {\n return groups.map(\n (g) => html`<div class=\"group\">\n ${g.prefix ? html`<div class=\"head\">${g.prefix}</div>` : nothing}\n <div>\n ${g.entries.map(\n (e) => html`<kd-pill tone=\"info\" title=${e.key}>${e.value === '' ? e.name : `${e.name}=${e.value}`}</kd-pill>`,\n )}\n </div>\n </div>`,\n );\n }\n\n #tree(groups: Group[]) {\n return html`<table>\n <tbody>\n ${groups.map(\n (g) => html`${g.prefix ? html`<tr class=\"head\"><td colspan=\"2\">${g.prefix}</td></tr>` : nothing}\n ${g.entries.map((e, i) => {\n const parsed = jsonValue(e.value);\n return html`<tr>\n <td class=\"k\">\n ${g.prefix ? html`<span class=\"twig\">${i === g.entries.length - 1 ? '└' : '├'}</span>` : nothing}<code\n >${e.name}</code\n >\n </td>\n <td class=\"v\">\n ${parsed\n ? html`<kd-data .data=${parsed}></kd-data>`\n : e.value.length > CLIP\n ? `${e.value.slice(0, CLIP)} …`\n : e.value}\n </td>\n </tr>`;\n })}`,\n )}\n </tbody>\n </table>`;\n }\n}\n\ndefine('kd-groups', KdGroups);\n","import { css, html, type PropertyValues } from 'lit';\n\nimport { define } from '../define';\nimport { KdElement, base } from '../element';\n\n/**\n * A secret value, hidden until clicked. The value never reaches a tooltip, the\n * console or any other attribute, and the dots do not give away its length.\n *\n * `<kd-mask value=\"{{password}}\"></kd-mask>`\n */\nexport class KdMask extends KdElement {\n static override properties = { value: {}, shown: { state: true } };\n static override styles = [\n base,\n css`\n :host {\n display: inline-block;\n }\n button {\n padding: 0;\n border: none;\n background: none;\n color: inherit;\n font: inherit;\n cursor: pointer;\n }\n .dots {\n color: var(--kd-text-2, inherit);\n letter-spacing: 0.1em;\n }\n code {\n font-family: var(--kd-font-mono, monospace);\n font-size: 12px;\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n user-select: all;\n }\n .hide {\n margin-left: 6px;\n color: var(--kd-text-dim, inherit);\n }\n `,\n ];\n\n declare value: string | undefined;\n declare shown: boolean;\n\n constructor() {\n super();\n this.shown = false;\n }\n\n // A new value starts hidden again.\n protected override willUpdate(changed: PropertyValues<this>): void {\n if (changed.has('value') && changed.get('value') !== undefined) this.shown = false;\n }\n\n override render() {\n if (!this.shown) {\n return html`<button type=\"button\" aria-label=\"show\" @click=${() => (this.shown = true)}>\n <span class=\"dots\">••••••••</span>\n </button>`;\n }\n return html`<code>${this.value ?? ''}</code\n ><button type=\"button\" class=\"hide\" aria-label=\"hide\" @click=${() => (this.shown = false)}>×</button>`;\n }\n}\n\ndefine('kd-mask', KdMask);\n","/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst t={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},e=t=>(...e)=>({_$litDirective$:t,values:e});class i{constructor(t){}get _$AU(){return this._$AM._$AU}_$AT(t,e,i){this._$Ct=t,this._$AM=e,this._$Ci=i}_$AS(t,e){return this.update(t,e)}update(t,e){return this.render(...e)}}export{i as Directive,t as PartType,e as directive};\n//# sourceMappingURL=directive.js.map\n","import{noChange as t}from\"../lit-html.js\";import{directive as e,Directive as r,PartType as s}from\"../directive.js\";\n/**\n * @license\n * Copyright 2018 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const n=\"important\",i=\" !\"+n,o=e(class extends r{constructor(t){if(super(t),t.type!==s.ATTRIBUTE||\"style\"!==t.name||t.strings?.length>2)throw Error(\"The `styleMap` directive must be used in the `style` attribute and must be the only part in the attribute.\")}render(t){return Object.keys(t).reduce((e,r)=>{const s=t[r];return null==s?e:e+`${r=r.includes(\"-\")?r:r.replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g,\"-$&\").toLowerCase()}:${s};`},\"\")}update(e,[r]){const{style:s}=e.element;if(void 0===this.ft)return this.ft=new Set(Object.keys(r)),this.render(r);for(const t of this.ft)null==r[t]&&(this.ft.delete(t),t.includes(\"-\")?s.removeProperty(t):s[t]=null);for(const t in r){const e=r[t];if(null!=e){this.ft.add(t);const r=\"string\"==typeof e&&e.endsWith(i);t.includes(\"-\")||r?s.setProperty(t,r?e.slice(0,-11):e,r?n:\"\"):s[t]=e}}return t}});export{o as styleMap};\n//# sourceMappingURL=style-map.js.map\n","import { css, html, nothing } from 'lit';\nimport { styleMap } from 'lit/directives/style-map.js';\n\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\nimport { tone, tones, type Tone } from '../parts';\n\nexport interface MeterMark {\n label: string;\n value: number;\n tone?: Tone;\n}\n\nexport interface MeterData {\n /** The measured value; null or missing shows only the marks. */\n value?: number | null;\n /** The full scale; defaults to the largest of the value and the marks. */\n max?: number;\n /** Appended to every number as is, e.g. `Mi`, `m` or ` cores`. */\n unit?: string;\n marks?: MeterMark[];\n}\n\nconst number = (n: number) => new Intl.NumberFormat(undefined, { maximumFractionDigits: 2 }).format(n);\n\n/**\n * A value against request/limit-style marks. The fill takes the tone of the\n * highest toned mark it has reached, else primary.\n *\n * `el.data = { value: 412, unit: 'Mi', marks: [{ label: 'request', value: 256 }, { label: 'limit', value: 512, tone: 'error' }] }`\n */\nexport class KdMeter extends KdElement {\n static override properties = { data: { attribute: 'data', converter: json } };\n static override styles = [\n base,\n tones,\n css`\n .track {\n position: relative;\n height: 8px;\n margin: 6px 0;\n border-radius: 4px;\n background: color-mix(in srgb, var(--kd-border-strong, currentColor) 35%, transparent);\n }\n .fill {\n height: 100%;\n border-radius: 4px;\n background: var(--tone);\n }\n .mark {\n position: absolute;\n top: -3px;\n bottom: -3px;\n width: 2px;\n background: var(--tone);\n box-shadow: 0 0 0 1px var(--kd-bg, transparent);\n }\n .legend {\n display: flex;\n flex-wrap: wrap;\n gap: 2px 20px;\n font-size: 12px;\n }\n .value {\n font-family: var(--kd-font-mono, monospace);\n font-size: 14px;\n }\n .legend .mark-label {\n color: var(--kd-text-2, inherit);\n }\n .legend .num {\n color: var(--tone-ink);\n font-family: var(--kd-font-mono, monospace);\n }\n .none {\n color: var(--kd-text-dim, inherit);\n }\n `,\n ];\n\n declare data: MeterData | undefined;\n\n override render() {\n const d = this.data;\n if (!d || typeof d !== 'object') return nothing;\n const value = typeof d.value === 'number' && Number.isFinite(d.value) ? d.value : undefined;\n const marks = (d.marks ?? []).filter((m) => m && Number.isFinite(m.value));\n const unit = d.unit ?? '';\n const largest = Math.max(value ?? 0, ...marks.map((m) => m.value));\n const scale = typeof d.max === 'number' && d.max > 0 ? d.max : largest > 0 ? largest : 1;\n // A mark's left edge moves from 0 to 100% - its width, so one at the maximum stays inside.\n const clamp = (f: number) => Math.min(1, Math.max(0, f));\n const at = (n: number) => `${Math.min(100, Math.max(0, (n / scale) * 100))}%`;\n const reached = value === undefined ? [] : marks.filter((m) => m.tone && value >= m.value);\n const fill = tone(reached.sort((a, b) => b.value - a.value)[0]?.tone, 'primary');\n return html`<div\n role=\"meter\"\n aria-valuemin=\"0\"\n aria-valuemax=${scale}\n aria-valuenow=${value ?? nothing}\n >\n <div class=\"track\">\n ${value === undefined ? nothing : html`<div class=\"fill ${fill}\" style=${styleMap({ width: at(value) })}></div>`}\n ${marks.map(\n (m) =>\n html`<div\n class=\"mark ${tone(m.tone)}\"\n style=${styleMap({ left: `calc(${at(m.value)} - ${clamp(m.value / scale) * 2}px)` })}\n title=\"${m.label} ${number(m.value)}${unit}\"\n ></div>`,\n )}\n </div>\n <div class=\"legend\">\n <span class=\"value ${value === undefined ? 'none' : ''}\">${value === undefined ? '–' : `${number(value)}${unit}`}</span>\n ${marks.map(\n (m) =>\n html`<span class=${tone(m.tone)}\n ><span class=\"mark-label\">${m.label}</span> <span class=\"num\">${number(m.value)}${unit}</span></span\n >`,\n )}\n </div>\n </div>`;\n }\n}\n\ndefine('kd-meter', KdMeter);\n","import { css, html, nothing } from 'lit';\n\nimport { cellStyles, isEmpty, renderCell, type Cell } from '../cell';\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\n\nexport interface SheetRow {\n key: string;\n value: Cell;\n}\n\n/** Rows in order, or a plain object (its keys in order). */\nexport type SheetData = SheetRow[] | Record<string, Cell>;\n\n/**\n * A two-column property sheet. A row whose value is empty is left out.\n *\n * `el.data = [{ key: 'Node', value: 'node-1' }, { key: 'Phase', value: { text: 'Running', tone: 'success' } }]`\n */\nexport class KdSheet extends KdElement {\n static override properties = { data: { attribute: 'data', converter: json } };\n static override styles = [\n base,\n cellStyles,\n css`\n dl {\n display: grid;\n grid-template-columns: max-content minmax(0, 1fr);\n margin: 0;\n font-size: 13px;\n }\n dt,\n dd {\n margin: 0;\n padding: 5px 12px 5px 0;\n border-bottom: 1px solid var(--kd-border, transparent);\n }\n dt {\n color: var(--kd-text-2, inherit);\n }\n dd {\n overflow-wrap: anywhere;\n }\n `,\n ];\n\n declare data: SheetData | undefined;\n\n override render() {\n const d = this.data;\n if (!d || typeof d !== 'object') return nothing;\n const rows = Array.isArray(d) ? d : Object.entries(d).map(([key, value]) => ({ key, value }));\n return html`<dl>\n ${rows\n .filter((row) => row && !isEmpty(row.value))\n .map((row) => html`<dt>${row.key}</dt><dd>${renderCell(row.value)}</dd>`)}\n </dl>`;\n }\n}\n\ndefine('kd-sheet', KdSheet);\n","import { css, html, nothing } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\nimport { tone, tones, type Tone } from '../parts';\n\nexport type StepStatus = 'done' | 'active' | 'failed' | 'pending' | Tone;\n\nexport interface Step {\n label: string;\n status: StepStatus;\n time?: string;\n detail?: string;\n}\n\nconst STATUS: Record<string, Tone> = { done: 'success', active: 'primary', failed: 'error', pending: 'neutral' };\n\nfunction glyph(t: Tone, n: number): string {\n if (t === 'success') return '✓';\n if (t === 'error') return '✗';\n if (t === 'warning') return '!';\n return String(n);\n}\n\n/**\n * A stepper or state stripe: ordered steps, each with a status (a lifecycle\n * word or a tone), an optional time and a detail line.\n *\n * `el.data = [{ label: 'Scheduled', status: 'done', time: '2m' }, { label: 'Ready', status: 'failed', detail: 'probe failed' }]`\n */\nexport class KdSteps extends KdElement {\n static override properties = { data: { attribute: 'data', converter: json } };\n static override styles = [\n base,\n tones,\n css`\n ol {\n display: flex;\n margin: 0;\n padding: 0;\n list-style: none;\n }\n li {\n position: relative;\n flex: 1;\n min-width: 0;\n text-align: center;\n }\n li + li::before {\n content: '';\n position: absolute;\n top: 12px;\n right: 50%;\n width: 100%;\n height: 2px;\n background: var(--kd-border-strong, currentColor);\n opacity: 0.6;\n }\n li.reached::before {\n background: var(--tone);\n opacity: 1;\n }\n .dot {\n position: relative;\n z-index: 1;\n width: 26px;\n height: 26px;\n margin: 0 auto;\n border-radius: 50%;\n background: var(--tone);\n color: var(--kd-bg, inherit);\n font-size: 13px;\n font-weight: 700;\n line-height: 26px;\n }\n .neutral .dot {\n border: 2px solid var(--tone-line);\n background: var(--kd-bg, transparent);\n color: var(--kd-text-2, inherit);\n line-height: 22px;\n }\n .active .dot {\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--tone) 30%, transparent);\n }\n .label {\n margin-top: 4px;\n font-size: 12px;\n }\n .time,\n .detail {\n color: var(--kd-text-2, inherit);\n font-size: 11px;\n }\n .detail {\n display: -webkit-box;\n overflow: hidden;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 2;\n overflow-wrap: anywhere;\n }\n `,\n ];\n\n declare data: Step[] | undefined;\n\n override render() {\n const steps = Array.isArray(this.data) ? this.data : [];\n if (!steps.length) return nothing;\n return html`<ol>\n ${steps.map((step, i) => {\n const t = tone(STATUS[step.status] ?? step.status);\n const reached = step.status === 'done' || step.status === 'success';\n const cls = `${t}${reached ? ' reached' : ''}${step.status === 'active' ? ' active' : ''}`;\n return html`<li class=${cls} title=${ifDefined(step.detail)}>\n <div class=\"dot\">${glyph(t, i + 1)}</div>\n <div class=\"label\">${step.label}</div>\n ${step.time ? html`<div class=\"time\">${step.time}</div>` : nothing}\n ${step.detail ? html`<div class=\"detail\">${step.detail}</div>` : nothing}\n </li>`;\n })}\n </ol>`;\n }\n}\n\ndefine('kd-steps', KdSteps);\n","import { css, html, nothing } from 'lit';\n\nimport { cellStyles, renderCell, type Cell } from '../cell';\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\n\nexport interface TableColumn {\n key: string;\n /** Defaults to the key. */\n label?: string;\n align?: 'left' | 'center' | 'right';\n /** Keep the cell on one line (counts, times, short pills). */\n nowrap?: boolean;\n}\n\nexport interface TableData {\n /** Defaults to every key of the rows, in order of first appearance. */\n columns?: TableColumn[];\n rows: Record<string, Cell>[];\n}\n\n/**\n * A small table of cells. `data` may also be just the rows. With no rows it\n * shows `empty` (default \"none\").\n *\n * `el.data = { columns: [{ key: 'reason', label: 'Reason' }, { key: 'n', align: 'right' }], rows }`\n */\nexport class KdTable extends KdElement {\n static override properties = {\n data: { attribute: 'data', converter: json },\n empty: {},\n };\n static override styles = [\n base,\n cellStyles,\n css`\n table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n }\n th,\n td {\n padding: 6px 12px 6px 0;\n border-bottom: 1px solid var(--kd-border, transparent);\n text-align: left;\n vertical-align: top;\n }\n th {\n color: var(--kd-text-2, inherit);\n font-size: 10px;\n font-weight: 500;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n }\n .center {\n text-align: center;\n }\n .right {\n text-align: right;\n }\n /* Prose breaks anywhere so one hash in a message cannot widen the table;\n links keep whole words and stop at 40ch with an ellipsis instead. */\n td {\n --kd-link-max: 40ch;\n overflow-wrap: anywhere;\n }\n .nowrap {\n white-space: nowrap;\n }\n .nowrap .cells {\n flex-wrap: nowrap;\n }\n .none {\n padding: 8px 0;\n color: var(--kd-text-dim, inherit);\n }\n `,\n ];\n\n declare data: TableData | TableData['rows'] | undefined;\n declare empty: string | undefined;\n\n override render() {\n const d = this.data;\n if (!d || typeof d !== 'object') return nothing;\n const { columns, rows = [] } = Array.isArray(d) ? { columns: undefined, rows: d } : d;\n if (!rows.length) return html`<div class=\"none\">${this.empty ?? 'none'}</div>`;\n const cols = columns ?? [...new Set(rows.flatMap((row) => Object.keys(row ?? {})))].map((key) => ({ key }) as TableColumn);\n const align = (col: TableColumn) => (col.align === 'right' || col.align === 'center' ? col.align : '');\n const cls = (col: TableColumn) => [align(col), col.nowrap ? 'nowrap' : ''].filter(Boolean).join(' ');\n return html`<table>\n <thead>\n <tr>\n ${cols.map((col) => html`<th class=${align(col)}>${col.label ?? col.key}</th>`)}\n </tr>\n </thead>\n <tbody>\n ${rows.map(\n (row) => html`<tr>\n ${cols.map((col) => html`<td class=${cls(col)}>${renderCell(row?.[col.key])}</td>`)}\n </tr>`,\n )}\n </tbody>\n </table>`;\n }\n}\n\ndefine('kd-table', KdTable);\n","import { LitElement, css, html, nothing, type PropertyValues } from 'lit';\n\nimport { define } from '../define';\nimport { KdElement, base } from '../element';\n\nconst label = (pane: Element, i: number) => pane.getAttribute('label') || `Tab ${i + 1}`;\n\n/**\n * Tabs over its child elements, any number of them: each child is a pane,\n * labelled by its `label` attribute, with an optional `count` beside it.\n * `selected` names the open pane by label (or by index). With a `key`, the\n * choice is kept in sessionStorage, so it survives the panel recreating the\n * element. A change dispatches `change` with `{ label, index }`.\n *\n * `<kd-tabs key=\"pod-tabs\"><section label=\"Events\" count=\"3\">…</section>…</kd-tabs>`\n */\nexport class KdTabs extends KdElement {\n static override properties = { selected: {}, key: {} };\n // Panes are assigned to slots by hand, so the light DOM is never touched.\n static override shadowRootOptions: ShadowRootInit = { ...LitElement.shadowRootOptions, slotAssignment: 'manual' };\n static override styles = [\n base,\n css`\n [role='tablist'] {\n display: flex;\n flex-wrap: wrap;\n gap: 0 22px;\n margin-bottom: 10px;\n border-bottom: 1px solid var(--kd-border, transparent);\n }\n button {\n margin: 0 0 -1px;\n padding: 6px 1px;\n border: none;\n border-bottom: 2px solid transparent;\n background: none;\n color: var(--kd-text-2, inherit);\n font: inherit;\n font-size: 13px;\n cursor: pointer;\n }\n button:hover {\n color: var(--kd-text, inherit);\n }\n /* Grafana's own active tab is underlined in this orange. */\n button[aria-selected='true'] {\n border-bottom-color: var(--kd-warning, currentColor);\n color: var(--kd-text, inherit);\n }\n .count {\n margin-left: 2px;\n color: var(--kd-text-dim, inherit);\n font-size: 11px;\n }\n `,\n ];\n\n declare selected: string | undefined;\n declare key: string | undefined;\n\n #observer: MutationObserver | undefined;\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Panes may arrive or be relabelled after the element is created.\n this.#observer ??= new MutationObserver(() => this.requestUpdate());\n this.#observer.observe(this, { childList: true, subtree: true, attributes: true, attributeFilter: ['label', 'count'] });\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#observer?.disconnect();\n }\n\n get #storage(): Storage | undefined {\n try {\n return this.ownerDocument?.defaultView?.sessionStorage ?? undefined;\n } catch {\n return undefined;\n }\n }\n\n protected override willUpdate(changed: PropertyValues<this>): void {\n if (!changed.has('key') || !this.key) return;\n try {\n const stored = this.#storage?.getItem(`kd-tabs:${this.key}`);\n if (stored !== null && stored !== undefined) this.selected = stored;\n } catch {\n // Storage can be blocked; the tab simply is not remembered.\n }\n }\n\n #panes(): Element[] {\n return [...this.children];\n }\n\n #index(panes: Element[]): number {\n const selected = this.selected;\n if (selected === undefined || selected === null || selected === '') return 0;\n const byLabel = panes.findIndex((pane, i) => label(pane, i) === selected);\n if (byLabel >= 0) return byLabel;\n const n = Number(selected);\n return Number.isInteger(n) && n >= 0 && n < panes.length ? n : 0;\n }\n\n #select(panes: Element[], index: number): void {\n const name = label(panes[index], index);\n if (this.key) {\n try {\n this.#storage?.setItem(`kd-tabs:${this.key}`, name);\n } catch {\n // as above\n }\n }\n if (name === this.selected) return;\n this.selected = name;\n this.dispatchEvent(new CustomEvent('change', { detail: { label: name, index }, bubbles: true, composed: true }));\n }\n\n override render() {\n const panes = this.#panes();\n if (!panes.length) return nothing;\n const open = this.#index(panes);\n return html`<div role=\"tablist\">\n ${panes.map((pane, i) => {\n const count = pane.getAttribute('count');\n return html`<button\n type=\"button\"\n role=\"tab\"\n aria-selected=${i === open ? 'true' : 'false'}\n @click=${() => this.#select(panes, i)}\n >\n ${label(pane, i)}${count ? html`<span class=\"count\">${count}</span>` : nothing}\n </button>`;\n })}\n </div>\n ${panes.map((_, i) => html`<div role=\"tabpanel\" ?hidden=${i !== open}><slot></slot></div>`)}`;\n }\n\n // One slot per pane, assigned by hand; switching tabs only hides the others.\n protected override updated(): void {\n const slots = this.renderRoot.querySelectorAll('slot');\n this.#panes().forEach((pane, i) => slots[i]?.assign(pane));\n }\n}\n\ndefine('kd-tabs', KdTabs);\n","import { css, html } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nimport { define } from '../define';\nimport { KdElement, base } from '../element';\nimport { renderIcon, safeHref } from '../parts';\n\n/**\n * The chat tile's header link: a large icon (an image URL or an emoji) over a\n * small label. An `http(s)` link opens in a new tab.\n *\n * `<kd-tile icon=\"🤖\" label=\"Ask\" href=\"https://…\"></kd-tile>`\n */\nexport class KdTile extends KdElement {\n static override properties = { icon: {}, label: {}, href: {} };\n static override styles = [\n base,\n css`\n a,\n div {\n display: block;\n padding-top: 6px;\n color: inherit;\n text-align: center;\n text-decoration: none;\n }\n .icon {\n display: block;\n height: 30px;\n margin: 0 auto;\n font-size: 30px;\n line-height: 1;\n }\n .label {\n display: block;\n margin-top: 6px;\n color: var(--kd-text-2, inherit);\n font-size: 12px;\n }\n `,\n ];\n\n declare icon: string | undefined;\n declare label: string | undefined;\n declare href: string | undefined;\n\n override render() {\n const body = html`${renderIcon(this.icon)}<span class=\"label\">${this.label ?? ''}</span>`;\n const href = safeHref(this.href);\n if (!href) return html`<div>${body}</div>`;\n const external = /^https?:/i.test(href);\n return html`<a\n href=${href}\n target=${ifDefined(external ? '_blank' : undefined)}\n rel=${ifDefined(external ? 'noopener' : undefined)}\n >${body}</a\n >`;\n }\n}\n\ndefine('kd-tile', KdTile);\n"],"ignoreList":[1,11,12],"mappings":"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"}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
//#region src/kd/scene.ts
|
|
2
|
+
var e = "[kd]";
|
|
3
|
+
function t(e) {
|
|
4
|
+
return e ? "nodeType" in e ? (e.nodeType === 9 ? e : e.ownerDocument)?.defaultView ?? null : e : null;
|
|
5
|
+
}
|
|
6
|
+
function n(e) {
|
|
7
|
+
return t(e)?.__grafanaSceneContext ?? null;
|
|
8
|
+
}
|
|
9
|
+
function r(e, t) {
|
|
10
|
+
return n(e)?.state.$variables?.getByName(t) ?? null;
|
|
11
|
+
}
|
|
12
|
+
function i(e, t) {
|
|
13
|
+
let n = r(e, t);
|
|
14
|
+
if (!n) return "";
|
|
15
|
+
let i = n.getValue();
|
|
16
|
+
return Array.isArray(i) ? i.join(",") : String(i ?? "");
|
|
17
|
+
}
|
|
18
|
+
function a(t, n, i) {
|
|
19
|
+
if (i == null || i === "") return null;
|
|
20
|
+
let a = r(t, n);
|
|
21
|
+
if (!a) return null;
|
|
22
|
+
let o = String(i);
|
|
23
|
+
if (String(a.getValue()) === o) return null;
|
|
24
|
+
try {
|
|
25
|
+
if (typeof a.changeValueTo == "function") {
|
|
26
|
+
let t = o.includes("__all") ? {
|
|
27
|
+
value: i,
|
|
28
|
+
label: "All"
|
|
29
|
+
} : (a.state.options ?? []).find((e) => String(e.value) === o);
|
|
30
|
+
return t ? (a.changeValueTo(t.value, t.label), o) : (console.warn(`${e} ignoring ${n}=${o}: not one of its options`), null);
|
|
31
|
+
}
|
|
32
|
+
if (typeof a.setValue == "function") return a.setValue(o), o;
|
|
33
|
+
} catch (t) {
|
|
34
|
+
console.warn(`${e} could not set ${n}`, t);
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
function o(e, t, n) {
|
|
39
|
+
let r = {};
|
|
40
|
+
for (let i of n) {
|
|
41
|
+
let n = a(e, i, t[i]);
|
|
42
|
+
n !== null && (r[i] = n);
|
|
43
|
+
}
|
|
44
|
+
return r;
|
|
45
|
+
}
|
|
46
|
+
function s(e) {
|
|
47
|
+
try {
|
|
48
|
+
let t = e;
|
|
49
|
+
return typeof t?.toISOString == "function" ? t.toISOString() : "";
|
|
50
|
+
} catch {
|
|
51
|
+
return "";
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function c(e) {
|
|
55
|
+
let t = n(e)?.state.$timeRange;
|
|
56
|
+
if (!t) return null;
|
|
57
|
+
let { from: r, to: i, value: a } = t.state ?? {};
|
|
58
|
+
return {
|
|
59
|
+
from: r == null ? "" : String(r),
|
|
60
|
+
to: i == null ? "" : String(i),
|
|
61
|
+
fromIso: s(a?.from),
|
|
62
|
+
toIso: s(a?.to)
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function l(t, r, i) {
|
|
66
|
+
let a = n(t)?.state.$timeRange, o = c(t);
|
|
67
|
+
if (!a || !o) return null;
|
|
68
|
+
let s = {
|
|
69
|
+
from: r || o.from,
|
|
70
|
+
to: i || o.to
|
|
71
|
+
};
|
|
72
|
+
try {
|
|
73
|
+
if (typeof a.onTimeRangeChange == "function") a.onTimeRangeChange({
|
|
74
|
+
raw: s,
|
|
75
|
+
from: s.from,
|
|
76
|
+
to: s.to
|
|
77
|
+
});
|
|
78
|
+
else if (typeof a.updateFromUrl == "function") a.updateFromUrl(s);
|
|
79
|
+
else return console.warn(`${e} no settable time range on this scene`), null;
|
|
80
|
+
return s;
|
|
81
|
+
} catch (t) {
|
|
82
|
+
return console.warn(`${e} could not set the time range`, t), null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
var u = {
|
|
86
|
+
s: 1,
|
|
87
|
+
m: 60,
|
|
88
|
+
h: 3600,
|
|
89
|
+
d: 86400
|
|
90
|
+
};
|
|
91
|
+
function d(e) {
|
|
92
|
+
let t = /^([0-9]+)([smhd])$/.exec(String(e ?? "").trim());
|
|
93
|
+
return t ? Number(t[1]) * u[t[2]] : 0;
|
|
94
|
+
}
|
|
95
|
+
function f(e) {
|
|
96
|
+
let t = n(e);
|
|
97
|
+
if (!t) return null;
|
|
98
|
+
let r = t.state.controls, i = [t.state.refreshPicker];
|
|
99
|
+
return Array.isArray(r) ? i.push(...r) : r?.state && i.push(r.state.refreshPicker), i.find((e) => {
|
|
100
|
+
let t = e?.state;
|
|
101
|
+
return !!t && "refresh" in t;
|
|
102
|
+
}) ?? null;
|
|
103
|
+
}
|
|
104
|
+
function p(e) {
|
|
105
|
+
let t = f(e);
|
|
106
|
+
return t ? String(t.state.refresh ?? "") : null;
|
|
107
|
+
}
|
|
108
|
+
function m(e) {
|
|
109
|
+
return [...f(e)?.state.intervals ?? []];
|
|
110
|
+
}
|
|
111
|
+
function h(e, t) {
|
|
112
|
+
let n = d(e);
|
|
113
|
+
if (!n) return null;
|
|
114
|
+
let r = null, i = Infinity, a = 0;
|
|
115
|
+
for (let e of t) {
|
|
116
|
+
let t = d(e);
|
|
117
|
+
if (!t) continue;
|
|
118
|
+
let o = Math.abs(Math.log(t / n));
|
|
119
|
+
(o < i - 1e-9 || Math.abs(o - i) < 1e-9 && t > a) && (r = e, i = o, a = t);
|
|
120
|
+
}
|
|
121
|
+
return r;
|
|
122
|
+
}
|
|
123
|
+
function g(t, n) {
|
|
124
|
+
let r = f(t);
|
|
125
|
+
if (!r) return null;
|
|
126
|
+
let i = String(n ?? "").trim();
|
|
127
|
+
try {
|
|
128
|
+
if (i === "" || i === "off") return r.setState({ refresh: "" }), "off";
|
|
129
|
+
let t = r.state.intervals ?? [], n = t.includes(i) ? i : h(i, t);
|
|
130
|
+
return n ? (n !== i && console.warn(`${e} ${i} is not offered on this dashboard; using ${n}`), r.setState({ refresh: n }), n) : (console.warn(`${e} ignoring unusable refresh ${i}`), null);
|
|
131
|
+
} catch (t) {
|
|
132
|
+
return console.warn(`${e} could not set refresh`, t), null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
var _ = /^panel-[0-9]+$/;
|
|
136
|
+
function v(e) {
|
|
137
|
+
let t = [], n = /* @__PURE__ */ new Set(), r = (e) => {
|
|
138
|
+
if (!e || typeof e != "object" || n.has(e)) return;
|
|
139
|
+
n.add(e);
|
|
140
|
+
let i = e.state;
|
|
141
|
+
if (i && typeof i == "object") {
|
|
142
|
+
if (typeof i.key == "string" && _.test(i.key)) t.push(i.key);
|
|
143
|
+
else for (let e of Object.values(i)) Array.isArray(e) ? e.forEach(r) : e && typeof e == "object" && "state" in e && r(e);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
return r(e), t;
|
|
147
|
+
}
|
|
148
|
+
function y(e) {
|
|
149
|
+
let t = n(e)?.state.body?.state?.rows;
|
|
150
|
+
if (!Array.isArray(t)) return [];
|
|
151
|
+
let r = [];
|
|
152
|
+
for (let e of t) {
|
|
153
|
+
let t = e.state.layout;
|
|
154
|
+
if (t && typeof t.switchToTab == "function") {
|
|
155
|
+
let e = typeof t.getCurrentTab == "function" ? t.getCurrentTab() : null;
|
|
156
|
+
for (let n of t.state.tabs ?? []) r.push({
|
|
157
|
+
name: n.state.title || "Untitled",
|
|
158
|
+
kind: "tab",
|
|
159
|
+
open: n === e,
|
|
160
|
+
focusable: !0,
|
|
161
|
+
panels: v(n.state.layout),
|
|
162
|
+
show: () => t.switchToTab(n)
|
|
163
|
+
});
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
let n = e, i = e.state.hideHeader === !0, a = typeof n.getCollapsedState == "function" && n.getCollapsedState();
|
|
167
|
+
r.push({
|
|
168
|
+
name: e.state.title || "Header",
|
|
169
|
+
kind: "row",
|
|
170
|
+
open: i || !a,
|
|
171
|
+
focusable: !i,
|
|
172
|
+
panels: v(t),
|
|
173
|
+
show: () => {
|
|
174
|
+
!i && typeof n.setCollapsedState == "function" && n.setCollapsedState(!1);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
return r;
|
|
179
|
+
}
|
|
180
|
+
function b(n, r) {
|
|
181
|
+
let i = t(n), a = String(r ?? "").trim();
|
|
182
|
+
if (!i || !a) return null;
|
|
183
|
+
let o = /^(panel-)?[0-9]+$/.test(a) ? `panel-${a.replace(/^panel-/, "")}` : null, s = y(i), c = o ? s.find((e) => e.panels.includes(o)) : s.find((e) => e.name.toLowerCase() === a.toLowerCase());
|
|
184
|
+
if (!c || !c.focusable) return console.warn(`${e} nothing focusable for ${a}`), null;
|
|
185
|
+
try {
|
|
186
|
+
c.show();
|
|
187
|
+
} catch (t) {
|
|
188
|
+
return console.warn(`${e} could not open ${c.name}`, t), null;
|
|
189
|
+
}
|
|
190
|
+
if (o) {
|
|
191
|
+
let e = 20, t = () => {
|
|
192
|
+
let n = i.document.querySelector(`[data-viz-panel-key="${o}"]`);
|
|
193
|
+
n ? n.scrollIntoView({
|
|
194
|
+
behavior: "smooth",
|
|
195
|
+
block: "center"
|
|
196
|
+
}) : --e > 0 && i.requestAnimationFrame(t);
|
|
197
|
+
};
|
|
198
|
+
i.requestAnimationFrame(t);
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
group: c.name,
|
|
202
|
+
kind: c.kind,
|
|
203
|
+
panel: o ? Number(o.slice(6)) : null
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
function x(e, t = 12) {
|
|
207
|
+
return Math.max(1, Math.ceil((e + t) / 38));
|
|
208
|
+
}
|
|
209
|
+
function S(e, t, n) {
|
|
210
|
+
if (!t) return !0;
|
|
211
|
+
for (let r = e; r && r !== n; r = r.parent) {
|
|
212
|
+
let e = r.state?.$variables?.state?.variables;
|
|
213
|
+
if (Array.isArray(e) && e.length) return e.every((e) => {
|
|
214
|
+
let n = e.state.name;
|
|
215
|
+
return !n || String(e.getValue()) === t(`\${${n}}`);
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
return !0;
|
|
219
|
+
}
|
|
220
|
+
function C(e, t = {}) {
|
|
221
|
+
let r = n(e), i = t.panel == null ? null : String(t.panel), a = i ? `panel-${i.replace(/^panel-/, "")}` : e.closest("[data-viz-panel-key]")?.getAttribute("data-viz-panel-key");
|
|
222
|
+
if (!r || !a) return null;
|
|
223
|
+
let o = [], s = (e) => {
|
|
224
|
+
e.state?.body?.state?.key === a && "height" in e.state ? o.push(e) : e.forEachChild?.(s);
|
|
225
|
+
};
|
|
226
|
+
s(r);
|
|
227
|
+
let c = t.grafana?.replaceVariables?.bind(t.grafana), l = o.length > 1 ? o.find((e) => S(e, c, r)) : o[0];
|
|
228
|
+
if (!l) return null;
|
|
229
|
+
let u = x(e.offsetHeight);
|
|
230
|
+
if (l.state.height !== u) {
|
|
231
|
+
l.setState?.({ height: u });
|
|
232
|
+
let e = l.parent;
|
|
233
|
+
e?.setState && Array.isArray(e.state?.children) && e.setState({ children: [...e.state.children] });
|
|
234
|
+
}
|
|
235
|
+
return u;
|
|
236
|
+
}
|
|
237
|
+
//#endregion
|
|
238
|
+
export { i as _, d as a, m as c, l as d, a as f, r as g, c as h, y as i, n as l, h as m, b as n, t as o, o as p, x as r, p as s, C as t, g as u };
|
|
239
|
+
|
|
240
|
+
//# sourceMappingURL=scene-CUr0fSXC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene-CUr0fSXC.js","names":["WARN","pageWindow","page","scene","variable","name","variableValue","v","value","setVariable","want","option","o","e","setVariables","applied","allowed","set","values","iso","d","date","timeRange","from","to","setTimeRange","t","now","raw","UNIT_SECONDS","intervalSeconds","m","interval","refreshPicker","s","controls","seen","st","x","refresh","p","refreshIntervals","snapInterval","target","best","bestScore","bestSeconds","candidate","offered","seconds","score","setRefresh","PANEL_KEY","panelKeysIn","out","walk","node","groups","rows","row","layout","current","tab","r","pinned","collapsed","focusPanel","win","key","all","group","g","tries","scroll","el","gridHeight","px","pad","repeatMatches","replace","item","root","vars","fitPanel","content","given","context","items","i","h","parent"],"sources":["../../src/kd/scene.ts"],"sourcesContent":["// The Grafana page helpers: the live dashboard scene behind `__grafanaSceneContext`,\n// read and driven from panel code. Typed against only the parts used here. Scene\n// method names survive Grafana's minification; class names do not, so nothing here\n// checks a constructor.\n//\n// Every helper takes the page (its Window, or any node in it) and none touches\n// `window` at import: Business Text hides `window` from plugin code, and\n// `context.element` is the way back to it.\n\n/** The page: its Window, or any node in it (a panel's `context.element`). */\nexport type Page = Window | Node;\n\nexport interface VariableOption {\n value: unknown;\n label?: string;\n}\n\n/** A dashboard variable: a dropdown has `changeValueTo` and options, a text box `setValue`. */\nexport interface SceneVariable {\n state: { name?: string; options?: VariableOption[] };\n getValue(): unknown;\n changeValueTo?(value: unknown, text?: unknown): void;\n setValue?(value: string): void;\n}\n\nexport interface VariableSet {\n getByName(name: string): SceneVariable | undefined;\n}\n\nexport interface RawRange {\n from: string;\n to: string;\n}\n\n/** SceneTimeRange: `from`/`to` are the raw picker strings, `value` the evaluated dates. */\nexport interface SceneTimeRange {\n state: { from?: unknown; to?: unknown; value?: { from?: unknown; to?: unknown } };\n onTimeRangeChange?(range: { raw: RawRange; from: string; to: string }): void;\n updateFromUrl?(raw: RawRange): void;\n}\n\nexport interface RefreshPicker {\n state: { refresh?: string; intervals?: string[] };\n setState(patch: { refresh: string }): void;\n}\n\n/** Any scene object, for walking the graph. */\nexport interface SceneNode {\n state: any;\n parent?: SceneNode | null;\n setState?(patch: Record<string, unknown>): void;\n forEachChild?(fn: (child: SceneNode) => void): void;\n}\n\nexport interface DashboardScene extends SceneNode {\n state: {\n $variables?: VariableSet;\n $timeRange?: SceneTimeRange;\n controls?: unknown;\n refreshPicker?: unknown;\n body?: SceneNode;\n [key: string]: unknown;\n };\n}\n\n/** A tab or a collapsible row, and the panels it holds (`panel-N` keys). */\nexport interface Group {\n name: string;\n kind: 'tab' | 'row';\n open: boolean;\n /** False for a row with a hidden header: always on screen, nothing to open. */\n focusable: boolean;\n panels: string[];\n show(): void;\n}\n\nexport interface Focused {\n group: string;\n kind: 'tab' | 'row';\n panel: number | null;\n}\n\nexport interface TimeWindow {\n from: string;\n to: string;\n fromIso: string;\n toIso: string;\n}\n\nconst WARN = '[kd]';\n\n/** The page's Window, from the Window itself or any node in it. */\nexport function pageWindow(page: Page | null | undefined): Window | null {\n if (!page) return null;\n if ('nodeType' in page) {\n const doc = page.nodeType === 9 ? (page as Document) : page.ownerDocument;\n return doc?.defaultView ?? null;\n }\n return page;\n}\n\n/** The dashboard scene, or null off a dashboard (or outside Grafana). */\nexport function scene(page: Page | null | undefined): DashboardScene | null {\n const win = pageWindow(page) as (Window & { __grafanaSceneContext?: DashboardScene }) | null;\n return win?.__grafanaSceneContext ?? null;\n}\n\n// --- variables ---------------------------------------------------------------\n\nexport function variable(page: Page, name: string): SceneVariable | null {\n return scene(page)?.state.$variables?.getByName(name) ?? null;\n}\n\n/** A variable's value as text: a multi-value joins with commas; missing is ''. */\nexport function variableValue(page: Page, name: string): string {\n const v = variable(page, name);\n if (!v) return '';\n const value = v.getValue();\n return Array.isArray(value) ? value.join(',') : String(value ?? '');\n}\n\n/**\n * Sets one variable. A dropdown takes one of its own options (or an `$__all`\n * value); anything else is refused, because Grafana would store it and show a\n * blank picker. A text box takes any value.\n *\n * @returns the value set, or null when nothing changed\n */\nexport function setVariable(page: Page, name: string, value: unknown): string | null {\n if (value === undefined || value === null || value === '') return null;\n const v = variable(page, name);\n if (!v) return null;\n const want = String(value);\n if (String(v.getValue()) === want) return null;\n try {\n if (typeof v.changeValueTo === 'function') {\n const option = want.includes('__all')\n ? { value, label: 'All' }\n : (v.state.options ?? []).find((o) => String(o.value) === want);\n if (!option) {\n console.warn(`${WARN} ignoring ${name}=${want}: not one of its options`);\n return null;\n }\n v.changeValueTo(option.value, option.label);\n return want;\n }\n if (typeof v.setValue === 'function') {\n v.setValue(want);\n return want;\n }\n } catch (e) {\n console.warn(`${WARN} could not set ${name}`, e);\n }\n return null;\n}\n\n/**\n * Sets the `allowed` names found in `values`, one at a time in `allowed`'s\n * order (order can matter: a variable that starts a job goes last).\n *\n * @returns what really changed, which is not always what was asked for\n */\nexport function setVariables(page: Page, values: Record<string, unknown>, allowed: string[]): Record<string, string> {\n const applied: Record<string, string> = {};\n for (const name of allowed) {\n const set = setVariable(page, name, values[name]);\n if (set !== null) applied[name] = set;\n }\n return applied;\n}\n\n// --- time range ----------------------------------------------------------------\n\nfunction iso(date: unknown): string {\n try {\n const d = date as { toISOString?(): string } | null | undefined;\n return typeof d?.toISOString === 'function' ? d.toISOString() : '';\n } catch {\n return '';\n }\n}\n\n/** The window on screen: raw (`now-24h`, what a person reads) and ISO (what a query needs). */\nexport function timeRange(page: Page): TimeWindow | null {\n const t = scene(page)?.state.$timeRange;\n if (!t) return null;\n const { from, to, value } = t.state ?? {};\n return {\n from: from == null ? '' : String(from),\n to: to == null ? '' : String(to),\n fromIso: iso(value?.from),\n toIso: iso(value?.to),\n };\n}\n\n/**\n * Moves the time picker, both ends in one call: `onTimeRangeChange` reads only\n * `raw`, evaluates it and pushes the URL, so a reload keeps the window. A\n * missing end keeps the picker's current one.\n *\n * @returns the raw window set, or null\n */\nexport function setTimeRange(page: Page, from?: string | null, to?: string | null): RawRange | null {\n const t = scene(page)?.state.$timeRange;\n const now = timeRange(page);\n if (!t || !now) return null;\n const raw = { from: from || now.from, to: to || now.to };\n try {\n if (typeof t.onTimeRangeChange === 'function') t.onTimeRangeChange({ raw, from: raw.from, to: raw.to });\n else if (typeof t.updateFromUrl === 'function') t.updateFromUrl(raw);\n else {\n console.warn(`${WARN} no settable time range on this scene`);\n return null;\n }\n return raw;\n } catch (e) {\n console.warn(`${WARN} could not set the time range`, e);\n return null;\n }\n}\n\n// --- refresh -------------------------------------------------------------------\n\nconst UNIT_SECONDS: Record<string, number> = { s: 1, m: 60, h: 3600, d: 86400 };\n\n/** `5m` -> 300. Off, empty or unreadable is 0. */\nexport function intervalSeconds(interval: string | null | undefined): number {\n const m = /^([0-9]+)([smhd])$/.exec(String(interval ?? '').trim());\n return m ? Number(m[1]) * UNIT_SECONDS[m[2]] : 0;\n}\n\n// The picker hangs off the root or off the controls object depending on the\n// scene, so take whichever candidate actually carries `refresh`.\nfunction refreshPicker(page: Page): RefreshPicker | null {\n const s = scene(page);\n if (!s) return null;\n const controls = s.state.controls as { state?: { refreshPicker?: unknown } } | unknown[] | undefined;\n const seen: unknown[] = [s.state.refreshPicker];\n if (Array.isArray(controls)) seen.push(...controls);\n else if (controls?.state) seen.push(controls.state.refreshPicker);\n const found = seen.find((x) => {\n const st = (x as { state?: object } | null)?.state;\n return !!st && 'refresh' in st;\n });\n return (found as RefreshPicker | undefined) ?? null;\n}\n\n/** The refresh interval: `''` when auto-refresh is off, null when there is no picker. */\nexport function refresh(page: Page): string | null {\n const p = refreshPicker(page);\n return p ? String(p.state.refresh ?? '') : null;\n}\n\n/** The intervals this dashboard's picker offers. Anything else renders it blank. */\nexport function refreshIntervals(page: Page): string[] {\n return [...(refreshPicker(page)?.state.intervals ?? [])];\n}\n\n/**\n * The offered interval nearest `want`, on a log scale because the steps are\n * multiplicative (10m is nearer 15m than 5m). A tie goes to the slower one:\n * fewer queries is the cheaper mistake.\n */\nexport function snapInterval(want: string, offered: string[]): string | null {\n const target = intervalSeconds(want);\n if (!target) return null;\n let best: string | null = null;\n let bestScore = Infinity;\n let bestSeconds = 0;\n for (const candidate of offered) {\n const seconds = intervalSeconds(candidate);\n if (!seconds) continue;\n const score = Math.abs(Math.log(seconds / target));\n if (score < bestScore - 1e-9 || (Math.abs(score - bestScore) < 1e-9 && seconds > bestSeconds)) {\n best = candidate;\n bestScore = score;\n bestSeconds = seconds;\n }\n }\n return best;\n}\n\n/**\n * Sets auto-refresh. An interval the picker does not offer is not an error to\n * Grafana - it is stored, the picker goes blank and refreshing stops - so it is\n * snapped to the nearest offered one.\n *\n * @returns what was set (`off` or an interval), or null\n */\nexport function setRefresh(page: Page, value: string): string | null {\n const p = refreshPicker(page);\n if (!p) return null;\n const want = String(value ?? '').trim();\n try {\n if (want === '' || want === 'off') {\n p.setState({ refresh: '' });\n return 'off';\n }\n const offered = p.state.intervals ?? [];\n const best = offered.includes(want) ? want : snapInterval(want, offered);\n if (!best) {\n console.warn(`${WARN} ignoring unusable refresh ${want}`);\n return null;\n }\n if (best !== want) console.warn(`${WARN} ${want} is not offered on this dashboard; using ${best}`);\n p.setState({ refresh: best });\n return best;\n } catch (e) {\n console.warn(`${WARN} could not set refresh`, e);\n return null;\n }\n}\n\n// --- groups and focus ----------------------------------------------------------\n\nconst PANEL_KEY = /^panel-[0-9]+$/;\n\n// Every panel under a layout, including those in closed tabs, which have no DOM\n// but are in the scene graph.\nfunction panelKeysIn(node: unknown): string[] {\n const out: string[] = [];\n const seen = new Set<unknown>();\n const walk = (o: unknown): void => {\n if (!o || typeof o !== 'object' || seen.has(o)) return;\n seen.add(o);\n const st = (o as SceneNode).state;\n if (!st || typeof st !== 'object') return;\n if (typeof st.key === 'string' && PANEL_KEY.test(st.key)) {\n out.push(st.key);\n return;\n }\n for (const v of Object.values(st)) {\n if (Array.isArray(v)) v.forEach(walk);\n else if (v && typeof v === 'object' && 'state' in v) walk(v);\n }\n };\n walk(node);\n return out;\n}\n\n/**\n * The dashboard's tabs and collapsible rows, in order. A v2 dashboard is a list\n * of rows; a row holds panels or a tabs manager, and both are groups here,\n * because to the person looking at it either way some panels show and others\n * do not.\n */\nexport function groups(page: Page): Group[] {\n const rows = scene(page)?.state.body?.state?.rows;\n if (!Array.isArray(rows)) return [];\n const out: Group[] = [];\n for (const row of rows as SceneNode[]) {\n const layout = row.state.layout;\n if (layout && typeof layout.switchToTab === 'function') {\n const current = typeof layout.getCurrentTab === 'function' ? layout.getCurrentTab() : null;\n for (const tab of (layout.state.tabs ?? []) as SceneNode[]) {\n out.push({\n name: tab.state.title || 'Untitled',\n kind: 'tab',\n open: tab === current,\n focusable: true,\n panels: panelKeysIn(tab.state.layout),\n show: () => layout.switchToTab(tab),\n });\n }\n continue;\n }\n const r = row as SceneNode & { getCollapsedState?(): boolean; setCollapsedState?(collapsed: boolean): void };\n const pinned = row.state.hideHeader === true;\n const collapsed = typeof r.getCollapsedState === 'function' && r.getCollapsedState();\n out.push({\n name: row.state.title || 'Header',\n kind: 'row',\n open: pinned || !collapsed,\n focusable: !pinned,\n panels: panelKeysIn(layout),\n show: () => {\n if (!pinned && typeof r.setCollapsedState === 'function') r.setCollapsedState(false);\n },\n });\n }\n return out;\n}\n\n/**\n * Brings a panel or a group on screen. `target` is a panel id (`5`, `panel-5`)\n * or a group name; either way its group is opened, so the caller never needs\n * to know whether that is a tab or a row. A panel is then scrolled to, retrying\n * over animation frames because a tab that was closed mounts a beat later.\n */\nexport function focusPanel(page: Page, target: string | number | null | undefined): Focused | null {\n const win = pageWindow(page);\n const want = String(target ?? '').trim();\n if (!win || !want) return null;\n const key = /^(panel-)?[0-9]+$/.test(want) ? `panel-${want.replace(/^panel-/, '')}` : null;\n const all = groups(win);\n const group = key\n ? all.find((g) => g.panels.includes(key))\n : all.find((g) => g.name.toLowerCase() === want.toLowerCase());\n if (!group || !group.focusable) {\n console.warn(`${WARN} nothing focusable for ${want}`);\n return null;\n }\n try {\n group.show();\n } catch (e) {\n console.warn(`${WARN} could not open ${group.name}`, e);\n return null;\n }\n if (key) {\n let tries = 20;\n const scroll = (): void => {\n const el = win.document.querySelector(`[data-viz-panel-key=\"${key}\"]`);\n if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' });\n else if (--tries > 0) win.requestAnimationFrame(scroll);\n };\n win.requestAnimationFrame(scroll);\n }\n return { group: group.name, kind: group.kind, panel: key ? Number(key.slice(6)) : null };\n}\n\n// --- fit -----------------------------------------------------------------------\n\n/** What `fitPanel` reads from Business Text's `context`. */\nexport interface FitContext {\n grafana?: { replaceVariables?(text: string): string };\n /** The panel id or key, when `content` is not inside the panel's own DOM. */\n panel?: string | number;\n}\n\n/**\n * Grid rows needed for `px` of content. A grid item of height h spans 38h - 8\n * px; `pad` covers the panel's own padding (12 with Business Text's `.dt-row`\n * padding set to `4px 0 0`).\n */\nexport function gridHeight(px: number, pad = 12): number {\n return Math.max(1, Math.ceil((px + pad) / 38));\n}\n\n// A repeat's clones share their panel key; each sits under a scene object whose\n// local $variables hold that clone's value.\nfunction repeatMatches(item: SceneNode, replace: ((text: string) => string) | undefined, root: SceneNode): boolean {\n if (!replace) return true;\n for (let p: SceneNode | null | undefined = item; p && p !== root; p = p.parent) {\n const vars = p.state?.$variables?.state?.variables as SceneVariable[] | undefined;\n if (!Array.isArray(vars) || !vars.length) continue;\n return vars.every((v) => {\n const name = v.state.name;\n return !name || String(v.getValue()) === replace(`\\${${name}}`);\n });\n }\n return true;\n}\n\n/**\n * Fits a panel's grid height to its content. Grafana has none of its own, but\n * the grid item is reachable in the scene: setting its height changes state\n * only, and the grid relays out once its parent gets a new children list. Live\n * only, never saved; a no-op when the height is already right, so it is safe in\n * an `afterRender` that runs twice per refresh.\n *\n * @param content the element to measure, inside the panel\n * @returns the height set or kept, or null when the panel was not found\n */\nexport function fitPanel(content: HTMLElement, context: FitContext = {}): number | null {\n const root = scene(content);\n const given = context.panel == null ? null : String(context.panel);\n const key = given\n ? `panel-${given.replace(/^panel-/, '')}`\n : content.closest('[data-viz-panel-key]')?.getAttribute('data-viz-panel-key');\n if (!root || !key) return null;\n\n const items: SceneNode[] = [];\n const walk = (o: SceneNode): void => {\n if (o.state?.body?.state?.key === key && 'height' in o.state) {\n items.push(o);\n return;\n }\n o.forEachChild?.(walk);\n };\n walk(root);\n const replace = context.grafana?.replaceVariables?.bind(context.grafana);\n const item = items.length > 1 ? items.find((i) => repeatMatches(i, replace, root)) : items[0];\n if (!item) return null;\n\n const h = gridHeight(content.offsetHeight);\n if (item.state.height !== h) {\n item.setState?.({ height: h });\n const parent = item.parent;\n if (parent?.setState && Array.isArray(parent.state?.children)) parent.setState({ children: [...parent.state.children] });\n }\n return h;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { nothing, type PropertyValues } from 'lit';
|
|
2
|
+
import '../../kd/elements/table';
|
|
3
|
+
import { KdElement } from '../../kd/element';
|
|
4
|
+
import { type EventGroup } from '../events';
|
|
5
|
+
/**
|
|
6
|
+
* Kubernetes events from Loki (the panel's frames, or their rows) folded into
|
|
7
|
+
* a table: one row per object, reason and message, with a reason pill
|
|
8
|
+
* (warnings in the error tone, the reporting component on hover), the
|
|
9
|
+
* message, how many times and when last seen. `object` adds the object each
|
|
10
|
+
* event is about, `namespace` its namespace. "Last seen" is measured to `now`
|
|
11
|
+
* (ms), else the dashboard's time range end, else the clock.
|
|
12
|
+
*
|
|
13
|
+
* `count` is the number of rows, `warnings` how many are warnings. Inside a
|
|
14
|
+
* `kd-tabs` pane, the pane's `count` follows it, so the tab shows it.
|
|
15
|
+
*
|
|
16
|
+
* `el.data = context.data` → `<kd-k8s-events object></kd-k8s-events>`
|
|
17
|
+
*/
|
|
18
|
+
export declare class KdK8sEvents extends KdElement {
|
|
19
|
+
#private;
|
|
20
|
+
static properties: {
|
|
21
|
+
data: {
|
|
22
|
+
attribute: string;
|
|
23
|
+
converter: {
|
|
24
|
+
fromAttribute(value: string | null): unknown;
|
|
25
|
+
toAttribute(value: unknown): string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
object: {
|
|
29
|
+
type: BooleanConstructor;
|
|
30
|
+
};
|
|
31
|
+
namespace: {
|
|
32
|
+
type: BooleanConstructor;
|
|
33
|
+
};
|
|
34
|
+
now: {
|
|
35
|
+
type: NumberConstructor;
|
|
36
|
+
};
|
|
37
|
+
empty: {};
|
|
38
|
+
};
|
|
39
|
+
static styles: import("lit").CSSResult;
|
|
40
|
+
data: unknown;
|
|
41
|
+
object: boolean | undefined;
|
|
42
|
+
namespace: boolean | undefined;
|
|
43
|
+
now: number | undefined;
|
|
44
|
+
empty: string | undefined;
|
|
45
|
+
/** The folded events. */
|
|
46
|
+
get groups(): EventGroup[];
|
|
47
|
+
/** How many rows the table has. */
|
|
48
|
+
get count(): number;
|
|
49
|
+
/** How many of them are warnings. */
|
|
50
|
+
get warnings(): number;
|
|
51
|
+
protected willUpdate(changed: PropertyValues<this>): void;
|
|
52
|
+
protected updated(): void;
|
|
53
|
+
render(): typeof nothing | import("lit-html").TemplateResult<1>;
|
|
54
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { nothing } from 'lit';
|
|
2
|
+
import '../../kd/elements/bar';
|
|
3
|
+
import '../../kd/elements/data';
|
|
4
|
+
import '../../kd/elements/groups';
|
|
5
|
+
import '../../kd/elements/sheet';
|
|
6
|
+
import '../../kd/elements/steps';
|
|
7
|
+
import '../../kd/elements/tabs';
|
|
8
|
+
import './events';
|
|
9
|
+
import { KdElement } from '../../kd/element';
|
|
10
|
+
import { type K8sObject } from '../map';
|
|
11
|
+
/**
|
|
12
|
+
* The generic page of one Kubernetes object, composed from the kd elements:
|
|
13
|
+
* the title bar, the conditions as steps, then tabs for the summary sheet,
|
|
14
|
+
* labels, annotations, events (when `events` is set: the panel's Loki frames)
|
|
15
|
+
* and the YAML. `related` objects extend the owner chain; `key` keeps the
|
|
16
|
+
* open tab per view; `now` (ms) pins the ages.
|
|
17
|
+
*
|
|
18
|
+
* `el.data = context.data[0][0]; el.events = context.data` → `<kd-k8s-object key="pod"></kd-k8s-object>`
|
|
19
|
+
*/
|
|
20
|
+
export declare class KdK8sObject extends KdElement {
|
|
21
|
+
static properties: {
|
|
22
|
+
data: {
|
|
23
|
+
attribute: string;
|
|
24
|
+
converter: {
|
|
25
|
+
fromAttribute(value: string | null): unknown;
|
|
26
|
+
toAttribute(value: unknown): string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
events: {
|
|
30
|
+
attribute: boolean;
|
|
31
|
+
};
|
|
32
|
+
related: {
|
|
33
|
+
attribute: boolean;
|
|
34
|
+
};
|
|
35
|
+
key: {};
|
|
36
|
+
now: {
|
|
37
|
+
type: NumberConstructor;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
static styles: import("lit").CSSResult[];
|
|
41
|
+
data: K8sObject | undefined;
|
|
42
|
+
events: unknown;
|
|
43
|
+
related: K8sObject[] | undefined;
|
|
44
|
+
key: string | undefined;
|
|
45
|
+
now: number | undefined;
|
|
46
|
+
render(): typeof nothing | import("lit-html").TemplateResult<1>;
|
|
47
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { nothing } from 'lit';
|
|
2
|
+
import '../../kd/elements/link';
|
|
3
|
+
import { KdElement } from '../../kd/element';
|
|
4
|
+
import { type ObjectRef } from '../links';
|
|
5
|
+
/**
|
|
6
|
+
* A link to the k8s-* view of one object, with its kind's icon and a back
|
|
7
|
+
* link to this page. Set `data` (an `ObjectRef`, or any object with `kind`,
|
|
8
|
+
* `apiVersion` and `metadata`), or the attributes `kind`, `name`, `namespace`,
|
|
9
|
+
* `api-version` and `plural`. A kind no view shows renders as a label.
|
|
10
|
+
*
|
|
11
|
+
* `<kd-k8s-ref kind="Pod" namespace="db" name="postgresql-0"></kd-k8s-ref>`
|
|
12
|
+
*/
|
|
13
|
+
export declare class KdK8sRef extends KdElement {
|
|
14
|
+
static properties: {
|
|
15
|
+
data: {
|
|
16
|
+
attribute: string;
|
|
17
|
+
converter: {
|
|
18
|
+
fromAttribute(value: string | null): unknown;
|
|
19
|
+
toAttribute(value: unknown): string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
kind: {};
|
|
23
|
+
name: {};
|
|
24
|
+
namespace: {};
|
|
25
|
+
apiVersion: {
|
|
26
|
+
attribute: string;
|
|
27
|
+
};
|
|
28
|
+
plural: {};
|
|
29
|
+
};
|
|
30
|
+
static styles: import("lit").CSSResult[];
|
|
31
|
+
data: (Partial<ObjectRef> & {
|
|
32
|
+
metadata?: {
|
|
33
|
+
name?: string;
|
|
34
|
+
namespace?: string;
|
|
35
|
+
};
|
|
36
|
+
}) | undefined;
|
|
37
|
+
kind: string | undefined;
|
|
38
|
+
name: string | undefined;
|
|
39
|
+
namespace: string | undefined;
|
|
40
|
+
apiVersion: string | undefined;
|
|
41
|
+
plural: string | undefined;
|
|
42
|
+
/** The reference, `data` taking precedence over the attributes field by field. */
|
|
43
|
+
get ref(): ObjectRef | undefined;
|
|
44
|
+
render(): typeof nothing | import("lit-html").TemplateResult<1>;
|
|
45
|
+
}
|