@actioneer/ads 0.6.0 → 0.8.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.
Files changed (123) hide show
  1. package/DESIGN.md +597 -0
  2. package/components/ai-elements/agent-trace.d.ts +2 -2
  3. package/components/ai-elements/agent-trace.js +164 -105
  4. package/components/ai-elements/chain-of-thought.d.ts +2 -2
  5. package/components/ai-elements/chain-of-thought.js +1 -1
  6. package/components/ai-elements/index.d.ts +0 -5
  7. package/components/ai-elements/inline-citation.js +1 -1
  8. package/components/alert.d.ts +6 -6
  9. package/components/alert.js +89 -53
  10. package/components/answer-sources.d.ts +2 -6
  11. package/components/answer-sources.js +58 -60
  12. package/components/answer.d.ts +5 -0
  13. package/components/answer.js +311 -271
  14. package/components/assistant-ui/action-bar.js +1 -1
  15. package/components/assistant-ui/attachment.js +11 -11
  16. package/components/assistant-ui/badge.js +18 -18
  17. package/components/assistant-ui/composer-harness.js +15 -20
  18. package/components/assistant-ui/composer-trigger-popover.js +9 -9
  19. package/components/assistant-ui/composer.d.ts +3 -1
  20. package/components/assistant-ui/composer.js +148 -144
  21. package/components/assistant-ui/image.js +61 -61
  22. package/components/assistant-ui/index.d.ts +0 -3
  23. package/components/assistant-ui/message-timing.js +1 -1
  24. package/components/assistant-ui/selection-toolbar.js +7 -7
  25. package/components/assistant-ui/thread-context.d.ts +3 -1
  26. package/components/assistant-ui/thread.js +50 -42
  27. package/components/avatar.js +42 -42
  28. package/components/badge.d.ts +5 -6
  29. package/components/badge.js +13 -76
  30. package/components/body-page-header.d.ts +15 -0
  31. package/components/body-page-header.js +24 -0
  32. package/components/brand-loader.d.ts +0 -3
  33. package/components/brand-loader.js +10 -32
  34. package/components/breadcrumbs.d.ts +0 -7
  35. package/components/breadcrumbs.js +54 -71
  36. package/components/button.d.ts +1 -1
  37. package/components/button.js +55 -49
  38. package/components/chart.js +298 -296
  39. package/components/chip.d.ts +13 -1
  40. package/components/chip.js +93 -80
  41. package/components/collection-header.d.ts +17 -0
  42. package/components/collection-header.js +31 -0
  43. package/components/connector-card.d.ts +6 -6
  44. package/components/connector-card.js +31 -32
  45. package/components/date-range-picker.d.ts +2 -1
  46. package/components/date-range-picker.js +158 -122
  47. package/components/divider.js +25 -25
  48. package/components/drawer.d.ts +6 -2
  49. package/components/drawer.js +61 -58
  50. package/components/dropdown.d.ts +1 -2
  51. package/components/dropdown.js +88 -89
  52. package/components/field.js +41 -36
  53. package/components/file-dropzone.js +1 -1
  54. package/components/index.d.ts +4 -4
  55. package/components/index.js +501 -549
  56. package/components/infinite-canvas.js +24 -24
  57. package/components/input-field.d.ts +18 -3
  58. package/components/input-field.js +88 -72
  59. package/components/input.js +32 -29
  60. package/components/modal.d.ts +31 -3
  61. package/components/modal.js +244 -170
  62. package/components/number-field.js +45 -42
  63. package/components/page-body.d.ts +12 -0
  64. package/components/page-body.js +18 -0
  65. package/components/pagination.js +36 -36
  66. package/components/pixel-blast-svg.js +71 -73
  67. package/components/select.d.ts +21 -0
  68. package/components/select.js +189 -148
  69. package/components/setting-row.d.ts +6 -5
  70. package/components/setting-row.js +33 -32
  71. package/components/sidebar.d.ts +2 -0
  72. package/components/sidebar.js +151 -141
  73. package/components/skeleton.js +8 -7
  74. package/components/slider.js +1 -1
  75. package/components/surface-loader.d.ts +11 -0
  76. package/components/surface-loader.js +35 -0
  77. package/components/table.d.ts +16 -10
  78. package/components/table.js +427 -412
  79. package/components/tabs.d.ts +2 -0
  80. package/components/tabs.js +160 -295
  81. package/components/textarea.js +9 -9
  82. package/components/toast.d.ts +1 -1
  83. package/components/toast.js +181 -118
  84. package/components/tree.d.ts +5 -1
  85. package/components/tree.js +54 -49
  86. package/components/typography.d.ts +4 -4
  87. package/components/typography.js +13 -13
  88. package/components/ui/button.d.ts +1 -1
  89. package/components/ui/button.js +4 -4
  90. package/components/ui/dialog.js +25 -25
  91. package/demo/components/add-to-artifact.js +6 -10
  92. package/lib/cn.js +11 -4
  93. package/lib/icons.d.ts +4 -0
  94. package/lib/icons.js +103 -102
  95. package/lib/interactive.d.ts +1 -1
  96. package/llms.txt +132 -188
  97. package/manifest.json +1719 -2831
  98. package/package.json +2 -2
  99. package/styles.css +362 -233
  100. package/theme.css +312 -177
  101. package/components/agent-icon.d.ts +0 -76
  102. package/components/agent-icon.js +0 -265
  103. package/components/ai-elements/queue.d.ts +0 -60
  104. package/components/ai-elements/queue.js +0 -193
  105. package/components/ai-elements/speech-input.d.ts +0 -16
  106. package/components/ai-elements/speech-input.js +0 -151
  107. package/components/ai-elements/task-progress.d.ts +0 -41
  108. package/components/ai-elements/task-progress.js +0 -224
  109. package/components/ai-elements/task.d.ts +0 -39
  110. package/components/ai-elements/task.js +0 -105
  111. package/components/ai-elements/voice.d.ts +0 -90
  112. package/components/ai-elements/voice.js +0 -496
  113. package/components/assistant-ui/follow-up-suggestions.d.ts +0 -11
  114. package/components/assistant-ui/follow-up-suggestions.js +0 -72
  115. package/components/assistant-ui/suggestions.d.ts +0 -7
  116. package/components/assistant-ui/suggestions.js +0 -19
  117. package/components/assistant-ui/voice.d.ts +0 -18
  118. package/components/link.d.ts +0 -14
  119. package/components/link.js +0 -72
  120. package/components/navbar.d.ts +0 -15
  121. package/components/navbar.js +0 -68
  122. package/components/pixel-icon.d.ts +0 -37
  123. package/components/pixel-icon.js +0 -859
@@ -1,48 +1,48 @@
1
1
  "use client";
2
2
  import { jsxs as u, jsx as l } from "react/jsx-runtime";
3
3
  import * as j from "react";
4
- import { ChevronLeft as k, MoreHorizontal as L, ChevronRight as G } from "../lib/icons.js";
4
+ import { ChevronLeft as L, MoreHorizontal as k, ChevronRight as G } from "../lib/icons.js";
5
5
  import { cn as o } from "../lib/cn.js";
6
6
  import { Select as M } from "./select.js";
7
- function p(e, r) {
8
- const t = [];
9
- for (let i = e; i <= r; i += 1) t.push(i);
10
- return t;
7
+ function p(t, s) {
8
+ const e = [];
9
+ for (let r = t; r <= s; r += 1) e.push(r);
10
+ return e;
11
11
  }
12
- function E(e, r, t) {
13
- if (t * 2 + 5 >= e)
14
- return p(1, e);
15
- const m = Math.max(r - t, 1), s = Math.min(r + t, e), d = m > 2, a = s < e - 1;
12
+ function E(t, s, e) {
13
+ if (e * 2 + 5 >= t)
14
+ return p(1, t);
15
+ const m = Math.max(s - e, 1), i = Math.min(s + e, t), d = m > 2, a = i < t - 1;
16
16
  if (!d && a) {
17
- const c = t * 2 + 3;
18
- return [...p(1, c), "end-ellipsis", e];
17
+ const c = e * 2 + 3;
18
+ return [...p(1, c), "end-ellipsis", t];
19
19
  }
20
20
  if (d && !a) {
21
- const c = t * 2 + 3;
22
- return [1, "start-ellipsis", ...p(e - c + 1, e)];
21
+ const c = e * 2 + 3;
22
+ return [1, "start-ellipsis", ...p(t - c + 1, t)];
23
23
  }
24
24
  return [
25
25
  1,
26
26
  "start-ellipsis",
27
- ...p(m, s),
27
+ ...p(m, i),
28
28
  "end-ellipsis",
29
- e
29
+ t
30
30
  ];
31
31
  }
32
- const A = (e) => o(
32
+ const A = () => o(
33
33
  "inline-flex items-center justify-center rounded-md font-normal",
34
34
  "outline-none focus-visible:ring-3 focus-visible:ring-ring",
35
35
  "transition active:scale-[0.97] motion-reduce:transition-none motion-reduce:active:scale-100",
36
36
  "disabled:pointer-events-none disabled:opacity-40",
37
- e === "sm" ? "size-7 text-xs" : "size-9 text-xs"
38
- ), N = (e) => e === "sm" ? "w-auto gap-1.5 px-2" : "w-auto gap-1.5 px-2.5", F = j.forwardRef(
37
+ "size-6 text-xs"
38
+ ), N = (t) => t === "sm" ? "w-auto gap-1.5 px-2" : "w-auto gap-1.5 px-2.5", F = j.forwardRef(
39
39
  ({
40
- className: e,
41
- total: r,
42
- page: t,
43
- onChange: i,
40
+ className: t,
41
+ total: s,
42
+ page: e,
43
+ onChange: r,
44
44
  siblings: m = 1,
45
- size: s = "md",
45
+ size: i = "md",
46
46
  summary: d,
47
47
  labels: a = !1,
48
48
  pageSize: c,
@@ -50,8 +50,8 @@ const A = (e) => o(
50
50
  onPageSizeChange: g,
51
51
  ...C
52
52
  }, y) => {
53
- if (r <= 0) return null;
54
- const P = E(r, t, m), R = t <= 1, S = t >= r, f = A(s), x = s === "sm" ? "size-3.5" : "size-4", h = c != null && !!g, b = d != null || h;
53
+ if (s <= 0) return null;
54
+ const P = E(s, e, m), R = e <= 1, S = e >= s, f = A(), x = i === "sm" ? "size-3.5" : "size-4", h = c != null && !!g, b = d != null || h;
55
55
  return /* @__PURE__ */ u(
56
56
  "nav",
57
57
  {
@@ -60,7 +60,7 @@ const A = (e) => o(
60
60
  className: o(
61
61
  "flex items-center",
62
62
  b ? "w-full justify-between gap-4" : "gap-1",
63
- e
63
+ t
64
64
  ),
65
65
  ...C,
66
66
  children: [
@@ -88,7 +88,7 @@ const A = (e) => o(
88
88
  M,
89
89
  {
90
90
  size: "sm",
91
- className: "w-18",
91
+ className: "w-18 text-s font-normal",
92
92
  placement: "top",
93
93
  items: (w ?? [8, 16, 32]).map((n) => ({
94
94
  label: String(n),
@@ -108,14 +108,14 @@ const A = (e) => o(
108
108
  type: "button",
109
109
  "aria-label": "Go to previous page",
110
110
  disabled: R,
111
- onClick: () => i(t - 1),
111
+ onClick: () => r(e - 1),
112
112
  className: o(
113
113
  f,
114
114
  "text-foreground hover:bg-muted",
115
- a && N(s)
115
+ a && N(i)
116
116
  ),
117
117
  children: [
118
- /* @__PURE__ */ l(k, { className: x, "aria-hidden": !0 }),
118
+ /* @__PURE__ */ l(L, { className: x, "aria-hidden": !0 }),
119
119
  a && "Prev"
120
120
  ]
121
121
  }
@@ -127,21 +127,21 @@ const A = (e) => o(
127
127
  {
128
128
  "aria-hidden": !0,
129
129
  className: o(f, "text-muted-foreground"),
130
- children: /* @__PURE__ */ l(L, { className: x })
130
+ children: /* @__PURE__ */ l(k, { className: x })
131
131
  },
132
132
  n
133
133
  );
134
- const v = n === t;
134
+ const v = n === e;
135
135
  return /* @__PURE__ */ l(
136
136
  "button",
137
137
  {
138
138
  type: "button",
139
139
  "aria-label": `Go to page ${n}`,
140
140
  "aria-current": v ? "page" : void 0,
141
- onClick: () => i(n),
141
+ onClick: () => r(n),
142
142
  className: o(
143
143
  f,
144
- v ? "bg-foreground text-background" : "text-foreground hover:bg-muted"
144
+ v ? "bg-wg10 text-brand-foreground" : "text-foreground hover:bg-muted"
145
145
  ),
146
146
  children: n
147
147
  },
@@ -154,11 +154,11 @@ const A = (e) => o(
154
154
  type: "button",
155
155
  "aria-label": "Go to next page",
156
156
  disabled: S,
157
- onClick: () => i(t + 1),
157
+ onClick: () => r(e + 1),
158
158
  className: o(
159
159
  f,
160
160
  "text-foreground hover:bg-muted",
161
- a && N(s)
161
+ a && N(i)
162
162
  ),
163
163
  children: [
164
164
  a && "Next",
@@ -1,19 +1,19 @@
1
1
  "use client";
2
2
  import { jsx as u } from "react/jsx-runtime";
3
3
  import * as c from "react";
4
- import { ditheringFragmentShader as g, getShaderColorFromString as M, ShaderFitOptions as N, DitheringTypes as L, DitheringShapes as m } from "@paper-design/shaders";
5
- import { ShaderMount as F } from "@paper-design/shaders-react";
6
- import { useReducedMotion as I } from "motion/react";
7
- import { cn as P } from "../lib/cn.js";
8
- const z = {
4
+ import { ditheringFragmentShader as h, getShaderColorFromString as T, ShaderFitOptions as P, DitheringTypes as z, DitheringShapes as g } from "@paper-design/shaders";
5
+ import { ShaderMount as D } from "@paper-design/shaders-react";
6
+ import { useReducedMotion as F } from "motion/react";
7
+ import { cn as L } from "../lib/cn.js";
8
+ const A = {
9
9
  alpha: !0,
10
10
  antialias: !1,
11
11
  depth: !1,
12
12
  powerPreference: "low-power",
13
13
  preserveDrawingBuffer: !1
14
- }, O = 1e6, B = `uniform float u_type;
14
+ }, B = 1e6, b = `uniform float u_type;
15
15
  uniform float u_patternDensity;
16
- uniform float u_pixelSizeJitter;`, k = " float res = step(.5, shape + dithering);", G = ` vec2 triangleUV = fract(pxSizeUV);
16
+ uniform float u_pixelSizeJitter;`, V = " float res = step(.5, shape + dithering);", G = ` vec2 triangleUV = fract(pxSizeUV);
17
17
  vec2 triangleCell = floor(pxSizeUV);
18
18
  float triangleFlip = mod(triangleCell.x + triangleCell.y, 2.0);
19
19
  triangleUV.x = mix(triangleUV.x, 1.0 - triangleUV.x, triangleFlip);
@@ -29,61 +29,59 @@ uniform float u_pixelSizeJitter;`, k = " float res = step(.5, shape + dithering
29
29
  float triangleMask = 1.0 - step(1.0, triangleDiagonal);
30
30
  float densityThreshold = 0.5 - (u_patternDensity - 1.0) * 0.12;
31
31
  float res = step(densityThreshold, shape + dithering) * triangleMask;`;
32
- if (!g.includes("uniform float u_type;") || !g.includes(k))
32
+ if (!h.includes("uniform float u_type;") || !h.includes(V))
33
33
  throw new Error("The Paper dithering shader no longer exposes the expected cell output.");
34
- const b = g.replace("uniform float u_type;", B).replace(k, G), d = (e) => Math.max(0, Math.min(1, e)), J = "#202020", W = "#ffffff";
35
- function X(e, t) {
36
- if (typeof document > "u") return t;
37
- const r = (o, i = 0) => {
38
- if (i > 4) return o;
39
- const n = o.trim(), a = n.match(/^var\((--[\w-]+)(?:,\s*(.+))?\)$/);
40
- if (!a) return n;
41
- const s = getComputedStyle(document.documentElement).getPropertyValue(a[1]).trim();
42
- return s ? r(s, i + 1) : a[2] ? r(a[2], i + 1) : t;
34
+ const O = h.replace("uniform float u_type;", b).replace(V, G), d = (e) => Math.max(0, Math.min(1, e));
35
+ function J(e) {
36
+ if (typeof document > "u") return null;
37
+ const t = (r, o = 0) => {
38
+ if (o > 4) return r;
39
+ const i = r.trim(), a = i.match(/^var\((--[\w-]+)(?:,\s*(.+))?\)$/);
40
+ if (!a) return i;
41
+ const l = getComputedStyle(document.documentElement).getPropertyValue(a[1]).trim();
42
+ return l ? t(l, o + 1) : a[2] ? t(a[2], o + 1) : null;
43
43
  };
44
- return r(e) || t;
44
+ return t(e);
45
45
  }
46
- function E(e, t) {
47
- const [r, o] = c.useState(
48
- () => e.startsWith("var(") ? t : e
46
+ function k(e) {
47
+ const [t, r] = c.useState(
48
+ () => e.startsWith("var(") ? null : e
49
49
  );
50
50
  return c.useEffect(() => {
51
- o(X(e, t));
52
- }, [t, e]), r;
51
+ r(J(e));
52
+ }, [e]), t;
53
53
  }
54
- const $ = c.forwardRef(
54
+ const W = c.forwardRef(
55
55
  ({
56
56
  variant: e = "custom",
57
57
  color: t = "var(--texture-ink)",
58
58
  pixelSize: r = 7,
59
59
  speed: o = 3,
60
60
  patternScale: i = 3,
61
- patternDensity: n = 1.8,
62
- pixelSizeJitter: a = 0.5,
63
- enableRipples: s = !1,
64
- liquid: p = !1,
65
- toneAmount: h = 0,
66
- edgeFade: R = 0.25,
67
- transparent: f = !0,
68
- backgroundColor: _ = "var(--color-background)",
69
- paused: x = !1,
70
- className: V,
71
- style: D
72
- }, w) => {
73
- const S = I(), U = E(t, J), C = E(
74
- _,
75
- W
76
- ), l = d(R) * 100, T = `linear-gradient(to right, transparent 0%, black ${l}%, black ${100 - l}%, transparent 100%)`, v = `linear-gradient(to bottom, transparent 0%, black ${l}%, black ${100 - l}%, transparent 100%)`, A = c.useMemo(() => {
77
- const y = M(U);
78
- return y[3] *= 1 - d(h), {
79
- u_colorBack: f ? [0, 0, 0, 0] : M(C),
80
- u_colorFront: y,
81
- u_shape: s ? m.ripple : p ? m.warp : m.simplex,
82
- u_type: L["4x4"],
61
+ patternDensity: a = 1.8,
62
+ pixelSizeJitter: l = 0.5,
63
+ enableRipples: p = !1,
64
+ liquid: _ = !1,
65
+ toneAmount: x = 0,
66
+ edgeFade: E = 0.25,
67
+ transparent: n = !0,
68
+ backgroundColor: v = "var(--color-background)",
69
+ paused: S = !1,
70
+ className: N,
71
+ style: R
72
+ }, I) => {
73
+ const y = F(), f = k(t), m = k(v), s = d(E) * 100, C = `linear-gradient(to right, transparent 0%, var(--color-wg12) ${s}%, var(--color-wg12) ${100 - s}%, transparent 100%)`, M = `linear-gradient(to bottom, transparent 0%, var(--color-wg12) ${s}%, var(--color-wg12) ${100 - s}%, transparent 100%)`, U = c.useMemo(() => {
74
+ if (!f || !n && !m) return null;
75
+ const w = T(f);
76
+ return w[3] *= 1 - d(x), {
77
+ u_colorBack: n ? [0, 0, 0, 0] : T(m),
78
+ u_colorFront: w,
79
+ u_shape: p ? g.ripple : _ ? g.warp : g.simplex,
80
+ u_type: z["4x4"],
83
81
  u_pxSize: Math.max(1, r),
84
- u_patternDensity: Math.max(0.1, n),
85
- u_pixelSizeJitter: d(a),
86
- u_fit: N.none,
82
+ u_patternDensity: Math.max(0.1, a),
83
+ u_pixelSizeJitter: d(l),
84
+ u_fit: P.none,
87
85
  u_scale: Math.max(0.01, i),
88
86
  u_rotation: 0,
89
87
  u_offsetX: 0,
@@ -94,52 +92,52 @@ const $ = c.forwardRef(
94
92
  u_worldHeight: 0
95
93
  };
96
94
  }, [
97
- s,
98
95
  p,
99
- n,
96
+ _,
97
+ a,
100
98
  i,
101
99
  r,
102
- a,
103
- C,
104
- U,
105
- h,
106
- f
100
+ l,
101
+ m,
102
+ f,
103
+ x,
104
+ n
107
105
  ]);
108
106
  return /* @__PURE__ */ u(
109
107
  "div",
110
108
  {
111
- ref: w,
109
+ ref: I,
112
110
  "aria-hidden": !0,
113
- "data-shader-paused": x || S ? "true" : "false",
114
- className: P("pixel-blast-svg", V),
111
+ "data-shader-paused": S || y ? "true" : "false",
112
+ className: L("pixel-blast-svg", N),
115
113
  style: {
116
- ...D,
117
- background: f ? "transparent" : _
114
+ ...R,
115
+ background: n ? "transparent" : v
118
116
  },
119
117
  children: /* @__PURE__ */ u(
120
118
  "div",
121
119
  {
122
120
  className: "size-full",
123
- style: { WebkitMaskImage: T, maskImage: T },
121
+ style: { WebkitMaskImage: C, maskImage: C },
124
122
  children: /* @__PURE__ */ u(
125
123
  "div",
126
124
  {
127
125
  className: "size-full",
128
- style: { WebkitMaskImage: v, maskImage: v },
129
- children: /* @__PURE__ */ u(
130
- F,
126
+ style: { WebkitMaskImage: M, maskImage: M },
127
+ children: U ? /* @__PURE__ */ u(
128
+ D,
131
129
  {
132
130
  className: "size-full",
133
131
  width: "100%",
134
132
  height: "100%",
135
- fragmentShader: b,
136
- uniforms: A,
137
- speed: x || S ? 0 : o,
133
+ fragmentShader: O,
134
+ uniforms: U,
135
+ speed: S || y ? 0 : o,
138
136
  minPixelRatio: 1,
139
- maxPixelCount: O,
140
- webGlContextAttributes: z
137
+ maxPixelCount: B,
138
+ webGlContextAttributes: A
141
139
  }
142
- )
140
+ ) : null
143
141
  }
144
142
  )
145
143
  }
@@ -148,7 +146,7 @@ const $ = c.forwardRef(
148
146
  );
149
147
  }
150
148
  );
151
- $.displayName = "PixelBlastSVG";
149
+ W.displayName = "PixelBlastSVG";
152
150
  export {
153
- $ as PixelBlastSVG
151
+ W as PixelBlastSVG
154
152
  };
@@ -8,6 +8,26 @@ export interface SelectItem {
8
8
  value: string;
9
9
  disabled?: boolean;
10
10
  }
11
+ export interface DropdownOptionsProps {
12
+ items: SelectItem[];
13
+ value?: string;
14
+ values?: string[];
15
+ multiple?: boolean;
16
+ activeIndex?: number;
17
+ onActiveIndexChange?: (index: number) => void;
18
+ onItemSelect?: (index: number) => void;
19
+ placement?: "top" | "bottom";
20
+ id?: string;
21
+ className?: string;
22
+ style?: React.CSSProperties;
23
+ "aria-label"?: string;
24
+ }
25
+ /**
26
+ * DropdownOptions — the reusable options surface composed by Select.
27
+ * It owns listbox semantics and the brand-green option interaction treatment;
28
+ * positioning and open/closed state stay with the parent Select.
29
+ */
30
+ export declare const DropdownOptions: React.ForwardRefExoticComponent<DropdownOptionsProps & React.RefAttributes<HTMLUListElement>>;
11
31
  export interface SelectProps extends VariantProps<typeof selectTriggerVariants> {
12
32
  items: SelectItem[];
13
33
  value?: string;
@@ -15,6 +35,7 @@ export interface SelectProps extends VariantProps<typeof selectTriggerVariants>
15
35
  multiple?: boolean;
16
36
  values?: string[];
17
37
  onValuesChange?: (values: string[]) => void;
38
+ /** Empty-state trigger copy. Defaults to "Select" and inherits tertiary text. */
18
39
  placeholder?: string;
19
40
  disabled?: boolean;
20
41
  isInvalid?: boolean;