@netlify/spark-ui 1.10.0 → 1.11.0
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/dist/components/preact/AskNetlify/AskNetlify.d.ts +3 -2
- package/dist/components/preact/AskNetlify/AskNetlify.js +32 -31
- package/dist/components/preact/AskNetlify/components/ChatInterface.d.ts +1 -1
- package/dist/components/preact/SearchModal/components/SearchModal/SearchModal.d.ts +1 -0
- package/dist/components/preact/SearchModal/components/SearchModal/SearchModal.js +56 -43
- package/dist/components/preact/SearchModal/components/SearchWindow.d.ts +1 -1
- package/dist/components/preact/SearchModal/components/SearchWindow.js +26 -38
- package/dist/components/preact/SearchModal/types/search.types.d.ts +0 -3
- package/package.json +1 -1
- package/packages/components/preact/AskNetlify/AskNetlify.tsx +11 -3
- package/packages/components/preact/AskNetlify/components/ChatInterface.tsx +1 -1
- package/packages/components/preact/SearchModal/components/SearchModal/SearchModal.tsx +21 -4
- package/packages/components/preact/SearchModal/components/SearchWindow.tsx +0 -10
- package/packages/components/preact/SearchModal/types/search.types.tsx +0 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
interface AskNetlifyProps {
|
|
2
|
-
|
|
2
|
+
kapaIntegrationId?: string;
|
|
3
|
+
setModalState?: (e: {
|
|
3
4
|
current: string;
|
|
4
5
|
}) => void;
|
|
5
6
|
}
|
|
6
|
-
export default function AskNetlify(props: AskNetlifyProps): import("preact").JSX.Element;
|
|
7
|
+
export default function AskNetlify(props: AskNetlifyProps): import("preact").JSX.Element | undefined;
|
|
7
8
|
export {};
|
|
@@ -1,35 +1,36 @@
|
|
|
1
|
-
import { u as
|
|
2
|
-
import { A as
|
|
3
|
-
import { C as s, K as
|
|
4
|
-
import { A as
|
|
5
|
-
import '../../../assets/AskNetlify.css';function
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
question: r.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
1
|
+
import { u as o } from "../../../chunks/jsxRuntime.module.Bzuv3cXw.js";
|
|
2
|
+
import { A as i } from "../../../chunks/hooks.module.DGkdD5n9.js";
|
|
3
|
+
import { C as s, K as a } from "../../../chunks/ChatInterface.EQAPs01R.js";
|
|
4
|
+
import { A as u } from "../../../chunks/analytics.Ch1vuuOl.js";
|
|
5
|
+
import '../../../assets/AskNetlify.css';function w(n) {
|
|
6
|
+
const r = i(new u());
|
|
7
|
+
if (n.kapaIntegrationId)
|
|
8
|
+
return /* @__PURE__ */ o(
|
|
9
|
+
a,
|
|
10
|
+
{
|
|
11
|
+
integrationId: n.kapaIntegrationId,
|
|
12
|
+
callbacks: {
|
|
13
|
+
askAI: {
|
|
14
|
+
onQuerySubmit: (e) => {
|
|
15
|
+
var t;
|
|
16
|
+
!e.question || !e.threadId || (t = r == null ? void 0 : r.current) == null || t.track("ask:new_query", {
|
|
17
|
+
question: e.question,
|
|
18
|
+
thread_id: e.threadId
|
|
19
|
+
});
|
|
20
|
+
},
|
|
21
|
+
onAnswerGenerationCompleted: (e) => {
|
|
22
|
+
var t;
|
|
23
|
+
!e.questionAnswerId || !e.answer || (t = r == null ? void 0 : r.current) == null || t.track("ask:answer_generated", {
|
|
24
|
+
question_id: e.questionAnswerId,
|
|
25
|
+
answer_length: e.answer.length
|
|
26
|
+
});
|
|
27
|
+
}
|
|
26
28
|
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
);
|
|
29
|
+
},
|
|
30
|
+
children: /* @__PURE__ */ o(s, { setModalState: n.setModalState })
|
|
31
|
+
}
|
|
32
|
+
);
|
|
32
33
|
}
|
|
33
34
|
export {
|
|
34
|
-
|
|
35
|
+
w as default
|
|
35
36
|
};
|
|
@@ -1,67 +1,80 @@
|
|
|
1
1
|
import { u as e } from "../../../../../chunks/jsxRuntime.module.Bzuv3cXw.js";
|
|
2
|
-
import { A as
|
|
3
|
-
import
|
|
2
|
+
import { A as v, y as m, d as h } from "../../../../../chunks/hooks.module.DGkdD5n9.js";
|
|
3
|
+
import b from "../../../Modal/Modal.js";
|
|
4
4
|
import p from "../../../KeyboardKey/KeyboardKey.js";
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
5
|
+
import w from "../SearchWindow.js";
|
|
6
|
+
import A from "../SearchInput.js";
|
|
7
|
+
import M from "../SearchLink/SearchLink.js";
|
|
8
|
+
import { useSearch as O } from "../../hooks/useSearch.js";
|
|
9
|
+
import { useSearchLogger as P } from "../../hooks/useSearchLogger.js";
|
|
10
|
+
import { useKeyboardNav as C } from "../../hooks/useKeyboardNav.js";
|
|
10
11
|
import { useSearchHotkeys as E } from "../../hooks/useSearchHotkeys.js";
|
|
11
12
|
import { useSearchParams as K } from "../../hooks/useSearchParams.js";
|
|
12
|
-
import { useSearchToggles as
|
|
13
|
-
import
|
|
14
|
-
import { Fragment as
|
|
15
|
-
import '../../../../../assets/SearchModal.css';function
|
|
16
|
-
const r =
|
|
17
|
-
return
|
|
13
|
+
import { useSearchToggles as F } from "../../hooks/useSearchToggles.js";
|
|
14
|
+
import R from "../../../AskNetlify/AskNetlify.js";
|
|
15
|
+
import { Fragment as I } from "preact";
|
|
16
|
+
import '../../../../../assets/SearchModal.css';function q(s) {
|
|
17
|
+
const r = v(null);
|
|
18
|
+
return m(() => {
|
|
18
19
|
function i(t) {
|
|
19
|
-
r.current && !r.current.contains(t.target) &&
|
|
20
|
+
r.current && !r.current.contains(t.target) && s();
|
|
20
21
|
}
|
|
21
22
|
return document.addEventListener("mousedown", i), () => {
|
|
22
23
|
document.removeEventListener("mousedown", i);
|
|
23
24
|
};
|
|
24
|
-
}, [
|
|
25
|
+
}, [s]), r;
|
|
25
26
|
}
|
|
26
|
-
function
|
|
27
|
-
const [r, i] = h(!1), [t,
|
|
28
|
-
|
|
29
|
-
let
|
|
30
|
-
const
|
|
31
|
-
window.pagefind && (i(!0),
|
|
27
|
+
function Z(s = { className: "", children: void 0, debug: !1, kapaIntegrationId: void 0 }) {
|
|
28
|
+
const [r, i] = h(!1), [t, d] = h({ current: "search" });
|
|
29
|
+
m(() => {
|
|
30
|
+
let n;
|
|
31
|
+
const c = () => {
|
|
32
|
+
window.pagefind && (i(!0), n && clearInterval(n));
|
|
32
33
|
};
|
|
33
|
-
return
|
|
34
|
+
return c(), n = setInterval(c, 100), () => clearInterval(n);
|
|
34
35
|
}, []);
|
|
35
|
-
const { children:
|
|
36
|
-
return
|
|
37
|
-
a.current && (
|
|
38
|
-
}, [
|
|
39
|
-
var
|
|
40
|
-
const
|
|
41
|
-
|
|
36
|
+
const { children: N, className: k, debug: y, ...L } = s, { state: o, actions: g } = O(), [l, S] = h(!1), u = () => S(!0), f = () => S(!1), a = v(null), T = q(f);
|
|
37
|
+
return P(o, y), F(r, u, d), K(r, g.setSearchTerm, u), E(r, l, u, f), C(r, a, l, f), m(() => {
|
|
38
|
+
a.current && (l ? a.current.showModal() : a.current.close());
|
|
39
|
+
}, [l]), m(() => {
|
|
40
|
+
var c;
|
|
41
|
+
const n = (c = a.current) == null ? void 0 : c.querySelector("input");
|
|
42
|
+
n && n.focus(), t.current === "ask" ? setTimeout(() => {
|
|
42
43
|
a.current.classList.add("n-search-modal-ask");
|
|
43
44
|
}, 150) : t.current === "search" && setTimeout(() => {
|
|
44
45
|
a.current.classList.remove("n-search-modal-ask");
|
|
45
46
|
}, 150);
|
|
46
47
|
}, [t.current]), /* @__PURE__ */ e(
|
|
47
|
-
|
|
48
|
+
b,
|
|
48
49
|
{
|
|
49
50
|
ref: a,
|
|
50
|
-
className: `n-search-modal ${
|
|
51
|
+
className: `n-search-modal ${k || ""}`,
|
|
51
52
|
"data-state": t.current,
|
|
52
|
-
...
|
|
53
|
-
children: /* @__PURE__ */ e("div", { ref:
|
|
54
|
-
t.current === "ask" && /* @__PURE__ */ e(
|
|
55
|
-
t.current === "search" && /* @__PURE__ */ e(
|
|
56
|
-
/* @__PURE__ */ e(
|
|
53
|
+
...L,
|
|
54
|
+
children: /* @__PURE__ */ e("div", { ref: T, className: "n-search-container", children: [
|
|
55
|
+
t.current === "ask" && /* @__PURE__ */ e(R, { setModalState: d, kapaIntegrationId: s.kapaIntegrationId }),
|
|
56
|
+
t.current === "search" && /* @__PURE__ */ e(I, { children: [
|
|
57
|
+
/* @__PURE__ */ e(A, { setSearchTerm: g.setSearchTerm, initialValue: o.searchTerm }),
|
|
57
58
|
/* @__PURE__ */ e(
|
|
58
|
-
|
|
59
|
+
w,
|
|
59
60
|
{
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
searchLoading: o.isLoading,
|
|
62
|
+
searchTerm: o.searchTerm,
|
|
63
|
+
results: o.results,
|
|
64
|
+
children: /* @__PURE__ */ e(I, { children: [
|
|
65
|
+
s.kapaIntegrationId && /* @__PURE__ */ e(
|
|
66
|
+
M,
|
|
67
|
+
{
|
|
68
|
+
as: "button",
|
|
69
|
+
icon: "askNetlify",
|
|
70
|
+
label: "Ask Netlify AI",
|
|
71
|
+
onClick: () => {
|
|
72
|
+
d({ current: "ask" });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
),
|
|
76
|
+
N
|
|
77
|
+
] })
|
|
65
78
|
}
|
|
66
79
|
),
|
|
67
80
|
/* @__PURE__ */ e("div", { className: "n-search-footer", children: [
|
|
@@ -82,5 +95,5 @@ function X(c = { className: "", children: null, debug: !1 }) {
|
|
|
82
95
|
);
|
|
83
96
|
}
|
|
84
97
|
export {
|
|
85
|
-
|
|
98
|
+
Z as default
|
|
86
99
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { SearchWindowProps } from '../types/search.types';
|
|
2
|
-
export default function SearchWindow({
|
|
2
|
+
export default function SearchWindow({ searchLoading, searchTerm, results, children: DefaultWindow, }: SearchWindowProps): import("preact").JSX.Element;
|
|
@@ -1,54 +1,42 @@
|
|
|
1
1
|
import { u as e } from "../../../../chunks/jsxRuntime.module.Bzuv3cXw.js";
|
|
2
|
-
import { T as
|
|
3
|
-
import
|
|
2
|
+
import { T as o } from "../../../../chunks/hooks.module.DGkdD5n9.js";
|
|
3
|
+
import m from "./SearchHeading/SearchHeading.js";
|
|
4
4
|
import a from "./SearchLink/SearchLink.js";
|
|
5
|
-
import { Fragment as
|
|
6
|
-
const
|
|
5
|
+
import { Fragment as h } from "preact";
|
|
6
|
+
const d = {
|
|
7
7
|
light: "dark",
|
|
8
8
|
dark: "light"
|
|
9
|
-
},
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
},
|
|
9
|
+
}, u = (n) => {
|
|
10
|
+
const t = document.getElementById("site-theme-select");
|
|
11
|
+
t && (t.value = n), document.documentElement.setAttribute("data-theme", n), localStorage.setItem("theme", n);
|
|
12
|
+
}, g = ({
|
|
13
13
|
searchLoading: n,
|
|
14
|
-
searchTerm:
|
|
15
|
-
results:
|
|
14
|
+
searchTerm: t,
|
|
15
|
+
results: r
|
|
16
16
|
}) => {
|
|
17
17
|
if (n)
|
|
18
|
-
return /* @__PURE__ */ e(
|
|
18
|
+
return /* @__PURE__ */ e(m, { children: [
|
|
19
19
|
"Searching for ",
|
|
20
|
-
/* @__PURE__ */ e("span", { className: "n-search-term", children:
|
|
20
|
+
/* @__PURE__ */ e("span", { className: "n-search-term", children: t }),
|
|
21
21
|
" ..."
|
|
22
22
|
] });
|
|
23
|
-
if (!
|
|
24
|
-
return /* @__PURE__ */ e(
|
|
23
|
+
if (!r || r.length === 0)
|
|
24
|
+
return /* @__PURE__ */ e(m, { children: [
|
|
25
25
|
"0 results for ",
|
|
26
|
-
/* @__PURE__ */ e("span", { className: "n-search-term", children:
|
|
26
|
+
/* @__PURE__ */ e("span", { className: "n-search-term", children: t })
|
|
27
27
|
] });
|
|
28
|
-
const c =
|
|
28
|
+
const c = o(() => r.map((i, l) => /* @__PURE__ */ e("li", { className: "n-results-list-item", children: /* @__PURE__ */ e(a, { ...i }) }, l)), [r]);
|
|
29
29
|
return /* @__PURE__ */ e("ul", { className: "n-results-list", role: "list", children: c });
|
|
30
30
|
};
|
|
31
|
-
function
|
|
32
|
-
|
|
33
|
-
searchLoading: r,
|
|
31
|
+
function N({
|
|
32
|
+
searchLoading: n,
|
|
34
33
|
searchTerm: t,
|
|
35
|
-
results:
|
|
36
|
-
children:
|
|
34
|
+
results: r,
|
|
35
|
+
children: c
|
|
37
36
|
}) {
|
|
38
|
-
return /* @__PURE__ */ e("div", { className: "n-search-window", children: /* @__PURE__ */ e("div", { className: "n-search-links", children: t && t.length > 1 ? /* @__PURE__ */ e(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
{
|
|
42
|
-
as: "button",
|
|
43
|
-
icon: "askNetlify",
|
|
44
|
-
label: "Ask Netlify AI",
|
|
45
|
-
onClick: () => {
|
|
46
|
-
n({ current: "ask" });
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
),
|
|
50
|
-
l,
|
|
51
|
-
/* @__PURE__ */ e(s, { children: "Actions" }),
|
|
37
|
+
return /* @__PURE__ */ e("div", { className: "n-search-window", children: /* @__PURE__ */ e("div", { className: "n-search-links", children: t && t.length > 1 ? /* @__PURE__ */ e(g, { searchLoading: n, searchTerm: t, results: r }) : c ? /* @__PURE__ */ e(h, { children: [
|
|
38
|
+
c,
|
|
39
|
+
/* @__PURE__ */ e(m, { children: "Actions" }),
|
|
52
40
|
/* @__PURE__ */ e(
|
|
53
41
|
a,
|
|
54
42
|
{
|
|
@@ -56,13 +44,13 @@ function A({
|
|
|
56
44
|
icon: "lightbulb",
|
|
57
45
|
label: "Toggle theme",
|
|
58
46
|
onClick: () => {
|
|
59
|
-
const i = window.matchMedia("(prefers-color-scheme: dark)").matches,
|
|
60
|
-
|
|
47
|
+
const i = window.matchMedia("(prefers-color-scheme: dark)").matches, l = document.documentElement.getAttribute("data-theme"), s = i ? "dark" : l || "light";
|
|
48
|
+
s && u(d[s]);
|
|
61
49
|
}
|
|
62
50
|
}
|
|
63
51
|
)
|
|
64
52
|
] }) : null }) });
|
|
65
53
|
}
|
|
66
54
|
export {
|
|
67
|
-
|
|
55
|
+
N as default
|
|
68
56
|
};
|
package/package.json
CHANGED
|
@@ -5,23 +5,31 @@ import ChatInterface from './components/ChatInterface';
|
|
|
5
5
|
import './AskNetlify.css';
|
|
6
6
|
|
|
7
7
|
interface AskNetlifyProps {
|
|
8
|
-
|
|
8
|
+
kapaIntegrationId?: string;
|
|
9
|
+
setModalState?: (e: { current: string }) => void;
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
export default function AskNetlify(props: AskNetlifyProps) {
|
|
12
13
|
const analyticsRef = useRef<Analytics>(new Analytics());
|
|
14
|
+
|
|
15
|
+
if (!props.kapaIntegrationId) return;
|
|
16
|
+
|
|
13
17
|
return (
|
|
14
18
|
<KapaProvider
|
|
15
|
-
integrationId=
|
|
19
|
+
integrationId={props.kapaIntegrationId}
|
|
16
20
|
callbacks={{
|
|
17
21
|
askAI: {
|
|
18
22
|
onQuerySubmit: data => {
|
|
23
|
+
if (!data.question || !data.threadId) return;
|
|
24
|
+
|
|
19
25
|
analyticsRef?.current?.track('ask:new_query', {
|
|
20
26
|
question: data.question,
|
|
21
27
|
thread_id: data.threadId,
|
|
22
28
|
});
|
|
23
29
|
},
|
|
24
30
|
onAnswerGenerationCompleted: data => {
|
|
31
|
+
if (!data.questionAnswerId || !data.answer) return;
|
|
32
|
+
|
|
25
33
|
analyticsRef?.current?.track('ask:answer_generated', {
|
|
26
34
|
question_id: data.questionAnswerId,
|
|
27
35
|
answer_length: data.answer.length,
|
|
@@ -30,7 +38,7 @@ export default function AskNetlify(props: AskNetlifyProps) {
|
|
|
30
38
|
},
|
|
31
39
|
}}
|
|
32
40
|
>
|
|
33
|
-
<ChatInterface {
|
|
41
|
+
<ChatInterface setModalState={props.setModalState} />
|
|
34
42
|
</KapaProvider>
|
|
35
43
|
);
|
|
36
44
|
}
|
|
@@ -6,7 +6,7 @@ import { BackButton } from './BackButton';
|
|
|
6
6
|
import { ChatMessages } from './ChatMessages';
|
|
7
7
|
|
|
8
8
|
interface Props {
|
|
9
|
-
setModalState?: (
|
|
9
|
+
setModalState?: (e: { current: string }) => void;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export default function ChatInterface({ setModalState }: Props) {
|
|
@@ -5,6 +5,7 @@ import Modal from '../../../../preact/Modal/Modal';
|
|
|
5
5
|
import KeyboardKey from '../../../../preact/KeyboardKey/KeyboardKey';
|
|
6
6
|
import SearchWindow from '../../components/SearchWindow';
|
|
7
7
|
import SearchInput from '../../components/SearchInput';
|
|
8
|
+
import SearchLink from '../../components/SearchLink/SearchLink';
|
|
8
9
|
import { useClickOutside } from '../../../../../utils/useClickOutside';
|
|
9
10
|
import {
|
|
10
11
|
useSearch,
|
|
@@ -23,9 +24,12 @@ interface Props {
|
|
|
23
24
|
children: ComponentChildren;
|
|
24
25
|
className?: string;
|
|
25
26
|
debug?: boolean;
|
|
27
|
+
kapaIntegrationId?: string;
|
|
26
28
|
}
|
|
27
29
|
|
|
28
|
-
function SearchModal(
|
|
30
|
+
function SearchModal(
|
|
31
|
+
props: Props = { className: '', children: undefined, debug: false, kapaIntegrationId: undefined }
|
|
32
|
+
) {
|
|
29
33
|
const [isPagefindLoaded, setIsPagefindLoaded] = useState(false);
|
|
30
34
|
const [modalState, setModalState] = useState({ current: 'search' });
|
|
31
35
|
|
|
@@ -93,18 +97,31 @@ function SearchModal(props: Props = { className: '', children: null, debug: fals
|
|
|
93
97
|
{...rest}
|
|
94
98
|
>
|
|
95
99
|
<div ref={containerRef} className="n-search-container">
|
|
96
|
-
{modalState.current === 'ask' &&
|
|
100
|
+
{modalState.current === 'ask' && (
|
|
101
|
+
<AskNetlify setModalState={setModalState} kapaIntegrationId={props.kapaIntegrationId} />
|
|
102
|
+
)}
|
|
97
103
|
{modalState.current === 'search' && (
|
|
98
104
|
<>
|
|
99
105
|
<SearchInput setSearchTerm={actions.setSearchTerm} initialValue={state.searchTerm} />
|
|
100
106
|
|
|
101
107
|
<SearchWindow
|
|
102
|
-
setModalState={setModalState}
|
|
103
108
|
searchLoading={state.isLoading}
|
|
104
109
|
searchTerm={state.searchTerm}
|
|
105
110
|
results={state.results}
|
|
106
111
|
>
|
|
107
|
-
|
|
112
|
+
<>
|
|
113
|
+
{props.kapaIntegrationId && (
|
|
114
|
+
<SearchLink
|
|
115
|
+
as="button"
|
|
116
|
+
icon="askNetlify"
|
|
117
|
+
label="Ask Netlify AI"
|
|
118
|
+
onClick={() => {
|
|
119
|
+
setModalState({ current: 'ask' });
|
|
120
|
+
}}
|
|
121
|
+
/>
|
|
122
|
+
)}
|
|
123
|
+
{children}
|
|
124
|
+
</>
|
|
108
125
|
</SearchWindow>
|
|
109
126
|
|
|
110
127
|
<div className="n-search-footer">
|
|
@@ -45,7 +45,6 @@ const SearchResults: FunctionComponent<SearchResultsProps> = ({
|
|
|
45
45
|
|
|
46
46
|
/* --- Main Search Results Component --- */
|
|
47
47
|
export default function SearchWindow({
|
|
48
|
-
setModalState,
|
|
49
48
|
searchLoading,
|
|
50
49
|
searchTerm,
|
|
51
50
|
results,
|
|
@@ -58,15 +57,6 @@ export default function SearchWindow({
|
|
|
58
57
|
<SearchResults searchLoading={searchLoading} searchTerm={searchTerm} results={results} />
|
|
59
58
|
) : DefaultWindow ? (
|
|
60
59
|
<>
|
|
61
|
-
<SearchLink
|
|
62
|
-
as="button"
|
|
63
|
-
icon="askNetlify"
|
|
64
|
-
label="Ask Netlify AI"
|
|
65
|
-
onClick={() => {
|
|
66
|
-
setModalState({ current: 'ask' });
|
|
67
|
-
}}
|
|
68
|
-
/>
|
|
69
|
-
|
|
70
60
|
{DefaultWindow}
|
|
71
61
|
|
|
72
62
|
<SearchHeading>Actions</SearchHeading>
|