@burdenoff/microfe-technospam 2026.1031.8 → 2026.1101.2

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 (29) hide show
  1. package/dist/generated/wspace-types.d.ts +288 -0
  2. package/dist/generated/wspace-types.d.ts.map +1 -1
  3. package/dist/stories/journeys/Problems.stories.d.ts.map +1 -1
  4. package/dist/technospam/api/technospamApi.d.ts +15 -0
  5. package/dist/technospam/api/technospamApi.d.ts.map +1 -1
  6. package/dist/technospam/api/technospamApi.js +200 -151
  7. package/dist/technospam/api/technospamApi.js.map +1 -1
  8. package/dist/technospam/components/ProblemsTable.d.ts +19 -0
  9. package/dist/technospam/components/ProblemsTable.d.ts.map +1 -0
  10. package/dist/technospam/components/ProblemsTable.js +117 -0
  11. package/dist/technospam/components/ProblemsTable.js.map +1 -0
  12. package/dist/technospam/components/index.d.ts +1 -0
  13. package/dist/technospam/components/index.d.ts.map +1 -1
  14. package/dist/technospam/components/index.js +2 -1
  15. package/dist/technospam/pages/ApplicationsProblemDetailsPagePage.js +38 -38
  16. package/dist/technospam/pages/ApplicationsProblemDetailsPagePage.js.map +1 -1
  17. package/dist/technospam/pages/ApplicationsProblemsPagePage.d.ts.map +1 -1
  18. package/dist/technospam/pages/ApplicationsProblemsPagePage.js +197 -144
  19. package/dist/technospam/pages/ApplicationsProblemsPagePage.js.map +1 -1
  20. package/dist/technospam/pages/CoursesCourseDetailsPagePage.js +195 -195
  21. package/dist/technospam/pages/CoursesCourseDetailsPagePage.js.map +1 -1
  22. package/dist/technospam/pages/CoursesCoursesPagePage.js +26 -26
  23. package/dist/technospam/pages/CoursesLessonPlayerPagePage.js +36 -36
  24. package/dist/technospam/pages/CoursesLessonPlayerPagePage.js.map +1 -1
  25. package/dist/technospam/utils/problemCatalog.d.ts +27 -0
  26. package/dist/technospam/utils/problemCatalog.d.ts.map +1 -0
  27. package/dist/technospam/utils/problemCatalog.js +68 -0
  28. package/dist/technospam/utils/problemCatalog.js.map +1 -0
  29. package/package.json +1 -1
@@ -5,105 +5,107 @@ import { PageLayout as i } from "../components/PageLayout.js";
5
5
  import { StatCard as a } from "../components/StatCard.js";
6
6
  import { MediaCover as o, topicIcon as s } from "../components/MediaCover.js";
7
7
  import { StatusBadge as c } from "../components/StatusBadge.js";
8
- import { LoadMore as l } from "../components/LoadMore.js";
9
- import { EmptyView as ee, ErrorView as te, LoadingGrid as u } from "../components/StateViews.js";
8
+ import { readProblemCatalogView as l, safeLocalStorage as u, writeProblemCatalogView as ee } from "../utils/problemCatalog.js";
10
9
  import { PremiumBadge as d } from "../components/UpgradeGate.js";
11
- import { pageArg as ne, usePageLimit as f, useProblemsQuery as p, useSubmissionsQuery as m } from "../api/technospamApi.js";
10
+ import { ProblemsTable as f } from "../components/ProblemsTable.js";
11
+ import { LoadMore as te } from "../components/LoadMore.js";
12
+ import { EmptyView as p, ErrorView as m, LoadingGrid as ne } from "../components/StateViews.js";
13
+ import { pageArg as re, usePageLimit as ie, useProblemsQuery as h, useSolvedProblemIds as ae } from "../api/technospamApi.js";
12
14
  import "../components/index.js";
13
- import { TAB_PANEL_FOCUS_CLASS as re } from "../lib/a11y.js";
14
- import { useMemo as h, useState as g } from "react";
15
- import { Building2 as _, CheckCircle2 as v, Code2 as y, Flame as b, Gauge as ie, Layers as x, Search as ae, Tag as S, Trophy as C } from "lucide-react";
16
- import { jsx as w, jsxs as T } from "react/jsx-runtime";
17
- import { Badge as E, GlassCard as D, Input as oe, Select as O, SelectContent as k, SelectItem as A, SelectTrigger as j, SelectValue as M, Tabs as N, TabsContent as P, TabsList as F, TabsTrigger as I } from "@burdenoff/fe-libs/ui";
15
+ import { TAB_PANEL_FOCUS_CLASS as oe } from "../lib/a11y.js";
16
+ import { useCallback as g, useMemo as _, useState as v } from "react";
17
+ import { Building2 as y, CheckCircle2 as b, Code2 as x, Flame as S, Gauge as se, Layers as C, LayoutGrid as w, List as ce, Search as le, Tag as T, Trophy as E } from "lucide-react";
18
+ import { jsx as D, jsxs as O } from "react/jsx-runtime";
19
+ import { Badge as k, Button as A, GlassCard as j, Input as ue, Select as M, SelectContent as N, SelectItem as P, SelectTrigger as F, SelectValue as I, Tabs as L, TabsContent as R, TabsList as z, TabsTrigger as B } from "@burdenoff/fe-libs/ui";
18
20
  //#region src/technospam/pages/ApplicationsProblemsPagePage.tsx
19
- function L({ problem: e, solved: t, onOpen: n }) {
21
+ function V({ problem: e, solved: t, onOpen: n }) {
20
22
  let i = r();
21
- return /* @__PURE__ */ T(D, {
23
+ return /* @__PURE__ */ O(j, {
22
24
  className: "group flex cursor-pointer flex-col overflow-hidden transition-all duration-200 hover:-translate-y-1 hover:shadow-lg",
23
25
  onClick: n,
24
- children: [/* @__PURE__ */ T(o, {
26
+ children: [/* @__PURE__ */ O(o, {
25
27
  seed: `${e.topic ?? ""} ${e.difficulty} ${e.title}`,
26
28
  icon: s(e.topic ?? e.title),
27
- children: [t ? /* @__PURE__ */ T("span", {
29
+ children: [t ? /* @__PURE__ */ O("span", {
28
30
  className: "inline-flex items-center gap-1 rounded-full bg-status-success-bg-subtle px-2 py-0.5 text-[11px] font-medium text-status-success-text ring-1 ring-status-success-border/30",
29
31
  children: [
30
- /* @__PURE__ */ w(v, { size: 12 }),
32
+ /* @__PURE__ */ D(b, { size: 12 }),
31
33
  " ",
32
34
  i("technospam.problems.solved", "Solved")
33
35
  ]
34
- }) : /* @__PURE__ */ w("span", {}), /* @__PURE__ */ T("div", {
36
+ }) : /* @__PURE__ */ D("span", {}), /* @__PURE__ */ O("div", {
35
37
  className: "flex flex-wrap items-center gap-1.5",
36
- children: [/* @__PURE__ */ w(c, {
38
+ children: [/* @__PURE__ */ D(c, {
37
39
  status: e.difficulty,
38
40
  kind: "level"
39
- }), e.isPremiumOnly ? /* @__PURE__ */ w(d, { locked: e.isLocked }) : null]
41
+ }), e.isPremiumOnly ? /* @__PURE__ */ D(d, { locked: e.isLocked }) : null]
40
42
  })]
41
- }), /* @__PURE__ */ T("div", {
43
+ }), /* @__PURE__ */ O("div", {
42
44
  className: "flex flex-1 flex-col gap-3 p-4",
43
45
  children: [
44
- /* @__PURE__ */ T("div", {
46
+ /* @__PURE__ */ O("div", {
45
47
  className: "min-w-0",
46
- children: [/* @__PURE__ */ w("h3", {
48
+ children: [/* @__PURE__ */ D("h3", {
47
49
  className: "truncate text-base font-semibold text-text-primary group-hover:text-accent-primary",
48
50
  children: e.title
49
- }), e.statement ? /* @__PURE__ */ w("p", {
51
+ }), e.statement ? /* @__PURE__ */ D("p", {
50
52
  className: "mt-1 line-clamp-2 text-sm text-text-secondary",
51
53
  children: e.statement
52
54
  }) : null]
53
55
  }),
54
- /* @__PURE__ */ T("div", {
56
+ /* @__PURE__ */ O("div", {
55
57
  className: "mt-auto flex flex-wrap items-center gap-3 text-xs text-text-muted",
56
58
  children: [
57
- e.topic ? /* @__PURE__ */ T("span", {
59
+ e.topic ? /* @__PURE__ */ O("span", {
58
60
  className: "inline-flex items-center gap-1",
59
61
  children: [
60
- /* @__PURE__ */ w(x, { size: 13 }),
62
+ /* @__PURE__ */ D(C, { size: 13 }),
61
63
  " ",
62
64
  e.topic
63
65
  ]
64
66
  }) : null,
65
- /* @__PURE__ */ T("span", {
67
+ /* @__PURE__ */ O("span", {
66
68
  className: "inline-flex items-center gap-1",
67
69
  children: [
68
- /* @__PURE__ */ w(C, { size: 13 }),
70
+ /* @__PURE__ */ D(E, { size: 13 }),
69
71
  " ",
70
72
  i("technospam.problems.points", "{{count}} pts", { count: e.points })
71
73
  ]
72
74
  }),
73
- e.languages.length ? /* @__PURE__ */ T("span", {
75
+ e.languages.length ? /* @__PURE__ */ O("span", {
74
76
  className: "inline-flex items-center gap-1",
75
77
  children: [
76
- /* @__PURE__ */ w(y, { size: 13 }),
78
+ /* @__PURE__ */ D(x, { size: 13 }),
77
79
  " ",
78
80
  e.languages.length === 1 ? i("technospam.problems.languages", "{{count}} lang", { count: e.languages.length }) : i("technospam.problems.languagesPlural", "{{count}} langs", { count: e.languages.length })
79
81
  ]
80
82
  }) : null
81
83
  ]
82
84
  }),
83
- e.companies.length ? /* @__PURE__ */ T("div", {
85
+ e.companies.length ? /* @__PURE__ */ O("div", {
84
86
  className: "flex flex-wrap gap-1.5",
85
- children: [e.companies.slice(0, 3).map((e) => /* @__PURE__ */ T(E, {
87
+ children: [e.companies.slice(0, 3).map((e) => /* @__PURE__ */ O(k, {
86
88
  variant: "outline",
87
89
  className: "text-[11px] capitalize",
88
- children: [/* @__PURE__ */ w(_, {
90
+ children: [/* @__PURE__ */ D(y, {
89
91
  size: 10,
90
92
  className: "mr-1"
91
93
  }), e.replace(/-/g, " ")]
92
- }, e)), e.interviewFrequency === "HIGH" ? /* @__PURE__ */ T(E, {
94
+ }, e)), e.interviewFrequency === "HIGH" ? /* @__PURE__ */ O(k, {
93
95
  variant: "secondary",
94
96
  className: "text-[11px] text-status-warning-text",
95
- children: [/* @__PURE__ */ w(b, {
97
+ children: [/* @__PURE__ */ D(S, {
96
98
  size: 10,
97
99
  className: "mr-1"
98
100
  }), i("technospam.problems.frequentlyAsked", "Frequently asked")]
99
101
  }) : null]
100
102
  }) : null,
101
- e.tags.length ? /* @__PURE__ */ w("div", {
103
+ e.tags.length ? /* @__PURE__ */ D("div", {
102
104
  className: "flex flex-wrap gap-1.5",
103
- children: e.tags.slice(0, 3).map((e) => /* @__PURE__ */ T(E, {
105
+ children: e.tags.slice(0, 3).map((e) => /* @__PURE__ */ O(k, {
104
106
  variant: "secondary",
105
107
  className: "text-[11px]",
106
- children: [/* @__PURE__ */ w(S, {
108
+ children: [/* @__PURE__ */ D(T, {
107
109
  size: 10,
108
110
  className: "mr-1"
109
111
  }), e]
@@ -113,25 +115,27 @@ function L({ problem: e, solved: t, onOpen: n }) {
113
115
  })]
114
116
  });
115
117
  }
116
- function R() {
117
- let o = t(), { currentUser: s, workspaceId: c } = e(), { emit: d } = n(), _ = r(), x = s?.id, [S, C] = g("ALL"), [E, D] = g("ALL"), [R, z] = g("ALL"), [B, V] = g(""), H = h(() => [
118
+ function H() {
119
+ let o = t(), { currentUser: s, workspaceId: c } = e(), { emit: d } = n(), y = r(), C = s?.id, [T, E] = v("ALL"), [k, j] = v("ALL"), [H, de] = v("ALL"), [U, fe] = v(""), [W, pe] = v(() => l(u())), G = g((e) => {
120
+ pe(e), ee(u(), e);
121
+ }, []), me = _(() => [
118
122
  {
119
123
  value: "ALL",
120
- label: _("technospam.problems.filterAll", "All")
124
+ label: y("technospam.problems.filterAll", "All")
121
125
  },
122
126
  {
123
127
  value: "EASY",
124
- label: _("technospam.problems.filterEasy", "Easy")
128
+ label: y("technospam.problems.filterEasy", "Easy")
125
129
  },
126
130
  {
127
131
  value: "MEDIUM",
128
- label: _("technospam.problems.filterMedium", "Medium")
132
+ label: y("technospam.problems.filterMedium", "Medium")
129
133
  },
130
134
  {
131
135
  value: "HARD",
132
- label: _("technospam.problems.filterHard", "Hard")
136
+ label: y("technospam.problems.filterHard", "Hard")
133
137
  }
134
- ], [_]), U = h(() => [
138
+ ], [y]), he = _(() => [
135
139
  {
136
140
  value: "google",
137
141
  label: "Google"
@@ -156,7 +160,7 @@ function R() {
156
160
  value: "netflix",
157
161
  label: "Netflix"
158
162
  }
159
- ], []), W = h(() => [
163
+ ], []), ge = _(() => [
160
164
  {
161
165
  value: "frontend",
162
166
  label: "Frontend"
@@ -181,71 +185,81 @@ function R() {
181
185
  value: "sre",
182
186
  label: "SRE / Infra"
183
187
  }
184
- ], []), { limit: G, more: K } = f(), { data: q, loading: J, error: Y } = p({
188
+ ], []), { limit: _e, more: ve } = ie(), { data: K, loading: q, error: J } = h({
185
189
  status: "PUBLISHED",
186
- pagination: ne(G),
187
- ...S === "ALL" ? {} : { difficulty: S },
188
- ...E === "ALL" ? {} : { company: E },
189
- ...R === "ALL" ? {} : { role: R }
190
- }), { data: X } = m(x ? { learnerId: x } : {}), Z = q?.tecListProblems?.items ?? [], se = q?.tecListProblems?.pageInfo?.hasMore ?? !1, Q = h(() => new Set((X?.tecListSubmissions?.items ?? []).filter((e) => e.verdict === "ACCEPTED").map((e) => e.problemId)), [X]), ce = Z.filter((e) => Q.has(e.id)).length, le = Z.filter((e) => e.difficulty === "EASY").length, ue = Z.filter((e) => e.difficulty === "HARD").length, $ = h(() => {
191
- let e = B.trim().toLowerCase();
192
- return e ? Z.filter((t) => t.title.toLowerCase().includes(e) || (t.topic ?? "").toLowerCase().includes(e) || t.tags.some((t) => t.toLowerCase().includes(e))) : Z;
193
- }, [Z, B]);
194
- return /* @__PURE__ */ T(i, {
190
+ pagination: re(_e),
191
+ ...T === "ALL" ? {} : { difficulty: T },
192
+ ...k === "ALL" ? {} : { company: k },
193
+ ...H === "ALL" ? {} : { role: H }
194
+ }), Y = ae(C), X = _(() => K?.tecListProblems?.items ?? [], [K]), Z = K?.tecListProblems?.pageInfo?.hasMore ?? !1, ye = X.filter((e) => Y.has(e.id)).length, be = X.filter((e) => e.difficulty === "EASY").length, xe = X.filter((e) => e.difficulty === "HARD").length, Q = _(() => {
195
+ let e = U.trim().toLowerCase();
196
+ return e ? X.filter((t) => t.title.toLowerCase().includes(e) || (t.topic ?? "").toLowerCase().includes(e) || t.tags.some((t) => t.toLowerCase().includes(e))) : X;
197
+ }, [X, U]), $ = g((e) => {
198
+ d("technospam.problem.viewed", {
199
+ workspaceId: c,
200
+ entityId: e.id,
201
+ entityType: "TEC_PROBLEM"
202
+ }), o(`/applications/problem-details-page?id=${e.id}`);
203
+ }, [
204
+ d,
205
+ o,
206
+ c
207
+ ]);
208
+ return /* @__PURE__ */ O(i, {
195
209
  hero: !0,
196
- title: _("technospam.problems.title", "Coding Problems"),
197
- description: _("technospam.problems.description", "Sharpen your problem-solving with hands-on, mentor-judged challenges across topics and difficulty."),
198
- children: [/* @__PURE__ */ T("div", {
210
+ title: y("technospam.problems.title", "Coding Problems"),
211
+ description: y("technospam.problems.description", "Sharpen your problem-solving with hands-on, mentor-judged challenges across topics and difficulty."),
212
+ children: [/* @__PURE__ */ O("div", {
199
213
  className: "mb-5 grid grid-cols-2 gap-3 sm:grid-cols-4",
200
214
  children: [
201
- /* @__PURE__ */ w(a, {
202
- label: _("technospam.problems.statProblems", "Problems"),
203
- value: Z.length,
204
- icon: y,
215
+ /* @__PURE__ */ D(a, {
216
+ label: y("technospam.problems.statProblems", "Problems"),
217
+ value: X.length,
218
+ icon: x,
205
219
  tone: "blue"
206
220
  }),
207
- /* @__PURE__ */ w(a, {
208
- label: _("technospam.problems.statSolved", "Solved"),
209
- value: ce,
210
- icon: v,
221
+ /* @__PURE__ */ D(a, {
222
+ label: y("technospam.problems.statSolved", "Solved"),
223
+ value: ye,
224
+ icon: b,
211
225
  tone: "green"
212
226
  }),
213
- /* @__PURE__ */ w(a, {
214
- label: _("technospam.problems.statEasy", "Easy"),
215
- value: le,
216
- icon: ie,
227
+ /* @__PURE__ */ D(a, {
228
+ label: y("technospam.problems.statEasy", "Easy"),
229
+ value: be,
230
+ icon: se,
217
231
  tone: "teal"
218
232
  }),
219
- /* @__PURE__ */ w(a, {
220
- label: _("technospam.problems.statHard", "Hard"),
221
- value: ue,
222
- icon: b,
233
+ /* @__PURE__ */ D(a, {
234
+ label: y("technospam.problems.statHard", "Hard"),
235
+ value: xe,
236
+ icon: S,
223
237
  tone: "amber"
224
238
  })
225
239
  ]
226
- }), /* @__PURE__ */ T(N, {
240
+ }), /* @__PURE__ */ O(L, {
227
241
  className: "gap-0",
228
- value: S,
229
- onValueChange: (e) => C(e),
242
+ value: T,
243
+ onValueChange: (e) => E(e),
230
244
  children: [
231
- /* @__PURE__ */ T("div", {
245
+ /* @__PURE__ */ O("div", {
232
246
  className: "mb-4 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",
233
- children: [/* @__PURE__ */ w(F, { children: H.map((e) => /* @__PURE__ */ w(I, {
247
+ children: [/* @__PURE__ */ D(z, { children: me.map((e) => /* @__PURE__ */ D(B, {
234
248
  value: e.value,
235
249
  children: e.label
236
- }, e.value)) }), /* @__PURE__ */ T("div", {
250
+ }, e.value)) }), /* @__PURE__ */ O("div", {
237
251
  className: "relative w-full sm:w-72",
238
- children: [/* @__PURE__ */ w(ae, {
252
+ children: [/* @__PURE__ */ D(le, {
239
253
  className: "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-text-muted",
240
254
  size: 16
241
- }), /* @__PURE__ */ w(oe, {
255
+ }), /* @__PURE__ */ D(ue, {
242
256
  className: "pl-9",
243
- "aria-label": _("technospam.problems.searchLabel", "Search problems"),
244
- placeholder: _("technospam.problems.searchPlaceholder", "Search problems…"),
245
- value: B,
246
- onChange: (e) => V(e.target.value),
257
+ "aria-label": y("technospam.problems.searchLabel", "Search problems"),
258
+ placeholder: y("technospam.problems.searchPlaceholder", "Search problems…"),
259
+ value: U,
260
+ onChange: (e) => fe(e.target.value),
247
261
  onBlur: () => {
248
- let e = B.trim();
262
+ let e = U.trim();
249
263
  e && d("technospam.search.performed", {
250
264
  workspaceId: c,
251
265
  entityType: "problem",
@@ -255,72 +269,111 @@ function R() {
255
269
  })]
256
270
  })]
257
271
  }),
258
- /* @__PURE__ */ T("div", {
272
+ /* @__PURE__ */ O("div", {
259
273
  className: "mb-4 flex flex-col gap-3 sm:flex-row sm:items-center",
260
- children: [/* @__PURE__ */ T(O, {
261
- value: E,
262
- onValueChange: D,
263
- children: [/* @__PURE__ */ w(j, {
264
- className: "w-full sm:w-48",
265
- "aria-label": _("technospam.problems.companyFilterLabel", "Filter by company"),
266
- children: /* @__PURE__ */ w(M, { placeholder: _("technospam.problems.companyPlaceholder", "Company") })
267
- }), /* @__PURE__ */ T(k, { children: [/* @__PURE__ */ w(A, {
268
- value: "ALL",
269
- children: _("technospam.problems.companyAll", "All companies")
270
- }), U.map((e) => /* @__PURE__ */ w(A, {
271
- value: e.value,
272
- children: e.label
273
- }, e.value))] })]
274
- }), /* @__PURE__ */ T(O, {
275
- value: R,
276
- onValueChange: z,
277
- children: [/* @__PURE__ */ w(j, {
278
- className: "w-full sm:w-48",
279
- "aria-label": _("technospam.problems.roleFilterLabel", "Filter by role"),
280
- children: /* @__PURE__ */ w(M, { placeholder: _("technospam.problems.rolePlaceholder", "Role") })
281
- }), /* @__PURE__ */ T(k, { children: [/* @__PURE__ */ w(A, {
282
- value: "ALL",
283
- children: _("technospam.problems.roleAll", "All roles")
284
- }), W.map((e) => /* @__PURE__ */ w(A, {
285
- value: e.value,
286
- children: e.label
287
- }, e.value))] })]
288
- })]
274
+ children: [
275
+ /* @__PURE__ */ O(M, {
276
+ value: k,
277
+ onValueChange: j,
278
+ children: [/* @__PURE__ */ D(F, {
279
+ className: "w-full sm:w-48",
280
+ "aria-label": y("technospam.problems.companyFilterLabel", "Filter by company"),
281
+ children: /* @__PURE__ */ D(I, { placeholder: y("technospam.problems.companyPlaceholder", "Company") })
282
+ }), /* @__PURE__ */ O(N, { children: [/* @__PURE__ */ D(P, {
283
+ value: "ALL",
284
+ children: y("technospam.problems.companyAll", "All companies")
285
+ }), he.map((e) => /* @__PURE__ */ D(P, {
286
+ value: e.value,
287
+ children: e.label
288
+ }, e.value))] })]
289
+ }),
290
+ /* @__PURE__ */ O(M, {
291
+ value: H,
292
+ onValueChange: de,
293
+ children: [/* @__PURE__ */ D(F, {
294
+ className: "w-full sm:w-48",
295
+ "aria-label": y("technospam.problems.roleFilterLabel", "Filter by role"),
296
+ children: /* @__PURE__ */ D(I, { placeholder: y("technospam.problems.rolePlaceholder", "Role") })
297
+ }), /* @__PURE__ */ O(N, { children: [/* @__PURE__ */ D(P, {
298
+ value: "ALL",
299
+ children: y("technospam.problems.roleAll", "All roles")
300
+ }), ge.map((e) => /* @__PURE__ */ D(P, {
301
+ value: e.value,
302
+ children: e.label
303
+ }, e.value))] })]
304
+ }),
305
+ /* @__PURE__ */ O("div", {
306
+ role: "group",
307
+ "aria-label": y("technospam.problems.viewLabel", "Catalog layout"),
308
+ className: "inline-flex items-center gap-1 self-start rounded-md border border-border-subtle bg-bg-surface p-1 sm:ml-auto sm:self-auto",
309
+ children: [/* @__PURE__ */ O(A, {
310
+ type: "button",
311
+ size: "sm",
312
+ variant: W === "table" ? "secondary" : "ghost",
313
+ "aria-pressed": W === "table",
314
+ onClick: () => G("table"),
315
+ children: [/* @__PURE__ */ D(ce, {
316
+ size: 14,
317
+ className: "mr-1.5",
318
+ "aria-hidden": "true"
319
+ }), y("technospam.problems.viewTable", "Table")]
320
+ }), /* @__PURE__ */ O(A, {
321
+ type: "button",
322
+ size: "sm",
323
+ variant: W === "cards" ? "secondary" : "ghost",
324
+ "aria-pressed": W === "cards",
325
+ onClick: () => G("cards"),
326
+ children: [/* @__PURE__ */ D(w, {
327
+ size: 14,
328
+ className: "mr-1.5",
329
+ "aria-hidden": "true"
330
+ }), y("technospam.problems.viewCards", "Cards")]
331
+ })]
332
+ })
333
+ ]
289
334
  }),
290
- /* @__PURE__ */ T(P, {
291
- value: S,
292
- className: re,
293
- children: [J && !Z.length ? /* @__PURE__ */ w(u, {}) : Y ? /* @__PURE__ */ w(te, {
294
- title: _("technospam.common.errorLoadProblems", "Couldn't load problems"),
295
- error: Y
296
- }) : $.length === 0 ? /* @__PURE__ */ w(ee, {
297
- icon: /* @__PURE__ */ w(y, { size: 26 }),
298
- title: B || S !== "ALL" || E !== "ALL" || R !== "ALL" ? _("technospam.problems.emptySearchTitle", "No matching problems") : _("technospam.problems.emptyDefaultTitle", "No problems published yet"),
299
- description: B || S !== "ALL" || E !== "ALL" || R !== "ALL" ? _("technospam.problems.emptySearchDesc", "Try a different search, difficulty, company, or role filter.") : _("technospam.problems.emptyDefaultDesc", "Published problems will appear here. Check back soon — TechnoSpam is pre-launch.")
300
- }) : /* @__PURE__ */ w("div", {
301
- className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
302
- children: $.map((e) => /* @__PURE__ */ w(L, {
303
- problem: e,
304
- solved: Q.has(e.id),
305
- onOpen: () => {
306
- d("technospam.problem.viewed", {
307
- workspaceId: c,
308
- entityId: e.id,
309
- entityType: "TEC_PROBLEM"
310
- }), o(`/applications/problem-details-page?id=${e.id}`);
311
- }
312
- }, e.id))
313
- }), /* @__PURE__ */ w(l, {
314
- hasMore: se,
315
- loading: J,
316
- onClick: K
317
- })]
335
+ /* @__PURE__ */ O(R, {
336
+ value: T,
337
+ className: oe,
338
+ children: [
339
+ q && !X.length ? /* @__PURE__ */ D(ne, {}) : J ? /* @__PURE__ */ D(m, {
340
+ title: y("technospam.common.errorLoadProblems", "Couldn't load problems"),
341
+ error: J
342
+ }) : Q.length === 0 ? /* @__PURE__ */ D(p, {
343
+ icon: /* @__PURE__ */ D(x, { size: 26 }),
344
+ title: U || T !== "ALL" || k !== "ALL" || H !== "ALL" ? y("technospam.problems.emptySearchTitle", "No matching problems") : y("technospam.problems.emptyDefaultTitle", "No problems published yet"),
345
+ description: U || T !== "ALL" || k !== "ALL" || H !== "ALL" ? y("technospam.problems.emptySearchDesc", "Try a different search, difficulty, company, or role filter.") : y("technospam.problems.emptyDefaultDesc", "Published problems will appear here. Check back soon — TechnoSpam is pre-launch.")
346
+ }) : W === "table" ? /* @__PURE__ */ D(f, {
347
+ problems: Q,
348
+ solvedIds: Y,
349
+ onOpen: $
350
+ }) : /* @__PURE__ */ D("div", {
351
+ className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
352
+ children: Q.map((e) => /* @__PURE__ */ D(V, {
353
+ problem: e,
354
+ solved: Y.has(e.id),
355
+ onOpen: () => $(e)
356
+ }, e.id))
357
+ }),
358
+ Q.length > 0 && !J ? /* @__PURE__ */ D("p", {
359
+ className: "mt-4 text-sm text-text-muted",
360
+ children: Q.length < X.length ? y("technospam.problems.showingFiltered", "Showing {{shown}} of {{total}} loaded problems", {
361
+ shown: Q.length,
362
+ total: X.length
363
+ }) : Z ? y("technospam.problems.showingMore", "Showing 1 to {{count}} problems — load more to see the rest", { count: Q.length }) : y("technospam.problems.showingAll", "Showing all {{count}} problems", { count: Q.length })
364
+ }) : null,
365
+ /* @__PURE__ */ D(te, {
366
+ hasMore: Z,
367
+ loading: q,
368
+ onClick: ve
369
+ })
370
+ ]
318
371
  })
319
372
  ]
320
373
  })]
321
374
  });
322
375
  }
323
376
  //#endregion
324
- export { R as ApplicationsProblemsPagePage };
377
+ export { H as ApplicationsProblemsPagePage };
325
378
 
326
379
  //# sourceMappingURL=ApplicationsProblemsPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ApplicationsProblemsPagePage.js","names":[],"sources":["../../../src/technospam/pages/ApplicationsProblemsPagePage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n Building2,\n CheckCircle2,\n Code2,\n Flame,\n Gauge,\n Layers,\n Search,\n Tag,\n Trophy,\n} from 'lucide-react';\nimport {\n Badge,\n GlassCard,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { TAB_PANEL_FOCUS_CLASS } from '../lib/a11y';\nimport {\n EmptyView,\n ErrorView,\n LoadMore,\n LoadingGrid,\n MediaCover,\n PageLayout,\n PremiumBadge,\n StatCard,\n StatusBadge,\n topicIcon,\n} from '../components';\nimport { useTechnoSpam, useTechnoSpamNavigate } from '../providers/TechnoSpamProvider';\nimport {\n pageArg,\n usePageLimit,\n useProblemsQuery,\n useSubmissionsQuery,\n type TecProblem,\n type TecProblemDifficulty,\n} from '../api/technospamApi';\nimport { useTechnoSpamAnalytics } from '../hooks/useTechnoSpamAnalytics';\nimport { useTr } from '../hooks/useTr';\n\nfunction ProblemCard({\n problem,\n solved,\n onOpen,\n}: {\n problem: TecProblem;\n solved: boolean;\n onOpen: () => void;\n}) {\n const tr = useTr();\n return (\n <GlassCard\n className=\"group flex cursor-pointer flex-col overflow-hidden transition-all duration-200 hover:-translate-y-1 hover:shadow-lg\"\n onClick={onOpen}\n >\n <MediaCover\n seed={`${problem.topic ?? ''} ${problem.difficulty} ${problem.title}`}\n icon={topicIcon(problem.topic ?? problem.title)}\n >\n {solved ? (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-status-success-bg-subtle px-2 py-0.5 text-[11px] font-medium text-status-success-text ring-1 ring-status-success-border/30\">\n <CheckCircle2 size={12} /> {tr('technospam.problems.solved', 'Solved')}\n </span>\n ) : (\n <span />\n )}\n <div className=\"flex flex-wrap items-center gap-1.5\">\n <StatusBadge status={problem.difficulty} kind=\"level\" />\n {problem.isPremiumOnly ? <PremiumBadge locked={problem.isLocked} /> : null}\n </div>\n </MediaCover>\n <div className=\"flex flex-1 flex-col gap-3 p-4\">\n <div className=\"min-w-0\">\n <h3 className=\"truncate text-base font-semibold text-text-primary group-hover:text-accent-primary\">\n {problem.title}\n </h3>\n {problem.statement ? (\n <p className=\"mt-1 line-clamp-2 text-sm text-text-secondary\">{problem.statement}</p>\n ) : null}\n </div>\n <div className=\"mt-auto flex flex-wrap items-center gap-3 text-xs text-text-muted\">\n {problem.topic ? (\n <span className=\"inline-flex items-center gap-1\">\n <Layers size={13} /> {problem.topic}\n </span>\n ) : null}\n <span className=\"inline-flex items-center gap-1\">\n <Trophy size={13} />{' '}\n {tr('technospam.problems.points', '{{count}} pts', { count: problem.points })}\n </span>\n {problem.languages.length ? (\n <span className=\"inline-flex items-center gap-1\">\n <Code2 size={13} />{' '}\n {problem.languages.length === 1\n ? tr('technospam.problems.languages', '{{count}} lang', {\n count: problem.languages.length,\n })\n : tr('technospam.problems.languagesPlural', '{{count}} langs', {\n count: problem.languages.length,\n })}\n </span>\n ) : null}\n </div>\n {problem.companies.length ? (\n <div className=\"flex flex-wrap gap-1.5\">\n {problem.companies.slice(0, 3).map((c) => (\n <Badge key={c} variant=\"outline\" className=\"text-[11px] capitalize\">\n <Building2 size={10} className=\"mr-1\" />\n {c.replace(/-/g, ' ')}\n </Badge>\n ))}\n {problem.interviewFrequency === 'HIGH' ? (\n <Badge variant=\"secondary\" className=\"text-[11px] text-status-warning-text\">\n <Flame size={10} className=\"mr-1\" />\n {tr('technospam.problems.frequentlyAsked', 'Frequently asked')}\n </Badge>\n ) : null}\n </div>\n ) : null}\n {problem.tags.length ? (\n <div className=\"flex flex-wrap gap-1.5\">\n {problem.tags.slice(0, 3).map((t) => (\n <Badge key={t} variant=\"secondary\" className=\"text-[11px]\">\n <Tag size={10} className=\"mr-1\" />\n {t}\n </Badge>\n ))}\n </div>\n ) : null}\n </div>\n </GlassCard>\n );\n}\n\nexport function ApplicationsProblemsPagePage() {\n const navigate = useTechnoSpamNavigate();\n const { currentUser, workspaceId } = useTechnoSpam();\n const { emit } = useTechnoSpamAnalytics();\n const tr = useTr();\n const learnerId = currentUser?.id;\n const [difficulty, setDifficulty] = useState<'ALL' | TecProblemDifficulty>('ALL');\n const [company, setCompany] = useState<string>('ALL');\n const [role, setRole] = useState<string>('ALL');\n const [search, setSearch] = useState('');\n\n const difficulties = useMemo(\n () => [\n { value: 'ALL' as const, label: tr('technospam.problems.filterAll', 'All') },\n {\n value: 'EASY' as TecProblemDifficulty,\n label: tr('technospam.problems.filterEasy', 'Easy'),\n },\n {\n value: 'MEDIUM' as TecProblemDifficulty,\n label: tr('technospam.problems.filterMedium', 'Medium'),\n },\n {\n value: 'HARD' as TecProblemDifficulty,\n label: tr('technospam.problems.filterHard', 'Hard'),\n },\n ],\n [tr]\n );\n\n // Curated interview-target lists for the catalog filters. Values follow the\n // backend's lowercase-slug convention (see practice.service.ts normalizeSlug).\n const companies = useMemo(\n () => [\n { value: 'google', label: 'Google' },\n { value: 'amazon', label: 'Amazon' },\n { value: 'meta', label: 'Meta' },\n { value: 'microsoft', label: 'Microsoft' },\n { value: 'apple', label: 'Apple' },\n { value: 'netflix', label: 'Netflix' },\n ],\n []\n );\n\n const roles = useMemo(\n () => [\n { value: 'frontend', label: 'Frontend' },\n { value: 'backend', label: 'Backend' },\n { value: 'fullstack', label: 'Full-Stack' },\n { value: 'data-science', label: 'Data Science' },\n { value: 'mobile', label: 'Mobile' },\n { value: 'sre', label: 'SRE / Infra' },\n ],\n []\n );\n\n const { limit, more } = usePageLimit();\n const { data, loading, error } = useProblemsQuery({\n status: 'PUBLISHED',\n pagination: pageArg(limit),\n ...(difficulty !== 'ALL' ? { difficulty } : {}),\n ...(company !== 'ALL' ? { company } : {}),\n ...(role !== 'ALL' ? { role } : {}),\n });\n const { data: subsData } = useSubmissionsQuery(learnerId ? { learnerId } : {});\n\n const problems = data?.tecListProblems?.items ?? [];\n const hasMore = data?.tecListProblems?.pageInfo?.hasMore ?? false;\n\n const solvedSet = useMemo(\n () =>\n new Set(\n (subsData?.tecListSubmissions?.items ?? [])\n .filter((s) => s.verdict === 'ACCEPTED')\n .map((s) => s.problemId)\n ),\n [subsData]\n );\n\n const solvedCount = problems.filter((p) => solvedSet.has(p.id)).length;\n const easyCount = problems.filter((p) => p.difficulty === 'EASY').length;\n const hardCount = problems.filter((p) => p.difficulty === 'HARD').length;\n\n const filtered = useMemo(() => {\n const q = search.trim().toLowerCase();\n if (!q) return problems;\n return problems.filter(\n (p) =>\n p.title.toLowerCase().includes(q) ||\n (p.topic ?? '').toLowerCase().includes(q) ||\n p.tags.some((t) => t.toLowerCase().includes(q))\n );\n }, [problems, search]);\n\n return (\n <PageLayout\n hero\n title={tr('technospam.problems.title', 'Coding Problems')}\n description={tr(\n 'technospam.problems.description',\n 'Sharpen your problem-solving with hands-on, mentor-judged challenges across topics and difficulty.'\n )}\n >\n <div className=\"mb-5 grid grid-cols-2 gap-3 sm:grid-cols-4\">\n <StatCard\n label={tr('technospam.problems.statProblems', 'Problems')}\n value={problems.length}\n icon={Code2}\n tone=\"blue\"\n />\n <StatCard\n label={tr('technospam.problems.statSolved', 'Solved')}\n value={solvedCount}\n icon={CheckCircle2}\n tone=\"green\"\n />\n <StatCard\n label={tr('technospam.problems.statEasy', 'Easy')}\n value={easyCount}\n icon={Gauge}\n tone=\"teal\"\n />\n <StatCard\n label={tr('technospam.problems.statHard', 'Hard')}\n value={hardCount}\n icon={Flame}\n tone=\"amber\"\n />\n </div>\n\n {/* The tabs filter one list, so that list is their tab panel: Radix points every\n trigger's aria-controls at a panel id, and without a TabsContent the id\n resolved to nothing (axe aria-valid-attr-value, critical; BOFF-3157). */}\n <Tabs\n className=\"gap-0\"\n value={difficulty}\n onValueChange={(v) => setDifficulty(v as 'ALL' | TecProblemDifficulty)}\n >\n <div className=\"mb-4 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <TabsList>\n {difficulties.map((d) => (\n <TabsTrigger key={d.value} value={d.value}>\n {d.label}\n </TabsTrigger>\n ))}\n </TabsList>\n <div className=\"relative w-full sm:w-72\">\n <Search\n className=\"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-text-muted\"\n size={16}\n />\n <Input\n className=\"pl-9\"\n aria-label={tr('technospam.problems.searchLabel', 'Search problems')}\n placeholder={tr('technospam.problems.searchPlaceholder', 'Search problems…')}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n onBlur={() => {\n const value = search.trim();\n if (value) {\n emit('technospam.search.performed', {\n workspaceId,\n entityType: 'problem',\n queryLength: value.length,\n });\n }\n }}\n />\n </div>\n </div>\n\n <div className=\"mb-4 flex flex-col gap-3 sm:flex-row sm:items-center\">\n <Select value={company} onValueChange={setCompany}>\n <SelectTrigger\n className=\"w-full sm:w-48\"\n aria-label={tr('technospam.problems.companyFilterLabel', 'Filter by company')}\n >\n <SelectValue placeholder={tr('technospam.problems.companyPlaceholder', 'Company')} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"ALL\">\n {tr('technospam.problems.companyAll', 'All companies')}\n </SelectItem>\n {companies.map((c) => (\n <SelectItem key={c.value} value={c.value}>\n {c.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Select value={role} onValueChange={setRole}>\n <SelectTrigger\n className=\"w-full sm:w-48\"\n aria-label={tr('technospam.problems.roleFilterLabel', 'Filter by role')}\n >\n <SelectValue placeholder={tr('technospam.problems.rolePlaceholder', 'Role')} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"ALL\">{tr('technospam.problems.roleAll', 'All roles')}</SelectItem>\n {roles.map((r) => (\n <SelectItem key={r.value} value={r.value}>\n {r.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <TabsContent value={difficulty} className={TAB_PANEL_FOCUS_CLASS}>\n {loading && !problems.length ? (\n <LoadingGrid />\n ) : error ? (\n <ErrorView\n title={tr('technospam.common.errorLoadProblems', \"Couldn't load problems\")}\n error={error}\n />\n ) : filtered.length === 0 ? (\n <EmptyView\n icon={<Code2 size={26} />}\n title={\n search || difficulty !== 'ALL' || company !== 'ALL' || role !== 'ALL'\n ? tr('technospam.problems.emptySearchTitle', 'No matching problems')\n : tr('technospam.problems.emptyDefaultTitle', 'No problems published yet')\n }\n description={\n search || difficulty !== 'ALL' || company !== 'ALL' || role !== 'ALL'\n ? tr(\n 'technospam.problems.emptySearchDesc',\n 'Try a different search, difficulty, company, or role filter.'\n )\n : tr(\n 'technospam.problems.emptyDefaultDesc',\n 'Published problems will appear here. Check back soon — TechnoSpam is pre-launch.'\n )\n }\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {filtered.map((problem) => (\n <ProblemCard\n key={problem.id}\n problem={problem}\n solved={solvedSet.has(problem.id)}\n onOpen={() => {\n emit('technospam.problem.viewed', {\n workspaceId,\n entityId: problem.id,\n entityType: 'TEC_PROBLEM',\n });\n navigate(`/applications/problem-details-page?id=${problem.id}`);\n }}\n />\n ))}\n </div>\n )}\n <LoadMore hasMore={hasMore} loading={loading} onClick={more} />\n </TabsContent>\n </Tabs>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ApplicationsProblemsPagePage.js","names":[],"sources":["../../../src/technospam/pages/ApplicationsProblemsPagePage.tsx"],"sourcesContent":["import { useCallback, useMemo, useState } from 'react';\nimport {\n Building2,\n CheckCircle2,\n Code2,\n Flame,\n Gauge,\n LayoutGrid,\n Layers,\n List,\n Search,\n Tag,\n Trophy,\n} from 'lucide-react';\nimport {\n Badge,\n Button,\n GlassCard,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { TAB_PANEL_FOCUS_CLASS } from '../lib/a11y';\nimport {\n EmptyView,\n ErrorView,\n LoadMore,\n LoadingGrid,\n MediaCover,\n PageLayout,\n PremiumBadge,\n ProblemsTable,\n StatCard,\n StatusBadge,\n topicIcon,\n} from '../components';\nimport { useTechnoSpam, useTechnoSpamNavigate } from '../providers/TechnoSpamProvider';\nimport {\n pageArg,\n usePageLimit,\n useProblemsQuery,\n useSolvedProblemIds,\n type TecProblem,\n type TecProblemDifficulty,\n} from '../api/technospamApi';\nimport { useTechnoSpamAnalytics } from '../hooks/useTechnoSpamAnalytics';\nimport { useTr } from '../hooks/useTr';\nimport {\n readProblemCatalogView,\n safeLocalStorage,\n writeProblemCatalogView,\n type ProblemCatalogView,\n} from '../utils/problemCatalog';\n\nfunction ProblemCard({\n problem,\n solved,\n onOpen,\n}: {\n problem: TecProblem;\n solved: boolean;\n onOpen: () => void;\n}) {\n const tr = useTr();\n return (\n <GlassCard\n className=\"group flex cursor-pointer flex-col overflow-hidden transition-all duration-200 hover:-translate-y-1 hover:shadow-lg\"\n onClick={onOpen}\n >\n <MediaCover\n seed={`${problem.topic ?? ''} ${problem.difficulty} ${problem.title}`}\n icon={topicIcon(problem.topic ?? problem.title)}\n >\n {solved ? (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-status-success-bg-subtle px-2 py-0.5 text-[11px] font-medium text-status-success-text ring-1 ring-status-success-border/30\">\n <CheckCircle2 size={12} /> {tr('technospam.problems.solved', 'Solved')}\n </span>\n ) : (\n <span />\n )}\n <div className=\"flex flex-wrap items-center gap-1.5\">\n <StatusBadge status={problem.difficulty} kind=\"level\" />\n {problem.isPremiumOnly ? <PremiumBadge locked={problem.isLocked} /> : null}\n </div>\n </MediaCover>\n <div className=\"flex flex-1 flex-col gap-3 p-4\">\n <div className=\"min-w-0\">\n <h3 className=\"truncate text-base font-semibold text-text-primary group-hover:text-accent-primary\">\n {problem.title}\n </h3>\n {problem.statement ? (\n <p className=\"mt-1 line-clamp-2 text-sm text-text-secondary\">{problem.statement}</p>\n ) : null}\n </div>\n <div className=\"mt-auto flex flex-wrap items-center gap-3 text-xs text-text-muted\">\n {problem.topic ? (\n <span className=\"inline-flex items-center gap-1\">\n <Layers size={13} /> {problem.topic}\n </span>\n ) : null}\n <span className=\"inline-flex items-center gap-1\">\n <Trophy size={13} />{' '}\n {tr('technospam.problems.points', '{{count}} pts', { count: problem.points })}\n </span>\n {problem.languages.length ? (\n <span className=\"inline-flex items-center gap-1\">\n <Code2 size={13} />{' '}\n {problem.languages.length === 1\n ? tr('technospam.problems.languages', '{{count}} lang', {\n count: problem.languages.length,\n })\n : tr('technospam.problems.languagesPlural', '{{count}} langs', {\n count: problem.languages.length,\n })}\n </span>\n ) : null}\n </div>\n {problem.companies.length ? (\n <div className=\"flex flex-wrap gap-1.5\">\n {problem.companies.slice(0, 3).map((c) => (\n <Badge key={c} variant=\"outline\" className=\"text-[11px] capitalize\">\n <Building2 size={10} className=\"mr-1\" />\n {c.replace(/-/g, ' ')}\n </Badge>\n ))}\n {problem.interviewFrequency === 'HIGH' ? (\n <Badge variant=\"secondary\" className=\"text-[11px] text-status-warning-text\">\n <Flame size={10} className=\"mr-1\" />\n {tr('technospam.problems.frequentlyAsked', 'Frequently asked')}\n </Badge>\n ) : null}\n </div>\n ) : null}\n {problem.tags.length ? (\n <div className=\"flex flex-wrap gap-1.5\">\n {problem.tags.slice(0, 3).map((t) => (\n <Badge key={t} variant=\"secondary\" className=\"text-[11px]\">\n <Tag size={10} className=\"mr-1\" />\n {t}\n </Badge>\n ))}\n </div>\n ) : null}\n </div>\n </GlassCard>\n );\n}\n\nexport function ApplicationsProblemsPagePage() {\n const navigate = useTechnoSpamNavigate();\n const { currentUser, workspaceId } = useTechnoSpam();\n const { emit } = useTechnoSpamAnalytics();\n const tr = useTr();\n const learnerId = currentUser?.id;\n const [difficulty, setDifficulty] = useState<'ALL' | TecProblemDifficulty>('ALL');\n const [company, setCompany] = useState<string>('ALL');\n const [role, setRole] = useState<string>('ALL');\n const [search, setSearch] = useState('');\n // The mock's data table is the default layout; the card grid stays available\n // as a compact visual view and the choice is remembered per viewer (BOFF-4077).\n const [view, setView] = useState<ProblemCatalogView>(() =>\n readProblemCatalogView(safeLocalStorage())\n );\n const changeView = useCallback((next: ProblemCatalogView) => {\n setView(next);\n writeProblemCatalogView(safeLocalStorage(), next);\n }, []);\n\n const difficulties = useMemo(\n () => [\n { value: 'ALL' as const, label: tr('technospam.problems.filterAll', 'All') },\n {\n value: 'EASY' as TecProblemDifficulty,\n label: tr('technospam.problems.filterEasy', 'Easy'),\n },\n {\n value: 'MEDIUM' as TecProblemDifficulty,\n label: tr('technospam.problems.filterMedium', 'Medium'),\n },\n {\n value: 'HARD' as TecProblemDifficulty,\n label: tr('technospam.problems.filterHard', 'Hard'),\n },\n ],\n [tr]\n );\n\n // Curated interview-target lists for the catalog filters. Values follow the\n // backend's lowercase-slug convention (see practice.service.ts normalizeSlug).\n const companies = useMemo(\n () => [\n { value: 'google', label: 'Google' },\n { value: 'amazon', label: 'Amazon' },\n { value: 'meta', label: 'Meta' },\n { value: 'microsoft', label: 'Microsoft' },\n { value: 'apple', label: 'Apple' },\n { value: 'netflix', label: 'Netflix' },\n ],\n []\n );\n\n const roles = useMemo(\n () => [\n { value: 'frontend', label: 'Frontend' },\n { value: 'backend', label: 'Backend' },\n { value: 'fullstack', label: 'Full-Stack' },\n { value: 'data-science', label: 'Data Science' },\n { value: 'mobile', label: 'Mobile' },\n { value: 'sre', label: 'SRE / Infra' },\n ],\n []\n );\n\n const { limit, more } = usePageLimit();\n const { data, loading, error } = useProblemsQuery({\n status: 'PUBLISHED',\n pagination: pageArg(limit),\n ...(difficulty !== 'ALL' ? { difficulty } : {}),\n ...(company !== 'ALL' ? { company } : {}),\n ...(role !== 'ALL' ? { role } : {}),\n });\n const solvedSet = useSolvedProblemIds(learnerId);\n\n const problems = useMemo(() => data?.tecListProblems?.items ?? [], [data]);\n const hasMore = data?.tecListProblems?.pageInfo?.hasMore ?? false;\n\n const solvedCount = problems.filter((p) => solvedSet.has(p.id)).length;\n const easyCount = problems.filter((p) => p.difficulty === 'EASY').length;\n const hardCount = problems.filter((p) => p.difficulty === 'HARD').length;\n\n const filtered = useMemo(() => {\n const q = search.trim().toLowerCase();\n if (!q) return problems;\n return problems.filter(\n (p) =>\n p.title.toLowerCase().includes(q) ||\n (p.topic ?? '').toLowerCase().includes(q) ||\n p.tags.some((t) => t.toLowerCase().includes(q))\n );\n }, [problems, search]);\n\n const openProblem = useCallback(\n (problem: TecProblem) => {\n emit('technospam.problem.viewed', {\n workspaceId,\n entityId: problem.id,\n entityType: 'TEC_PROBLEM',\n });\n navigate(`/applications/problem-details-page?id=${problem.id}`);\n },\n [emit, navigate, workspaceId]\n );\n\n return (\n <PageLayout\n hero\n title={tr('technospam.problems.title', 'Coding Problems')}\n description={tr(\n 'technospam.problems.description',\n 'Sharpen your problem-solving with hands-on, mentor-judged challenges across topics and difficulty.'\n )}\n >\n <div className=\"mb-5 grid grid-cols-2 gap-3 sm:grid-cols-4\">\n <StatCard\n label={tr('technospam.problems.statProblems', 'Problems')}\n value={problems.length}\n icon={Code2}\n tone=\"blue\"\n />\n <StatCard\n label={tr('technospam.problems.statSolved', 'Solved')}\n value={solvedCount}\n icon={CheckCircle2}\n tone=\"green\"\n />\n <StatCard\n label={tr('technospam.problems.statEasy', 'Easy')}\n value={easyCount}\n icon={Gauge}\n tone=\"teal\"\n />\n <StatCard\n label={tr('technospam.problems.statHard', 'Hard')}\n value={hardCount}\n icon={Flame}\n tone=\"amber\"\n />\n </div>\n\n {/* The tabs filter one list, so that list is their tab panel: Radix points every\n trigger's aria-controls at a panel id, and without a TabsContent the id\n resolved to nothing (axe aria-valid-attr-value, critical; BOFF-3157). */}\n <Tabs\n className=\"gap-0\"\n value={difficulty}\n onValueChange={(v) => setDifficulty(v as 'ALL' | TecProblemDifficulty)}\n >\n <div className=\"mb-4 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <TabsList>\n {difficulties.map((d) => (\n <TabsTrigger key={d.value} value={d.value}>\n {d.label}\n </TabsTrigger>\n ))}\n </TabsList>\n <div className=\"relative w-full sm:w-72\">\n <Search\n className=\"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-text-muted\"\n size={16}\n />\n <Input\n className=\"pl-9\"\n aria-label={tr('technospam.problems.searchLabel', 'Search problems')}\n placeholder={tr('technospam.problems.searchPlaceholder', 'Search problems…')}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n onBlur={() => {\n const value = search.trim();\n if (value) {\n emit('technospam.search.performed', {\n workspaceId,\n entityType: 'problem',\n queryLength: value.length,\n });\n }\n }}\n />\n </div>\n </div>\n\n <div className=\"mb-4 flex flex-col gap-3 sm:flex-row sm:items-center\">\n <Select value={company} onValueChange={setCompany}>\n <SelectTrigger\n className=\"w-full sm:w-48\"\n aria-label={tr('technospam.problems.companyFilterLabel', 'Filter by company')}\n >\n <SelectValue placeholder={tr('technospam.problems.companyPlaceholder', 'Company')} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"ALL\">\n {tr('technospam.problems.companyAll', 'All companies')}\n </SelectItem>\n {companies.map((c) => (\n <SelectItem key={c.value} value={c.value}>\n {c.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Select value={role} onValueChange={setRole}>\n <SelectTrigger\n className=\"w-full sm:w-48\"\n aria-label={tr('technospam.problems.roleFilterLabel', 'Filter by role')}\n >\n <SelectValue placeholder={tr('technospam.problems.rolePlaceholder', 'Role')} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"ALL\">{tr('technospam.problems.roleAll', 'All roles')}</SelectItem>\n {roles.map((r) => (\n <SelectItem key={r.value} value={r.value}>\n {r.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <div\n role=\"group\"\n aria-label={tr('technospam.problems.viewLabel', 'Catalog layout')}\n className=\"inline-flex items-center gap-1 self-start rounded-md border border-border-subtle bg-bg-surface p-1 sm:ml-auto sm:self-auto\"\n >\n <Button\n type=\"button\"\n size=\"sm\"\n variant={view === 'table' ? 'secondary' : 'ghost'}\n aria-pressed={view === 'table'}\n onClick={() => changeView('table')}\n >\n <List size={14} className=\"mr-1.5\" aria-hidden=\"true\" />\n {tr('technospam.problems.viewTable', 'Table')}\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n variant={view === 'cards' ? 'secondary' : 'ghost'}\n aria-pressed={view === 'cards'}\n onClick={() => changeView('cards')}\n >\n <LayoutGrid size={14} className=\"mr-1.5\" aria-hidden=\"true\" />\n {tr('technospam.problems.viewCards', 'Cards')}\n </Button>\n </div>\n </div>\n\n <TabsContent value={difficulty} className={TAB_PANEL_FOCUS_CLASS}>\n {loading && !problems.length ? (\n <LoadingGrid />\n ) : error ? (\n <ErrorView\n title={tr('technospam.common.errorLoadProblems', \"Couldn't load problems\")}\n error={error}\n />\n ) : filtered.length === 0 ? (\n <EmptyView\n icon={<Code2 size={26} />}\n title={\n search || difficulty !== 'ALL' || company !== 'ALL' || role !== 'ALL'\n ? tr('technospam.problems.emptySearchTitle', 'No matching problems')\n : tr('technospam.problems.emptyDefaultTitle', 'No problems published yet')\n }\n description={\n search || difficulty !== 'ALL' || company !== 'ALL' || role !== 'ALL'\n ? tr(\n 'technospam.problems.emptySearchDesc',\n 'Try a different search, difficulty, company, or role filter.'\n )\n : tr(\n 'technospam.problems.emptyDefaultDesc',\n 'Published problems will appear here. Check back soon — TechnoSpam is pre-launch.'\n )\n }\n />\n ) : view === 'table' ? (\n <ProblemsTable problems={filtered} solvedIds={solvedSet} onOpen={openProblem} />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {filtered.map((problem) => (\n <ProblemCard\n key={problem.id}\n problem={problem}\n solved={solvedSet.has(problem.id)}\n onOpen={() => openProblem(problem)}\n />\n ))}\n </div>\n )}\n {filtered.length > 0 && !error ? (\n <p className=\"mt-4 text-sm text-text-muted\">\n {filtered.length < problems.length\n ? tr(\n 'technospam.problems.showingFiltered',\n 'Showing {{shown}} of {{total}} loaded problems',\n { shown: filtered.length, total: problems.length }\n )\n : hasMore\n ? tr(\n 'technospam.problems.showingMore',\n 'Showing 1 to {{count}} problems — load more to see the rest',\n { count: filtered.length }\n )\n : tr('technospam.problems.showingAll', 'Showing all {{count}} problems', {\n count: filtered.length,\n })}\n </p>\n ) : null}\n <LoadMore hasMore={hasMore} loading={loading} onClick={more} />\n </TabsContent>\n </Tabs>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA6DA,SAAS,EAAY,EACnB,YACA,WACA,aAKC;CACD,IAAM,IAAK,GAAO;AAClB,QACE,kBAAC,GAAD;EACE,WAAU;EACV,SAAS;YAFX,CAIE,kBAAC,GAAD;GACE,MAAM,GAAG,EAAQ,SAAS,GAAG,GAAG,EAAQ,WAAW,GAAG,EAAQ;GAC9D,MAAM,EAAU,EAAQ,SAAS,EAAQ,MAAM;aAFjD,CAIG,IACC,kBAAC,QAAD;IAAM,WAAU;cAAhB;KACE,kBAAC,GAAD,EAAc,MAAM,IAAM,CAAA;;KAAE,EAAG,8BAA8B,SAAS;KACjE;QAEP,kBAAC,QAAD,EAAQ,CAAA,EAEV,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KAAa,QAAQ,EAAQ;KAAY,MAAK;KAAU,CAAA,EACvD,EAAQ,gBAAgB,kBAAC,GAAD,EAAc,QAAQ,EAAQ,UAAY,CAAA,GAAG,KAClE;MACK;MACb,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBACX,EAAQ;MACN,CAAA,EACJ,EAAQ,YACP,kBAAC,KAAD;MAAG,WAAU;gBAAiD,EAAQ;MAAc,CAAA,GAClF,KACA;;IACN,kBAAC,OAAD;KAAK,WAAU;eAAf;MACG,EAAQ,QACP,kBAAC,QAAD;OAAM,WAAU;iBAAhB;QACE,kBAAC,GAAD,EAAQ,MAAM,IAAM,CAAA;;QAAE,EAAQ;QACzB;WACL;MACJ,kBAAC,QAAD;OAAM,WAAU;iBAAhB;QACE,kBAAC,GAAD,EAAQ,MAAM,IAAM,CAAA;QAAC;QACpB,EAAG,8BAA8B,iBAAiB,EAAE,OAAO,EAAQ,QAAQ,CAAC;QACxE;;MACN,EAAQ,UAAU,SACjB,kBAAC,QAAD;OAAM,WAAU;iBAAhB;QACE,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA;QAAC;QACnB,EAAQ,UAAU,WAAW,IAC1B,EAAG,iCAAiC,kBAAkB,EACpD,OAAO,EAAQ,UAAU,QAC1B,CAAC,GACF,EAAG,uCAAuC,mBAAmB,EAC3D,OAAO,EAAQ,UAAU,QAC1B,CAAC;QACD;WACL;MACA;;IACL,EAAQ,UAAU,SACjB,kBAAC,OAAD;KAAK,WAAU;eAAf,CACG,EAAQ,UAAU,MAAM,GAAG,EAAE,CAAC,KAAK,MAClC,kBAAC,GAAD;MAAe,SAAQ;MAAU,WAAU;gBAA3C,CACE,kBAAC,GAAD;OAAW,MAAM;OAAI,WAAU;OAAS,CAAA,EACvC,EAAE,QAAQ,MAAM,IAAI,CACf;QAHI,EAGJ,CACR,EACD,EAAQ,uBAAuB,SAC9B,kBAAC,GAAD;MAAO,SAAQ;MAAY,WAAU;gBAArC,CACE,kBAAC,GAAD;OAAO,MAAM;OAAI,WAAU;OAAS,CAAA,EACnC,EAAG,uCAAuC,mBAAmB,CACxD;UACN,KACA;SACJ;IACH,EAAQ,KAAK,SACZ,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAQ,KAAK,MAAM,GAAG,EAAE,CAAC,KAAK,MAC7B,kBAAC,GAAD;MAAe,SAAQ;MAAY,WAAU;gBAA7C,CACE,kBAAC,GAAD;OAAK,MAAM;OAAI,WAAU;OAAS,CAAA,EACjC,EACK;QAHI,EAGJ,CACR;KACE,CAAA,GACJ;IACA;KACI;;;AAIhB,SAAgB,IAA+B;CAC7C,IAAM,IAAW,GAAuB,EAClC,EAAE,gBAAa,mBAAgB,GAAe,EAC9C,EAAE,YAAS,GAAwB,EACnC,IAAK,GAAO,EACZ,IAAY,GAAa,IACzB,CAAC,GAAY,KAAiB,EAAuC,MAAM,EAC3E,CAAC,GAAS,KAAc,EAAiB,MAAM,EAC/C,CAAC,GAAM,MAAW,EAAiB,MAAM,EACzC,CAAC,GAAQ,MAAa,EAAS,GAAG,EAGlC,CAAC,GAAM,MAAW,QACtB,EAAuB,GAAkB,CAAC,CAC3C,EACK,IAAa,GAAa,MAA6B;AAE3D,EADA,GAAQ,EAAK,EACb,GAAwB,GAAkB,EAAE,EAAK;IAChD,EAAE,CAAC,EAEA,KAAe,QACb;EACJ;GAAE,OAAO;GAAgB,OAAO,EAAG,iCAAiC,MAAM;GAAE;EAC5E;GACE,OAAO;GACP,OAAO,EAAG,kCAAkC,OAAO;GACpD;EACD;GACE,OAAO;GACP,OAAO,EAAG,oCAAoC,SAAS;GACxD;EACD;GACE,OAAO;GACP,OAAO,EAAG,kCAAkC,OAAO;GACpD;EACF,EACD,CAAC,EAAG,CACL,EAIK,KAAY,QACV;EACJ;GAAE,OAAO;GAAU,OAAO;GAAU;EACpC;GAAE,OAAO;GAAU,OAAO;GAAU;EACpC;GAAE,OAAO;GAAQ,OAAO;GAAQ;EAChC;GAAE,OAAO;GAAa,OAAO;GAAa;EAC1C;GAAE,OAAO;GAAS,OAAO;GAAS;EAClC;GAAE,OAAO;GAAW,OAAO;GAAW;EACvC,EACD,EAAE,CACH,EAEK,KAAQ,QACN;EACJ;GAAE,OAAO;GAAY,OAAO;GAAY;EACxC;GAAE,OAAO;GAAW,OAAO;GAAW;EACtC;GAAE,OAAO;GAAa,OAAO;GAAc;EAC3C;GAAE,OAAO;GAAgB,OAAO;GAAgB;EAChD;GAAE,OAAO;GAAU,OAAO;GAAU;EACpC;GAAE,OAAO;GAAO,OAAO;GAAe;EACvC,EACD,EAAE,CACH,EAEK,EAAE,WAAO,aAAS,IAAc,EAChC,EAAE,SAAM,YAAS,aAAU,EAAiB;EAChD,QAAQ;EACR,YAAY,GAAQ,GAAM;EAC1B,GAAI,MAAe,QAAyB,EAAE,GAAnB,EAAE,eAAY;EACzC,GAAI,MAAY,QAAsB,EAAE,GAAhB,EAAE,YAAS;EACnC,GAAI,MAAS,QAAmB,EAAE,GAAb,EAAE,SAAM;EAC9B,CAAC,EACI,IAAY,GAAoB,EAAU,EAE1C,IAAW,QAAc,GAAM,iBAAiB,SAAS,EAAE,EAAE,CAAC,EAAK,CAAC,EACpE,IAAU,GAAM,iBAAiB,UAAU,WAAW,IAEtD,KAAc,EAAS,QAAQ,MAAM,EAAU,IAAI,EAAE,GAAG,CAAC,CAAC,QAC1D,KAAY,EAAS,QAAQ,MAAM,EAAE,eAAe,OAAO,CAAC,QAC5D,KAAY,EAAS,QAAQ,MAAM,EAAE,eAAe,OAAO,CAAC,QAE5D,IAAW,QAAc;EAC7B,IAAM,IAAI,EAAO,MAAM,CAAC,aAAa;AAErC,SADK,IACE,EAAS,QACb,MACC,EAAE,MAAM,aAAa,CAAC,SAAS,EAAE,KAChC,EAAE,SAAS,IAAI,aAAa,CAAC,SAAS,EAAE,IACzC,EAAE,KAAK,MAAM,MAAM,EAAE,aAAa,CAAC,SAAS,EAAE,CAAC,CAClD,GANc;IAOd,CAAC,GAAU,EAAO,CAAC,EAEhB,IAAc,GACjB,MAAwB;AAMvB,EALA,EAAK,6BAA6B;GAChC;GACA,UAAU,EAAQ;GAClB,YAAY;GACb,CAAC,EACF,EAAS,yCAAyC,EAAQ,KAAK;IAEjE;EAAC;EAAM;EAAU;EAAY,CAC9B;AAED,QACE,kBAAC,GAAD;EACE,MAAA;EACA,OAAO,EAAG,6BAA6B,kBAAkB;EACzD,aAAa,EACX,mCACA,qGACD;YANH,CAQE,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD;KACE,OAAO,EAAG,oCAAoC,WAAW;KACzD,OAAO,EAAS;KAChB,MAAM;KACN,MAAK;KACL,CAAA;IACF,kBAAC,GAAD;KACE,OAAO,EAAG,kCAAkC,SAAS;KACrD,OAAO;KACP,MAAM;KACN,MAAK;KACL,CAAA;IACF,kBAAC,GAAD;KACE,OAAO,EAAG,gCAAgC,OAAO;KACjD,OAAO;KACP,MAAM;KACN,MAAK;KACL,CAAA;IACF,kBAAC,GAAD;KACE,OAAO,EAAG,gCAAgC,OAAO;KACjD,OAAO;KACP,MAAM;KACN,MAAK;KACL,CAAA;IACE;MAKN,kBAAC,GAAD;GACE,WAAU;GACV,OAAO;GACP,gBAAgB,MAAM,EAAc,EAAkC;aAHxE;IAKE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD,EAAA,UACG,GAAa,KAAK,MACjB,kBAAC,GAAD;MAA2B,OAAO,EAAE;gBACjC,EAAE;MACS,EAFI,EAAE,MAEN,CACd,EACO,CAAA,EACX,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,IAAD;OACE,WAAU;OACV,MAAM;OACN,CAAA,EACF,kBAAC,IAAD;OACE,WAAU;OACV,cAAY,EAAG,mCAAmC,kBAAkB;OACpE,aAAa,EAAG,yCAAyC,mBAAmB;OAC5E,OAAO;OACP,WAAW,MAAM,GAAU,EAAE,OAAO,MAAM;OAC1C,cAAc;QACZ,IAAM,IAAQ,EAAO,MAAM;AAC3B,QAAI,KACF,EAAK,+BAA+B;SAClC;SACA,YAAY;SACZ,aAAa,EAAM;SACpB,CAAC;;OAGN,CAAA,CACE;QACF;;IAEN,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,GAAD;OAAQ,OAAO;OAAS,eAAe;iBAAvC,CACE,kBAAC,GAAD;QACE,WAAU;QACV,cAAY,EAAG,0CAA0C,oBAAoB;kBAE7E,kBAAC,GAAD,EAAa,aAAa,EAAG,0CAA0C,UAAU,EAAI,CAAA;QACvE,CAAA,EAChB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;QAAY,OAAM;kBACf,EAAG,kCAAkC,gBAAgB;QAC3C,CAAA,EACZ,GAAU,KAAK,MACd,kBAAC,GAAD;QAA0B,OAAO,EAAE;kBAChC,EAAE;QACQ,EAFI,EAAE,MAEN,CACb,CACY,EAAA,CAAA,CACT;;MACT,kBAAC,GAAD;OAAQ,OAAO;OAAM,eAAe;iBAApC,CACE,kBAAC,GAAD;QACE,WAAU;QACV,cAAY,EAAG,uCAAuC,iBAAiB;kBAEvE,kBAAC,GAAD,EAAa,aAAa,EAAG,uCAAuC,OAAO,EAAI,CAAA;QACjE,CAAA,EAChB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;QAAY,OAAM;kBAAO,EAAG,+BAA+B,YAAY;QAAc,CAAA,EACpF,GAAM,KAAK,MACV,kBAAC,GAAD;QAA0B,OAAO,EAAE;kBAChC,EAAE;QACQ,EAFI,EAAE,MAEN,CACb,CACY,EAAA,CAAA,CACT;;MACT,kBAAC,OAAD;OACE,MAAK;OACL,cAAY,EAAG,iCAAiC,iBAAiB;OACjE,WAAU;iBAHZ,CAKE,kBAAC,GAAD;QACE,MAAK;QACL,MAAK;QACL,SAAS,MAAS,UAAU,cAAc;QAC1C,gBAAc,MAAS;QACvB,eAAe,EAAW,QAAQ;kBALpC,CAOE,kBAAC,IAAD;SAAM,MAAM;SAAI,WAAU;SAAS,eAAY;SAAS,CAAA,EACvD,EAAG,iCAAiC,QAAQ,CACtC;WACT,kBAAC,GAAD;QACE,MAAK;QACL,MAAK;QACL,SAAS,MAAS,UAAU,cAAc;QAC1C,gBAAc,MAAS;QACvB,eAAe,EAAW,QAAQ;kBALpC,CAOE,kBAAC,GAAD;SAAY,MAAM;SAAI,WAAU;SAAS,eAAY;SAAS,CAAA,EAC7D,EAAG,iCAAiC,QAAQ,CACtC;UACL;;MACF;;IAEN,kBAAC,GAAD;KAAa,OAAO;KAAY,WAAW;eAA3C;MACG,KAAW,CAAC,EAAS,SACpB,kBAAC,IAAD,EAAe,CAAA,GACb,IACF,kBAAC,GAAD;OACE,OAAO,EAAG,uCAAuC,yBAAyB;OACnE;OACP,CAAA,GACA,EAAS,WAAW,IACtB,kBAAC,GAAD;OACE,MAAM,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA;OACzB,OACE,KAAU,MAAe,SAAS,MAAY,SAAS,MAAS,QAC5D,EAAG,wCAAwC,uBAAuB,GAClE,EAAG,yCAAyC,4BAA4B;OAE9E,aACE,KAAU,MAAe,SAAS,MAAY,SAAS,MAAS,QAC5D,EACE,uCACA,+DACD,GACD,EACE,wCACA,mFACD;OAEP,CAAA,GACA,MAAS,UACX,kBAAC,GAAD;OAAe,UAAU;OAAU,WAAW;OAAW,QAAQ;OAAe,CAAA,GAEhF,kBAAC,OAAD;OAAK,WAAU;iBACZ,EAAS,KAAK,MACb,kBAAC,GAAD;QAEW;QACT,QAAQ,EAAU,IAAI,EAAQ,GAAG;QACjC,cAAc,EAAY,EAAQ;QAClC,EAJK,EAAQ,GAIb,CACF;OACE,CAAA;MAEP,EAAS,SAAS,KAAK,CAAC,IACvB,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAS,SAAS,EAAS,SACxB,EACE,uCACA,kDACA;QAAE,OAAO,EAAS;QAAQ,OAAO,EAAS;QAAQ,CACnD,GACD,IACE,EACE,mCACA,+DACA,EAAE,OAAO,EAAS,QAAQ,CAC3B,GACD,EAAG,kCAAkC,kCAAkC,EACrE,OAAO,EAAS,QACjB,CAAC;OACN,CAAA,GACF;MACJ,kBAAC,IAAD;OAAmB;OAAkB;OAAS,SAAS;OAAQ,CAAA;MACnD;;IACT;KACI"}