bitsnap-react 1.7.1 → 1.9.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 (112) hide show
  1. package/README.md +130 -0
  2. package/dist/CartProvider-XWTLBIZ5.js +2 -0
  3. package/dist/CartProvider-XWTLBIZ5.js.map +1 -0
  4. package/dist/CartProvider-ZURLJNBW.mjs +2 -0
  5. package/dist/analytics.d.mts +28 -0
  6. package/dist/analytics.d.ts +28 -0
  7. package/dist/analytics.js +2 -0
  8. package/dist/analytics.js.map +1 -0
  9. package/dist/analytics.mjs +2 -0
  10. package/dist/catalog.d.mts +14 -1
  11. package/dist/catalog.d.ts +14 -1
  12. package/dist/catalog.js +1 -1
  13. package/dist/catalog.js.map +1 -1
  14. package/dist/catalog.mjs +1 -1
  15. package/dist/chunk-3IMJALBX.js +2 -0
  16. package/dist/chunk-3IMJALBX.js.map +1 -0
  17. package/dist/chunk-3UHPJ6NK.js +2 -0
  18. package/dist/chunk-3UHPJ6NK.js.map +1 -0
  19. package/dist/chunk-CO2P4FR5.js +2 -0
  20. package/dist/chunk-CO2P4FR5.js.map +1 -0
  21. package/dist/chunk-E6QVQEGZ.mjs +2 -0
  22. package/dist/chunk-E6QVQEGZ.mjs.map +1 -0
  23. package/dist/chunk-FHDFLSPW.js +2 -0
  24. package/dist/chunk-FHDFLSPW.js.map +1 -0
  25. package/dist/{chunk-6KQBDN7M.mjs → chunk-GN63ITLA.mjs} +2 -2
  26. package/dist/chunk-HKVMSMDF.mjs +2 -0
  27. package/dist/chunk-HKVMSMDF.mjs.map +1 -0
  28. package/dist/chunk-JSDGZ4NY.js +2 -0
  29. package/dist/chunk-JSDGZ4NY.js.map +1 -0
  30. package/dist/chunk-KG6RU37U.js +4 -0
  31. package/dist/chunk-KG6RU37U.js.map +1 -0
  32. package/dist/chunk-KOVKUJAW.mjs +2 -0
  33. package/dist/chunk-KOVKUJAW.mjs.map +1 -0
  34. package/dist/chunk-KOYBZORL.js +2 -0
  35. package/dist/chunk-KOYBZORL.js.map +1 -0
  36. package/dist/chunk-LJWS6ZRJ.mjs +2 -0
  37. package/dist/chunk-LJWS6ZRJ.mjs.map +1 -0
  38. package/dist/chunk-LZE2E4TE.mjs +4 -0
  39. package/dist/chunk-LZE2E4TE.mjs.map +1 -0
  40. package/dist/chunk-QZJGNLCZ.js +2 -0
  41. package/dist/chunk-QZJGNLCZ.js.map +1 -0
  42. package/dist/chunk-RA452LXZ.mjs +2 -0
  43. package/dist/chunk-RA452LXZ.mjs.map +1 -0
  44. package/dist/chunk-SLLBTQTW.mjs +2 -0
  45. package/dist/chunk-SLLBTQTW.mjs.map +1 -0
  46. package/dist/chunk-SZ256RCC.mjs +2 -0
  47. package/dist/chunk-SZ256RCC.mjs.map +1 -0
  48. package/dist/chunk-V4U2PTKN.js +2 -0
  49. package/dist/chunk-V4U2PTKN.js.map +1 -0
  50. package/dist/chunk-VM6JEJFZ.js +2 -0
  51. package/dist/chunk-VM6JEJFZ.js.map +1 -0
  52. package/dist/chunk-VXB7LA4E.js +2 -0
  53. package/dist/chunk-VXB7LA4E.js.map +1 -0
  54. package/dist/chunk-XVQKEGPO.mjs +2 -0
  55. package/dist/chunk-XVQKEGPO.mjs.map +1 -0
  56. package/dist/consent.d.mts +158 -0
  57. package/dist/consent.d.ts +158 -0
  58. package/dist/consent.js +75 -0
  59. package/dist/consent.js.map +1 -0
  60. package/dist/consent.mjs +75 -0
  61. package/dist/consent.mjs.map +1 -0
  62. package/dist/course.d.mts +1882 -0
  63. package/dist/course.d.ts +1882 -0
  64. package/dist/course.js +2 -0
  65. package/dist/course.js.map +1 -0
  66. package/dist/course.mjs +2 -0
  67. package/dist/course.mjs.map +1 -0
  68. package/dist/embed/analytics.js +1 -0
  69. package/dist/embed/consent.js +74 -0
  70. package/dist/errors.js +1 -1
  71. package/dist/errors.js.map +1 -1
  72. package/dist/index.css +1 -1
  73. package/dist/index.css.map +1 -1
  74. package/dist/index.d.mts +56 -40
  75. package/dist/index.d.ts +56 -40
  76. package/dist/index.js +1 -3
  77. package/dist/index.js.map +1 -1
  78. package/dist/index.mjs +1 -1
  79. package/dist/index.mjs.map +1 -1
  80. package/dist/instrument-C_abZLHk.d.mts +912 -0
  81. package/dist/instrument-C_abZLHk.d.ts +912 -0
  82. package/dist/internal.js +1 -1
  83. package/dist/internal.js.map +1 -1
  84. package/dist/methods-CYARZTYL.mjs +2 -0
  85. package/dist/methods-CYARZTYL.mjs.map +1 -0
  86. package/dist/methods-DAPEWVI6.js +2 -0
  87. package/dist/methods-DAPEWVI6.js.map +1 -0
  88. package/dist/models.js +1 -1
  89. package/dist/models.js.map +1 -1
  90. package/dist/returns.d.mts +14 -196
  91. package/dist/returns.d.ts +14 -196
  92. package/dist/returns.js +1 -1
  93. package/dist/returns.js.map +1 -1
  94. package/dist/returns.mjs +1 -1
  95. package/dist/texts-CIEFbJTN.d.ts +196 -0
  96. package/dist/texts-tQtAGJCT.d.mts +196 -0
  97. package/dist/types-BaqLJYuq.d.ts +53 -0
  98. package/dist/types-D_WnqwR_.d.mts +53 -0
  99. package/package.json +41 -5
  100. package/dist/CartProvider-F2VH7WFO.mjs +0 -2
  101. package/dist/chunk-3TENJTY4.mjs +0 -2
  102. package/dist/chunk-3TENJTY4.mjs.map +0 -1
  103. package/dist/chunk-4HOZFM6V.mjs +0 -2
  104. package/dist/chunk-4HOZFM6V.mjs.map +0 -1
  105. package/dist/chunk-FTYJTO6O.mjs +0 -2
  106. package/dist/chunk-FTYJTO6O.mjs.map +0 -1
  107. package/dist/chunk-RATFYRKZ.mjs +0 -4
  108. package/dist/chunk-RATFYRKZ.mjs.map +0 -1
  109. package/dist/methods-PFZSMZFU.mjs +0 -2
  110. /package/dist/{CartProvider-F2VH7WFO.mjs.map → CartProvider-ZURLJNBW.mjs.map} +0 -0
  111. /package/dist/{methods-PFZSMZFU.mjs.map → analytics.mjs.map} +0 -0
  112. /package/dist/{chunk-6KQBDN7M.mjs.map → chunk-GN63ITLA.mjs.map} +0 -0
@@ -0,0 +1,1882 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { A as AnalyticsOption } from './instrument-C_abZLHk.js';
3
+ import { G as GetThemeOutput } from './types-BaqLJYuq.js';
4
+ import { Client } from '@connectrpc/connect';
5
+ import { GenService, GenMessage } from '@bufbuild/protobuf/codegenv2';
6
+ import { Timestamp } from '@bufbuild/protobuf/wkt';
7
+ import { Message } from '@bufbuild/protobuf';
8
+ import 'react';
9
+ import './texts-CIEFbJTN.js';
10
+ import './appearance-core-Dt2grZdl.js';
11
+
12
+ /**
13
+ * Shared text machinery: typed string tables per locale, the locale fallback
14
+ * and a merge with caller overrides. Each module (checkout, later returns)
15
+ * supplies its own key type and default tables.
16
+ */
17
+ /** Strings of one locale, keyed by text key. */
18
+ type TextTable<Key extends string> = Record<Key, string>;
19
+ /** Default tables for the supported locales. */
20
+ type LocaleTables<Key extends string> = {
21
+ en: TextTable<Key>;
22
+ pl: TextTable<Key>;
23
+ };
24
+
25
+ /**
26
+ * Every string of the course view. Pass a partial object through the `texts`
27
+ * prop of `PanelCourse` to override any of them, whatever the locale.
28
+ * Placeholders like `{count}` stay in overrides.
29
+ */
30
+ type CourseTexts = {
31
+ back: string;
32
+ loading: string;
33
+ retry: string;
34
+ errorGeneric: string;
35
+ errorUnauthorized: string;
36
+ errorNotFound: string;
37
+ errorUnavailable: string;
38
+ previewBadge: string;
39
+ /** Placeholders `{done}` and `{total}`. */
40
+ progressLessons: string;
41
+ /** Placeholder `{percent}`. */
42
+ progressPercent: string;
43
+ contents: string;
44
+ free: string;
45
+ locked: string;
46
+ /** Placeholder `{test}`. */
47
+ lockedByTest: string;
48
+ /** Placeholder `{test}`. */
49
+ lockedPage: string;
50
+ testBadge: string;
51
+ completed: string;
52
+ continueCourse: string;
53
+ noItem: string;
54
+ markComplete: string;
55
+ markedComplete: string;
56
+ prevItem: string;
57
+ nextItem: string;
58
+ attachments: string;
59
+ download: string;
60
+ autoplay: string;
61
+ videoError: string;
62
+ videoRetry: string;
63
+ noContent: string;
64
+ testGating: string;
65
+ testAttemptsLeft: string;
66
+ testAttemptsUnlimited: string;
67
+ testNoAttemptsLeft: string;
68
+ testPassThreshold: string;
69
+ testBestScore: string;
70
+ testSubmit: string;
71
+ testSubmitting: string;
72
+ /** Placeholder `{count}`. */
73
+ testUnanswered: string;
74
+ testPassed: string;
75
+ testFailed: string;
76
+ /** Placeholder `{percent}`. */
77
+ testScore: string;
78
+ testCorrect: string;
79
+ testIncorrect: string;
80
+ testCorrectAnswer: string;
81
+ testTryAgain: string;
82
+ testPreviousAttempts: string;
83
+ /** Placeholders `{percent}` and `{date}`. */
84
+ testAttemptRow: string;
85
+ testNoQuestions: string;
86
+ mcqSingle: string;
87
+ mcqMultiple: string;
88
+ todoHint: string;
89
+ todoRequired: string;
90
+ gapPlaceholder: string;
91
+ sortHint: string;
92
+ moveUp: string;
93
+ moveDown: string;
94
+ questionsTitle: string;
95
+ questionsEmpty: string;
96
+ questionPlaceholder: string;
97
+ questionSubmit: string;
98
+ questionSent: string;
99
+ questionMine: string;
100
+ questionTeamAnswer: string;
101
+ rateTitle: string;
102
+ /** Placeholder `{n}`. */
103
+ rateStar: string;
104
+ ratePlaceholder: string;
105
+ rateSubmit: string;
106
+ rateSaved: string;
107
+ /** Placeholders `{average}` and `{count}`. */
108
+ rateAverage: string;
109
+ };
110
+ declare const COURSE_TEXT_TABLES: LocaleTables<keyof CourseTexts>;
111
+ /** Course strings for a locale (library locale by default) with overrides. */
112
+ declare function getCourseTexts(overrides?: Partial<CourseTexts>, locale?: string): CourseTexts;
113
+
114
+ /**
115
+ * Domain model of the course view. It is independent of the generated
116
+ * protobuf messages, so a creator preview can feed `PanelCourse` through its
117
+ * own `CourseDataSource` without the RPC layer.
118
+ */
119
+ type CourseType = "standard" | "video";
120
+ type CourseItemKind = "lesson" | "test";
121
+ /** The gating test that has to be passed before the item opens. */
122
+ type LockReason = {
123
+ gatingTestId: string;
124
+ gatingTestTitle: string;
125
+ };
126
+ /** A lesson or a test in the list of a course. */
127
+ type CourseItem = {
128
+ /** Unique among all items of the course. */
129
+ id: string;
130
+ kind: CourseItemKind;
131
+ title: string;
132
+ isFree: boolean;
133
+ locked: boolean;
134
+ lockReason?: LockReason;
135
+ /** A lesson: completed. A test: passed. */
136
+ completed: boolean;
137
+ /** Video length, 0 when unknown. */
138
+ durationSeconds: number;
139
+ thumbnailUrl?: string;
140
+ /** Tests only: passing it unlocks the following sections. */
141
+ gating: boolean;
142
+ };
143
+ /** A module (standard course) or a section (video course). */
144
+ type CourseSection = {
145
+ id: string;
146
+ title: string;
147
+ description: string;
148
+ items: CourseItem[];
149
+ };
150
+ type Course = {
151
+ id: string;
152
+ type: CourseType;
153
+ title: string;
154
+ description: string;
155
+ coverUrl?: string;
156
+ totalLessons: number;
157
+ completedLessons: number;
158
+ /** 0 to 100. */
159
+ progressPercent: number;
160
+ sections: CourseSection[];
161
+ /** Tests of the whole course, after the last section. */
162
+ finalItems: CourseItem[];
163
+ /** Item to continue with; empty when everything is done. */
164
+ resumeItemId: string;
165
+ };
166
+ type ItemRef = {
167
+ id: string;
168
+ kind: CourseItemKind;
169
+ };
170
+ type LessonVideo = {
171
+ hlsUrl: string;
172
+ posterUrl?: string;
173
+ durationSeconds: number;
174
+ };
175
+ type LessonAttachment = {
176
+ id: string;
177
+ name: string;
178
+ /** Bytes. */
179
+ size: number;
180
+ url: string;
181
+ };
182
+ type Lesson = {
183
+ id: string;
184
+ sectionId: string;
185
+ title: string;
186
+ description: string;
187
+ /** Raw HTML of the editor. Always pass it through `sanitizeLessonHtml`. */
188
+ contentHtml: string;
189
+ video?: LessonVideo;
190
+ attachments: LessonAttachment[];
191
+ prev?: ItemRef;
192
+ next?: ItemRef;
193
+ completed: boolean;
194
+ /** Where the customer stopped the video. */
195
+ positionSeconds: number;
196
+ /** 0 when the customer has not rated the lesson. */
197
+ myRating: number;
198
+ averageRating: number;
199
+ ratingCount: number;
200
+ /** When the signed URLs stop working. */
201
+ urlsExpireAt?: Date;
202
+ };
203
+ type SaveProgressInput = {
204
+ lessonId: string;
205
+ completed: boolean;
206
+ positionSeconds: number;
207
+ durationSeconds: number;
208
+ };
209
+ type ProgressSaved = {
210
+ completed: boolean;
211
+ completedLessons: number;
212
+ progressPercent: number;
213
+ };
214
+ type TestChoice = {
215
+ id: string;
216
+ label: string;
217
+ };
218
+ type TestQuestionConfig = {
219
+ type: "mcq";
220
+ choices: TestChoice[];
221
+ multiple: boolean;
222
+ } | {
223
+ type: "todolist";
224
+ steps: {
225
+ id: string;
226
+ label: string;
227
+ required: boolean;
228
+ }[];
229
+ } | {
230
+ type: "fill_gap";
231
+ template: string;
232
+ blanks: string[];
233
+ } | {
234
+ type: "sort_order";
235
+ items: TestChoice[];
236
+ };
237
+ type TestQuestion = {
238
+ id: string;
239
+ prompt: string;
240
+ points: number;
241
+ config: TestQuestionConfig;
242
+ };
243
+ type QuestionAnswer = {
244
+ type: "mcq";
245
+ selectedIds: string[];
246
+ } | {
247
+ type: "todolist";
248
+ checkedIds: string[];
249
+ } | {
250
+ type: "fill_gap";
251
+ values: Record<string, string>;
252
+ } | {
253
+ type: "sort_order";
254
+ orderedIds: string[];
255
+ };
256
+ /** Answers by question id. */
257
+ type TestAnswers = Record<string, QuestionAnswer>;
258
+ type Test = {
259
+ id: string;
260
+ title: string;
261
+ description: string;
262
+ gating: boolean;
263
+ passThresholdPercent: number;
264
+ /** 0 means unlimited. */
265
+ attemptsAllowed: number;
266
+ /** `undefined` when the attempts are unlimited. */
267
+ attemptsLeft?: number;
268
+ attemptCount: number;
269
+ bestScorePercent: number;
270
+ passed: boolean;
271
+ questions: TestQuestion[];
272
+ };
273
+ type TestSubmission = {
274
+ id: string;
275
+ scorePercent: number;
276
+ passed: boolean;
277
+ durationMs: number;
278
+ createdAt?: Date;
279
+ };
280
+ type QuestionResult = {
281
+ questionId: string;
282
+ correct: boolean;
283
+ points: number;
284
+ /** Only when the show-answers rule of the test allows it. */
285
+ correctAnswer?: QuestionAnswer;
286
+ };
287
+ type TestResult = {
288
+ submission: TestSubmission;
289
+ results: QuestionResult[];
290
+ attemptsLeft?: number;
291
+ };
292
+ type TestSubmissionList = {
293
+ submissions: TestSubmission[];
294
+ bestScorePercent: number;
295
+ attemptCount: number;
296
+ };
297
+ type LessonQuestion = {
298
+ id: string;
299
+ content: string;
300
+ authorName: string;
301
+ isMine: boolean;
302
+ createdAt?: Date;
303
+ answer?: {
304
+ content: string;
305
+ createdAt?: Date;
306
+ };
307
+ };
308
+ type LessonRating = {
309
+ myRating: number;
310
+ averageRating: number;
311
+ ratingCount: number;
312
+ };
313
+ type CourseErrorCode = "unauthorized" | "course_not_found" | "item_not_found" | "item_locked" | "no_attempts_left" | "invalid_argument" | "rate_limited" | "unavailable" | "unknown";
314
+ /** Failure reported by a data source. */
315
+ declare class CourseError extends Error {
316
+ readonly code: CourseErrorCode;
317
+ constructor(code: CourseErrorCode, message?: string);
318
+ }
319
+ /**
320
+ * Everything `PanelCourse` needs from a backend, scoped to one course and one
321
+ * customer. Methods reject with `CourseError` for failures the view can
322
+ * explain (any other error is shown as a generic one).
323
+ *
324
+ * The default implementation is `createRpcCourseDataSource`; the creator
325
+ * preview of the Bitsnap dashboard passes its own.
326
+ */
327
+ interface CourseDataSource {
328
+ getCourse(): Promise<Course>;
329
+ getLesson(lessonId: string): Promise<Lesson>;
330
+ saveProgress(input: SaveProgressInput): Promise<ProgressSaved>;
331
+ getTest(testId: string): Promise<Test>;
332
+ submitTest(testId: string, answers: TestAnswers, durationMs: number): Promise<TestResult>;
333
+ listSubmissions(testId: string): Promise<TestSubmissionList>;
334
+ listQuestions(lessonId: string): Promise<LessonQuestion[]>;
335
+ askQuestion(lessonId: string, content: string): Promise<LessonQuestion>;
336
+ rate(lessonId: string, score: number, comment?: string): Promise<LessonRating>;
337
+ }
338
+
339
+ type PanelCourseProps = {
340
+ /** `UserProduct.access_id` of the purchased course. Not needed with `dataSource`. */
341
+ accessId?: string;
342
+ /** Panel session token; read from the panel session when omitted. */
343
+ accessToken?: string;
344
+ /**
345
+ * Replaces the default data source (`UserPanelCourseService` through the
346
+ * panel's transport). The creator preview of the dashboard passes its own.
347
+ */
348
+ dataSource?: CourseDataSource;
349
+ /** Creator preview: shows a badge and never saves progress. */
350
+ preview?: boolean;
351
+ /** The open lesson or test. Controlled together with `onItemChange`. */
352
+ itemId?: string;
353
+ onItemChange?: (itemId: string) => void;
354
+ /** Shows a back button. */
355
+ onBack?: () => void;
356
+ /** Course structure to render right away (server rendering, preview). */
357
+ initialCourse?: Course;
358
+ /** Text overrides; Polish and English defaults by `locale`. */
359
+ texts?: Partial<CourseTexts>;
360
+ /** Defaults to the locale of the library (`setLocale`). */
361
+ locale?: string;
362
+ /** Brand colors; the panel theme (`setTheme`) by default. */
363
+ theme?: GetThemeOutput;
364
+ className?: string;
365
+ /**
366
+ * Usage statistics for your Bitsnap dashboard (course opened, lessons
367
+ * started and completed, video progress, tests, ratings). On by default;
368
+ * `false` turns it off, and the creator `preview` never reports. Inside
369
+ * `<Panel>` the panel's setting applies unless this is given. An object
370
+ * lets you forward every event: `{ onEvent }`. Nothing is stored on the
371
+ * visitor's device.
372
+ */
373
+ analytics?: AnalyticsOption;
374
+ };
375
+ /**
376
+ * The course of a customer inside the panel: structure with progress and
377
+ * locks, lessons with video, text and attachments, tests, questions and
378
+ * ratings. Standard courses get a sidebar of modules, video courses a
379
+ * playlist next to the player.
380
+ *
381
+ * Load it lazily from `bitsnap-react/course`. Inside the panel it needs only
382
+ * `accessId` of the purchased course.
383
+ */
384
+ declare function PanelCourse$1({ accessId, accessToken, dataSource: customDataSource, preview, itemId, onItemChange, onBack, initialCourse, texts: textOverrides, locale, theme, className, analytics, }: PanelCourseProps): react_jsx_runtime.JSX.Element;
385
+
386
+ type RpcCourseDataSourceOptions = {
387
+ /** `UserProduct.access_id` of the purchased course. */
388
+ accessId: string;
389
+ /**
390
+ * Panel session token. By default it is read from the panel session of the
391
+ * configured project (`setProjectID`, `setHost`) on every call.
392
+ */
393
+ accessToken?: string;
394
+ /** Bitsnap host; the panel host (`setHost`, bitsnap.pl by default) otherwise. */
395
+ host?: string;
396
+ };
397
+ /**
398
+ * Default data source: `UserPanelCourseService` on `{host}/api/rpc`, using the
399
+ * transport and the session token of the panel.
400
+ */
401
+ declare function createRpcCourseDataSource(options: RpcCourseDataSourceOptions): CourseDataSource;
402
+
403
+ /**
404
+ * Why an item is locked.
405
+ *
406
+ * @generated from message public_api.v1.PanelLockReason
407
+ */
408
+ type PanelLockReason = Message<"public_api.v1.PanelLockReason"> & {
409
+ /**
410
+ * The test (of an earlier module) that has to be passed first.
411
+ *
412
+ * @generated from field: string gating_test_id = 1;
413
+ */
414
+ gatingTestId: string;
415
+ /**
416
+ * @generated from field: string gating_test_title = 2;
417
+ */
418
+ gatingTestTitle: string;
419
+ };
420
+ /**
421
+ * A lesson or a test in the list of a course.
422
+ *
423
+ * @generated from message public_api.v1.PanelCourseItem
424
+ */
425
+ type PanelCourseItem = Message<"public_api.v1.PanelCourseItem"> & {
426
+ /**
427
+ * Unique among all items of the course, lessons and tests alike.
428
+ *
429
+ * @generated from field: string id = 1;
430
+ */
431
+ id: string;
432
+ /**
433
+ * @generated from field: public_api.v1.PanelCourseItemKind kind = 2;
434
+ */
435
+ kind: PanelCourseItemKind;
436
+ /**
437
+ * @generated from field: string title = 3;
438
+ */
439
+ title: string;
440
+ /**
441
+ * Free for everyone, shown as a badge.
442
+ *
443
+ * @generated from field: bool is_free = 4;
444
+ */
445
+ isFree: boolean;
446
+ /**
447
+ * A locked item can't be opened (GetLesson/GetTest fail with ITEM_LOCKED).
448
+ *
449
+ * @generated from field: bool locked = 5;
450
+ */
451
+ locked: boolean;
452
+ /**
453
+ * Set when locked.
454
+ *
455
+ * @generated from field: optional public_api.v1.PanelLockReason lock_reason = 6;
456
+ */
457
+ lockReason?: PanelLockReason;
458
+ /**
459
+ * A lesson: completed. A test: passed.
460
+ *
461
+ * @generated from field: bool completed = 7;
462
+ */
463
+ completed: boolean;
464
+ /**
465
+ * Video length in seconds; 0 when unknown or the lesson has no video.
466
+ *
467
+ * @generated from field: int32 duration_seconds = 8;
468
+ */
469
+ durationSeconds: number;
470
+ /**
471
+ * Signed URL of the thumbnail; unset when there is none.
472
+ *
473
+ * @generated from field: optional string thumbnail_url = 9;
474
+ */
475
+ thumbnailUrl?: string;
476
+ /**
477
+ * Tests only: lessons of the following sections stay locked until it is passed.
478
+ *
479
+ * @generated from field: bool gating = 10;
480
+ */
481
+ gating: boolean;
482
+ };
483
+ /**
484
+ * A module (standard course) or a section (video course).
485
+ *
486
+ * @generated from message public_api.v1.PanelCourseSection
487
+ */
488
+ type PanelCourseSection = Message<"public_api.v1.PanelCourseSection"> & {
489
+ /**
490
+ * @generated from field: string id = 1;
491
+ */
492
+ id: string;
493
+ /**
494
+ * @generated from field: string title = 2;
495
+ */
496
+ title: string;
497
+ /**
498
+ * @generated from field: string description = 3;
499
+ */
500
+ description: string;
501
+ /**
502
+ * Lessons in order, then the tests of the section.
503
+ *
504
+ * @generated from field: repeated public_api.v1.PanelCourseItem items = 4;
505
+ */
506
+ items: PanelCourseItem[];
507
+ };
508
+ /**
509
+ * @generated from message public_api.v1.PanelCourse
510
+ */
511
+ type PanelCourse = Message<"public_api.v1.PanelCourse"> & {
512
+ /**
513
+ * Id of the course in Bitsnap (stable, used in the URL of the panel).
514
+ *
515
+ * @generated from field: string id = 1;
516
+ */
517
+ id: string;
518
+ /**
519
+ * @generated from field: public_api.v1.PanelCourseType type = 2;
520
+ */
521
+ type: PanelCourseType;
522
+ /**
523
+ * @generated from field: string title = 3;
524
+ */
525
+ title: string;
526
+ /**
527
+ * @generated from field: string description = 4;
528
+ */
529
+ description: string;
530
+ /**
531
+ * Signed URL of the cover; unset when the course has none.
532
+ *
533
+ * @generated from field: optional string cover_url = 5;
534
+ */
535
+ coverUrl?: string;
536
+ /**
537
+ * @generated from field: int32 total_lessons = 6;
538
+ */
539
+ totalLessons: number;
540
+ /**
541
+ * @generated from field: int32 completed_lessons = 7;
542
+ */
543
+ completedLessons: number;
544
+ /**
545
+ * 0 to 100.
546
+ *
547
+ * @generated from field: int32 progress_percent = 8;
548
+ */
549
+ progressPercent: number;
550
+ /**
551
+ * @generated from field: repeated public_api.v1.PanelCourseSection sections = 9;
552
+ */
553
+ sections: PanelCourseSection[];
554
+ /**
555
+ * Tests of the whole course, shown after the last section.
556
+ *
557
+ * @generated from field: repeated public_api.v1.PanelCourseItem final_items = 10;
558
+ */
559
+ finalItems: PanelCourseItem[];
560
+ /**
561
+ * Item to continue with (first unfinished and unlocked lesson); empty when
562
+ * everything is done.
563
+ *
564
+ * @generated from field: string resume_item_id = 11;
565
+ */
566
+ resumeItemId: string;
567
+ };
568
+ /**
569
+ * @generated from message public_api.v1.UserPanelGetCourseRequest
570
+ */
571
+ type UserPanelGetCourseRequest = Message<"public_api.v1.UserPanelGetCourseRequest"> & {
572
+ /**
573
+ * @generated from field: string access_token = 1;
574
+ */
575
+ accessToken: string;
576
+ /**
577
+ * @generated from field: string access_id = 2;
578
+ */
579
+ accessId: string;
580
+ };
581
+ /**
582
+ * Describes the message public_api.v1.UserPanelGetCourseRequest.
583
+ * Use `create(UserPanelGetCourseRequestSchema)` to create a new message.
584
+ */
585
+ declare const UserPanelGetCourseRequestSchema: GenMessage<UserPanelGetCourseRequest>;
586
+ /**
587
+ * @generated from message public_api.v1.UserPanelGetCourseResponse
588
+ */
589
+ type UserPanelGetCourseResponse = Message<"public_api.v1.UserPanelGetCourseResponse"> & {
590
+ /**
591
+ * @generated from oneof public_api.v1.UserPanelGetCourseResponse.result
592
+ */
593
+ result: {
594
+ /**
595
+ * @generated from field: public_api.v1.PanelCourse success = 1;
596
+ */
597
+ value: PanelCourse;
598
+ case: "success";
599
+ } | {
600
+ /**
601
+ * @generated from field: public_api.v1.PanelCourseFailure failure = 2;
602
+ */
603
+ value: PanelCourseFailure;
604
+ case: "failure";
605
+ } | {
606
+ case: undefined;
607
+ value?: undefined;
608
+ };
609
+ };
610
+ /**
611
+ * Describes the message public_api.v1.UserPanelGetCourseResponse.
612
+ * Use `create(UserPanelGetCourseResponseSchema)` to create a new message.
613
+ */
614
+ declare const UserPanelGetCourseResponseSchema: GenMessage<UserPanelGetCourseResponse>;
615
+ /**
616
+ * @generated from message public_api.v1.PanelVideo
617
+ */
618
+ type PanelVideo = Message<"public_api.v1.PanelVideo"> & {
619
+ /**
620
+ * Cloudflare Stream HLS manifest URL with a signed token.
621
+ *
622
+ * @generated from field: string hls_url = 1;
623
+ */
624
+ hlsUrl: string;
625
+ /**
626
+ * @generated from field: optional string poster_url = 2;
627
+ */
628
+ posterUrl?: string;
629
+ /**
630
+ * @generated from field: int32 duration_seconds = 3;
631
+ */
632
+ durationSeconds: number;
633
+ };
634
+ /**
635
+ * @generated from message public_api.v1.PanelAttachment
636
+ */
637
+ type PanelAttachment = Message<"public_api.v1.PanelAttachment"> & {
638
+ /**
639
+ * @generated from field: string id = 1;
640
+ */
641
+ id: string;
642
+ /**
643
+ * @generated from field: string name = 2;
644
+ */
645
+ name: string;
646
+ /**
647
+ * Bytes.
648
+ *
649
+ * @generated from field: int64 size = 3;
650
+ */
651
+ size: bigint;
652
+ /**
653
+ * Presigned S3 URL.
654
+ *
655
+ * @generated from field: string url = 4;
656
+ */
657
+ url: string;
658
+ };
659
+ /**
660
+ * Neighbour of a lesson in the course order.
661
+ *
662
+ * @generated from message public_api.v1.PanelItemRef
663
+ */
664
+ type PanelItemRef = Message<"public_api.v1.PanelItemRef"> & {
665
+ /**
666
+ * @generated from field: string id = 1;
667
+ */
668
+ id: string;
669
+ /**
670
+ * @generated from field: public_api.v1.PanelCourseItemKind kind = 2;
671
+ */
672
+ kind: PanelCourseItemKind;
673
+ };
674
+ /**
675
+ * @generated from message public_api.v1.PanelLesson
676
+ */
677
+ type PanelLesson = Message<"public_api.v1.PanelLesson"> & {
678
+ /**
679
+ * @generated from field: string id = 1;
680
+ */
681
+ id: string;
682
+ /**
683
+ * @generated from field: string section_id = 2;
684
+ */
685
+ sectionId: string;
686
+ /**
687
+ * @generated from field: string title = 3;
688
+ */
689
+ title: string;
690
+ /**
691
+ * Plain text, mainly for video lessons.
692
+ *
693
+ * @generated from field: string description = 4;
694
+ */
695
+ description: string;
696
+ /**
697
+ * HTML from the editor of the creator. The client sanitises it before it
698
+ * renders it, the server should too.
699
+ *
700
+ * @generated from field: string content_html = 5;
701
+ */
702
+ contentHtml: string;
703
+ /**
704
+ * Unset when the lesson has no video.
705
+ *
706
+ * @generated from field: optional public_api.v1.PanelVideo video = 6;
707
+ */
708
+ video?: PanelVideo;
709
+ /**
710
+ * @generated from field: repeated public_api.v1.PanelAttachment attachments = 7;
711
+ */
712
+ attachments: PanelAttachment[];
713
+ /**
714
+ * Unset for the first / last item of the course.
715
+ *
716
+ * @generated from field: optional public_api.v1.PanelItemRef prev = 8;
717
+ */
718
+ prev?: PanelItemRef;
719
+ /**
720
+ * @generated from field: optional public_api.v1.PanelItemRef next = 9;
721
+ */
722
+ next?: PanelItemRef;
723
+ /**
724
+ * @generated from field: bool completed = 10;
725
+ */
726
+ completed: boolean;
727
+ /**
728
+ * Where the customer stopped the video, to resume from.
729
+ *
730
+ * @generated from field: int32 position_seconds = 11;
731
+ */
732
+ positionSeconds: number;
733
+ /**
734
+ * Rating of the customer, 0 when not rated.
735
+ *
736
+ * @generated from field: int32 my_rating = 12;
737
+ */
738
+ myRating: number;
739
+ /**
740
+ * @generated from field: float average_rating = 13;
741
+ */
742
+ averageRating: number;
743
+ /**
744
+ * @generated from field: int32 rating_count = 14;
745
+ */
746
+ ratingCount: number;
747
+ /**
748
+ * When the signed URLs (video, attachments) stop working; unset when unknown.
749
+ *
750
+ * @generated from field: optional google.protobuf.Timestamp urls_expire_at = 15;
751
+ */
752
+ urlsExpireAt?: Timestamp;
753
+ };
754
+ /**
755
+ * @generated from message public_api.v1.UserPanelGetLessonRequest
756
+ */
757
+ type UserPanelGetLessonRequest = Message<"public_api.v1.UserPanelGetLessonRequest"> & {
758
+ /**
759
+ * @generated from field: string access_token = 1;
760
+ */
761
+ accessToken: string;
762
+ /**
763
+ * @generated from field: string access_id = 2;
764
+ */
765
+ accessId: string;
766
+ /**
767
+ * @generated from field: string lesson_id = 3;
768
+ */
769
+ lessonId: string;
770
+ };
771
+ /**
772
+ * Describes the message public_api.v1.UserPanelGetLessonRequest.
773
+ * Use `create(UserPanelGetLessonRequestSchema)` to create a new message.
774
+ */
775
+ declare const UserPanelGetLessonRequestSchema: GenMessage<UserPanelGetLessonRequest>;
776
+ /**
777
+ * @generated from message public_api.v1.UserPanelGetLessonResponse
778
+ */
779
+ type UserPanelGetLessonResponse = Message<"public_api.v1.UserPanelGetLessonResponse"> & {
780
+ /**
781
+ * @generated from oneof public_api.v1.UserPanelGetLessonResponse.result
782
+ */
783
+ result: {
784
+ /**
785
+ * @generated from field: public_api.v1.PanelLesson success = 1;
786
+ */
787
+ value: PanelLesson;
788
+ case: "success";
789
+ } | {
790
+ /**
791
+ * @generated from field: public_api.v1.PanelCourseFailure failure = 2;
792
+ */
793
+ value: PanelCourseFailure;
794
+ case: "failure";
795
+ } | {
796
+ case: undefined;
797
+ value?: undefined;
798
+ };
799
+ };
800
+ /**
801
+ * Describes the message public_api.v1.UserPanelGetLessonResponse.
802
+ * Use `create(UserPanelGetLessonResponseSchema)` to create a new message.
803
+ */
804
+ declare const UserPanelGetLessonResponseSchema: GenMessage<UserPanelGetLessonResponse>;
805
+ /**
806
+ * @generated from message public_api.v1.UserPanelSaveLessonProgressRequest
807
+ */
808
+ type UserPanelSaveLessonProgressRequest = Message<"public_api.v1.UserPanelSaveLessonProgressRequest"> & {
809
+ /**
810
+ * @generated from field: string access_token = 1;
811
+ */
812
+ accessToken: string;
813
+ /**
814
+ * @generated from field: string access_id = 2;
815
+ */
816
+ accessId: string;
817
+ /**
818
+ * @generated from field: string lesson_id = 3;
819
+ */
820
+ lessonId: string;
821
+ /**
822
+ * Mark the lesson completed. Never un-completes a lesson.
823
+ *
824
+ * @generated from field: bool completed = 4;
825
+ */
826
+ completed: boolean;
827
+ /**
828
+ * Playback position in seconds.
829
+ *
830
+ * @generated from field: int32 position_seconds = 5;
831
+ */
832
+ positionSeconds: number;
833
+ /**
834
+ * Length of the video in seconds, so the server can compute the percentage.
835
+ *
836
+ * @generated from field: int32 duration_seconds = 6;
837
+ */
838
+ durationSeconds: number;
839
+ };
840
+ /**
841
+ * Describes the message public_api.v1.UserPanelSaveLessonProgressRequest.
842
+ * Use `create(UserPanelSaveLessonProgressRequestSchema)` to create a new message.
843
+ */
844
+ declare const UserPanelSaveLessonProgressRequestSchema: GenMessage<UserPanelSaveLessonProgressRequest>;
845
+ /**
846
+ * @generated from message public_api.v1.UserPanelSaveLessonProgressResponse
847
+ */
848
+ type UserPanelSaveLessonProgressResponse = Message<"public_api.v1.UserPanelSaveLessonProgressResponse"> & {
849
+ /**
850
+ * @generated from oneof public_api.v1.UserPanelSaveLessonProgressResponse.result
851
+ */
852
+ result: {
853
+ /**
854
+ * @generated from field: public_api.v1.UserPanelSaveLessonProgressResponse.Result success = 1;
855
+ */
856
+ value: UserPanelSaveLessonProgressResponse_Result;
857
+ case: "success";
858
+ } | {
859
+ /**
860
+ * @generated from field: public_api.v1.PanelCourseFailure failure = 2;
861
+ */
862
+ value: PanelCourseFailure;
863
+ case: "failure";
864
+ } | {
865
+ case: undefined;
866
+ value?: undefined;
867
+ };
868
+ };
869
+ /**
870
+ * Describes the message public_api.v1.UserPanelSaveLessonProgressResponse.
871
+ * Use `create(UserPanelSaveLessonProgressResponseSchema)` to create a new message.
872
+ */
873
+ declare const UserPanelSaveLessonProgressResponseSchema: GenMessage<UserPanelSaveLessonProgressResponse>;
874
+ /**
875
+ * @generated from message public_api.v1.UserPanelSaveLessonProgressResponse.Result
876
+ */
877
+ type UserPanelSaveLessonProgressResponse_Result = Message<"public_api.v1.UserPanelSaveLessonProgressResponse.Result"> & {
878
+ /**
879
+ * @generated from field: bool completed = 1;
880
+ */
881
+ completed: boolean;
882
+ /**
883
+ * Updated numbers of the whole course.
884
+ *
885
+ * @generated from field: int32 completed_lessons = 2;
886
+ */
887
+ completedLessons: number;
888
+ /**
889
+ * @generated from field: int32 progress_percent = 3;
890
+ */
891
+ progressPercent: number;
892
+ };
893
+ /**
894
+ * @generated from message public_api.v1.PanelChoice
895
+ */
896
+ type PanelChoice = Message<"public_api.v1.PanelChoice"> & {
897
+ /**
898
+ * @generated from field: string id = 1;
899
+ */
900
+ id: string;
901
+ /**
902
+ * @generated from field: string label = 2;
903
+ */
904
+ label: string;
905
+ };
906
+ /**
907
+ * Multiple choice question.
908
+ *
909
+ * @generated from message public_api.v1.PanelMcqConfig
910
+ */
911
+ type PanelMcqConfig = Message<"public_api.v1.PanelMcqConfig"> & {
912
+ /**
913
+ * @generated from field: repeated public_api.v1.PanelChoice choices = 1;
914
+ */
915
+ choices: PanelChoice[];
916
+ /**
917
+ * True when more than one choice may be selected (checkboxes), false for
918
+ * radio buttons. Does not tell how many answers are correct.
919
+ *
920
+ * @generated from field: bool multiple = 2;
921
+ */
922
+ multiple: boolean;
923
+ };
924
+ /**
925
+ * A checklist: all required steps have to be checked.
926
+ *
927
+ * @generated from message public_api.v1.PanelTodolistConfig
928
+ */
929
+ type PanelTodolistConfig = Message<"public_api.v1.PanelTodolistConfig"> & {
930
+ /**
931
+ * @generated from field: repeated public_api.v1.PanelTodolistConfig.Step steps = 1;
932
+ */
933
+ steps: PanelTodolistConfig_Step[];
934
+ };
935
+ /**
936
+ * @generated from message public_api.v1.PanelTodolistConfig.Step
937
+ */
938
+ type PanelTodolistConfig_Step = Message<"public_api.v1.PanelTodolistConfig.Step"> & {
939
+ /**
940
+ * @generated from field: string id = 1;
941
+ */
942
+ id: string;
943
+ /**
944
+ * @generated from field: string label = 2;
945
+ */
946
+ label: string;
947
+ /**
948
+ * @generated from field: bool required = 3;
949
+ */
950
+ required: boolean;
951
+ };
952
+ /**
953
+ * Text with gaps.
954
+ *
955
+ * @generated from message public_api.v1.PanelFillGapConfig
956
+ */
957
+ type PanelFillGapConfig = Message<"public_api.v1.PanelFillGapConfig"> & {
958
+ /**
959
+ * Text with placeholders `{{blank_id}}`, one for each id in `blanks`.
960
+ *
961
+ * @generated from field: string template = 1;
962
+ */
963
+ template: string;
964
+ /**
965
+ * @generated from field: repeated string blanks = 2;
966
+ */
967
+ blanks: string[];
968
+ };
969
+ /**
970
+ * Order the items. The server returns them already shuffled.
971
+ *
972
+ * @generated from message public_api.v1.PanelSortOrderConfig
973
+ */
974
+ type PanelSortOrderConfig = Message<"public_api.v1.PanelSortOrderConfig"> & {
975
+ /**
976
+ * @generated from field: repeated public_api.v1.PanelChoice items = 1;
977
+ */
978
+ items: PanelChoice[];
979
+ };
980
+ /**
981
+ * @generated from message public_api.v1.PanelTestQuestion
982
+ */
983
+ type PanelTestQuestion = Message<"public_api.v1.PanelTestQuestion"> & {
984
+ /**
985
+ * @generated from field: string id = 1;
986
+ */
987
+ id: string;
988
+ /**
989
+ * @generated from field: string prompt = 2;
990
+ */
991
+ prompt: string;
992
+ /**
993
+ * @generated from field: int32 points = 3;
994
+ */
995
+ points: number;
996
+ /**
997
+ * @generated from oneof public_api.v1.PanelTestQuestion.config
998
+ */
999
+ config: {
1000
+ /**
1001
+ * @generated from field: public_api.v1.PanelMcqConfig mcq = 10;
1002
+ */
1003
+ value: PanelMcqConfig;
1004
+ case: "mcq";
1005
+ } | {
1006
+ /**
1007
+ * @generated from field: public_api.v1.PanelTodolistConfig todolist = 11;
1008
+ */
1009
+ value: PanelTodolistConfig;
1010
+ case: "todolist";
1011
+ } | {
1012
+ /**
1013
+ * @generated from field: public_api.v1.PanelFillGapConfig fill_gap = 12;
1014
+ */
1015
+ value: PanelFillGapConfig;
1016
+ case: "fillGap";
1017
+ } | {
1018
+ /**
1019
+ * @generated from field: public_api.v1.PanelSortOrderConfig sort_order = 13;
1020
+ */
1021
+ value: PanelSortOrderConfig;
1022
+ case: "sortOrder";
1023
+ } | {
1024
+ case: undefined;
1025
+ value?: undefined;
1026
+ };
1027
+ };
1028
+ /**
1029
+ * @generated from message public_api.v1.PanelTest
1030
+ */
1031
+ type PanelTest = Message<"public_api.v1.PanelTest"> & {
1032
+ /**
1033
+ * @generated from field: string id = 1;
1034
+ */
1035
+ id: string;
1036
+ /**
1037
+ * @generated from field: string title = 2;
1038
+ */
1039
+ title: string;
1040
+ /**
1041
+ * @generated from field: string description = 3;
1042
+ */
1043
+ description: string;
1044
+ /**
1045
+ * Passing it unlocks the following sections.
1046
+ *
1047
+ * @generated from field: bool gating = 4;
1048
+ */
1049
+ gating: boolean;
1050
+ /**
1051
+ * Minimum score for a pass, 0 to 100.
1052
+ *
1053
+ * @generated from field: int32 pass_threshold_percent = 5;
1054
+ */
1055
+ passThresholdPercent: number;
1056
+ /**
1057
+ * 0 means unlimited.
1058
+ *
1059
+ * @generated from field: int32 attempts_allowed = 6;
1060
+ */
1061
+ attemptsAllowed: number;
1062
+ /**
1063
+ * Unset when the number of attempts is unlimited.
1064
+ *
1065
+ * @generated from field: optional int32 attempts_left = 7;
1066
+ */
1067
+ attemptsLeft?: number;
1068
+ /**
1069
+ * @generated from field: int32 attempt_count = 8;
1070
+ */
1071
+ attemptCount: number;
1072
+ /**
1073
+ * @generated from field: int32 best_score_percent = 9;
1074
+ */
1075
+ bestScorePercent: number;
1076
+ /**
1077
+ * @generated from field: bool passed = 10;
1078
+ */
1079
+ passed: boolean;
1080
+ /**
1081
+ * Questions in order, without the correct answers.
1082
+ *
1083
+ * @generated from field: repeated public_api.v1.PanelTestQuestion questions = 11;
1084
+ */
1085
+ questions: PanelTestQuestion[];
1086
+ };
1087
+ /**
1088
+ * @generated from message public_api.v1.UserPanelGetTestRequest
1089
+ */
1090
+ type UserPanelGetTestRequest = Message<"public_api.v1.UserPanelGetTestRequest"> & {
1091
+ /**
1092
+ * @generated from field: string access_token = 1;
1093
+ */
1094
+ accessToken: string;
1095
+ /**
1096
+ * @generated from field: string access_id = 2;
1097
+ */
1098
+ accessId: string;
1099
+ /**
1100
+ * @generated from field: string test_id = 3;
1101
+ */
1102
+ testId: string;
1103
+ };
1104
+ /**
1105
+ * Describes the message public_api.v1.UserPanelGetTestRequest.
1106
+ * Use `create(UserPanelGetTestRequestSchema)` to create a new message.
1107
+ */
1108
+ declare const UserPanelGetTestRequestSchema: GenMessage<UserPanelGetTestRequest>;
1109
+ /**
1110
+ * @generated from message public_api.v1.UserPanelGetTestResponse
1111
+ */
1112
+ type UserPanelGetTestResponse = Message<"public_api.v1.UserPanelGetTestResponse"> & {
1113
+ /**
1114
+ * @generated from oneof public_api.v1.UserPanelGetTestResponse.result
1115
+ */
1116
+ result: {
1117
+ /**
1118
+ * @generated from field: public_api.v1.PanelTest success = 1;
1119
+ */
1120
+ value: PanelTest;
1121
+ case: "success";
1122
+ } | {
1123
+ /**
1124
+ * @generated from field: public_api.v1.PanelCourseFailure failure = 2;
1125
+ */
1126
+ value: PanelCourseFailure;
1127
+ case: "failure";
1128
+ } | {
1129
+ case: undefined;
1130
+ value?: undefined;
1131
+ };
1132
+ };
1133
+ /**
1134
+ * Describes the message public_api.v1.UserPanelGetTestResponse.
1135
+ * Use `create(UserPanelGetTestResponseSchema)` to create a new message.
1136
+ */
1137
+ declare const UserPanelGetTestResponseSchema: GenMessage<UserPanelGetTestResponse>;
1138
+ /**
1139
+ * @generated from message public_api.v1.PanelMcqAnswer
1140
+ */
1141
+ type PanelMcqAnswer = Message<"public_api.v1.PanelMcqAnswer"> & {
1142
+ /**
1143
+ * @generated from field: repeated string selected_ids = 1;
1144
+ */
1145
+ selectedIds: string[];
1146
+ };
1147
+ /**
1148
+ * @generated from message public_api.v1.PanelTodolistAnswer
1149
+ */
1150
+ type PanelTodolistAnswer = Message<"public_api.v1.PanelTodolistAnswer"> & {
1151
+ /**
1152
+ * @generated from field: repeated string checked_ids = 1;
1153
+ */
1154
+ checkedIds: string[];
1155
+ };
1156
+ /**
1157
+ * @generated from message public_api.v1.PanelFillGapAnswer
1158
+ */
1159
+ type PanelFillGapAnswer = Message<"public_api.v1.PanelFillGapAnswer"> & {
1160
+ /**
1161
+ * blank id -> text typed by the customer.
1162
+ *
1163
+ * @generated from field: map<string, string> values = 1;
1164
+ */
1165
+ values: {
1166
+ [key: string]: string;
1167
+ };
1168
+ };
1169
+ /**
1170
+ * @generated from message public_api.v1.PanelSortOrderAnswer
1171
+ */
1172
+ type PanelSortOrderAnswer = Message<"public_api.v1.PanelSortOrderAnswer"> & {
1173
+ /**
1174
+ * @generated from field: repeated string ordered_ids = 1;
1175
+ */
1176
+ orderedIds: string[];
1177
+ };
1178
+ /**
1179
+ * An answer to one question. The variant has to match the question's config.
1180
+ *
1181
+ * @generated from message public_api.v1.PanelAnswer
1182
+ */
1183
+ type PanelAnswer = Message<"public_api.v1.PanelAnswer"> & {
1184
+ /**
1185
+ * @generated from field: string question_id = 1;
1186
+ */
1187
+ questionId: string;
1188
+ /**
1189
+ * @generated from oneof public_api.v1.PanelAnswer.value
1190
+ */
1191
+ value: {
1192
+ /**
1193
+ * @generated from field: public_api.v1.PanelMcqAnswer mcq = 10;
1194
+ */
1195
+ value: PanelMcqAnswer;
1196
+ case: "mcq";
1197
+ } | {
1198
+ /**
1199
+ * @generated from field: public_api.v1.PanelTodolistAnswer todolist = 11;
1200
+ */
1201
+ value: PanelTodolistAnswer;
1202
+ case: "todolist";
1203
+ } | {
1204
+ /**
1205
+ * @generated from field: public_api.v1.PanelFillGapAnswer fill_gap = 12;
1206
+ */
1207
+ value: PanelFillGapAnswer;
1208
+ case: "fillGap";
1209
+ } | {
1210
+ /**
1211
+ * @generated from field: public_api.v1.PanelSortOrderAnswer sort_order = 13;
1212
+ */
1213
+ value: PanelSortOrderAnswer;
1214
+ case: "sortOrder";
1215
+ } | {
1216
+ case: undefined;
1217
+ value?: undefined;
1218
+ };
1219
+ };
1220
+ /**
1221
+ * @generated from message public_api.v1.PanelTestSubmission
1222
+ */
1223
+ type PanelTestSubmission = Message<"public_api.v1.PanelTestSubmission"> & {
1224
+ /**
1225
+ * @generated from field: string id = 1;
1226
+ */
1227
+ id: string;
1228
+ /**
1229
+ * @generated from field: int32 score_percent = 2;
1230
+ */
1231
+ scorePercent: number;
1232
+ /**
1233
+ * @generated from field: bool passed = 3;
1234
+ */
1235
+ passed: boolean;
1236
+ /**
1237
+ * @generated from field: int64 duration_ms = 4;
1238
+ */
1239
+ durationMs: bigint;
1240
+ /**
1241
+ * @generated from field: google.protobuf.Timestamp created_at = 5;
1242
+ */
1243
+ createdAt?: Timestamp;
1244
+ };
1245
+ /**
1246
+ * @generated from message public_api.v1.PanelQuestionResult
1247
+ */
1248
+ type PanelQuestionResult = Message<"public_api.v1.PanelQuestionResult"> & {
1249
+ /**
1250
+ * @generated from field: string question_id = 1;
1251
+ */
1252
+ questionId: string;
1253
+ /**
1254
+ * @generated from field: bool correct = 2;
1255
+ */
1256
+ correct: boolean;
1257
+ /**
1258
+ * @generated from field: int32 points = 3;
1259
+ */
1260
+ points: number;
1261
+ /**
1262
+ * The correct answer; only set when the "show answers" rule of the test
1263
+ * allows it (after submit / after pass / never).
1264
+ *
1265
+ * @generated from field: optional public_api.v1.PanelAnswer correct_answer = 4;
1266
+ */
1267
+ correctAnswer?: PanelAnswer;
1268
+ };
1269
+ /**
1270
+ * @generated from message public_api.v1.UserPanelSubmitTestRequest
1271
+ */
1272
+ type UserPanelSubmitTestRequest = Message<"public_api.v1.UserPanelSubmitTestRequest"> & {
1273
+ /**
1274
+ * @generated from field: string access_token = 1;
1275
+ */
1276
+ accessToken: string;
1277
+ /**
1278
+ * @generated from field: string access_id = 2;
1279
+ */
1280
+ accessId: string;
1281
+ /**
1282
+ * @generated from field: string test_id = 3;
1283
+ */
1284
+ testId: string;
1285
+ /**
1286
+ * Unanswered questions may be omitted; they score zero.
1287
+ *
1288
+ * @generated from field: repeated public_api.v1.PanelAnswer answers = 4;
1289
+ */
1290
+ answers: PanelAnswer[];
1291
+ /**
1292
+ * Time spent on the test.
1293
+ *
1294
+ * @generated from field: int64 duration_ms = 5;
1295
+ */
1296
+ durationMs: bigint;
1297
+ };
1298
+ /**
1299
+ * Describes the message public_api.v1.UserPanelSubmitTestRequest.
1300
+ * Use `create(UserPanelSubmitTestRequestSchema)` to create a new message.
1301
+ */
1302
+ declare const UserPanelSubmitTestRequestSchema: GenMessage<UserPanelSubmitTestRequest>;
1303
+ /**
1304
+ * @generated from message public_api.v1.UserPanelSubmitTestResponse
1305
+ */
1306
+ type UserPanelSubmitTestResponse = Message<"public_api.v1.UserPanelSubmitTestResponse"> & {
1307
+ /**
1308
+ * @generated from oneof public_api.v1.UserPanelSubmitTestResponse.result
1309
+ */
1310
+ result: {
1311
+ /**
1312
+ * @generated from field: public_api.v1.UserPanelSubmitTestResponse.Result success = 1;
1313
+ */
1314
+ value: UserPanelSubmitTestResponse_Result;
1315
+ case: "success";
1316
+ } | {
1317
+ /**
1318
+ * @generated from field: public_api.v1.PanelCourseFailure failure = 2;
1319
+ */
1320
+ value: PanelCourseFailure;
1321
+ case: "failure";
1322
+ } | {
1323
+ case: undefined;
1324
+ value?: undefined;
1325
+ };
1326
+ };
1327
+ /**
1328
+ * Describes the message public_api.v1.UserPanelSubmitTestResponse.
1329
+ * Use `create(UserPanelSubmitTestResponseSchema)` to create a new message.
1330
+ */
1331
+ declare const UserPanelSubmitTestResponseSchema: GenMessage<UserPanelSubmitTestResponse>;
1332
+ /**
1333
+ * @generated from message public_api.v1.UserPanelSubmitTestResponse.Result
1334
+ */
1335
+ type UserPanelSubmitTestResponse_Result = Message<"public_api.v1.UserPanelSubmitTestResponse.Result"> & {
1336
+ /**
1337
+ * @generated from field: public_api.v1.PanelTestSubmission submission = 1;
1338
+ */
1339
+ submission?: PanelTestSubmission;
1340
+ /**
1341
+ * @generated from field: repeated public_api.v1.PanelQuestionResult results = 2;
1342
+ */
1343
+ results: PanelQuestionResult[];
1344
+ /**
1345
+ * Unset when the number of attempts is unlimited.
1346
+ *
1347
+ * @generated from field: optional int32 attempts_left = 3;
1348
+ */
1349
+ attemptsLeft?: number;
1350
+ };
1351
+ /**
1352
+ * @generated from message public_api.v1.UserPanelListTestSubmissionsRequest
1353
+ */
1354
+ type UserPanelListTestSubmissionsRequest = Message<"public_api.v1.UserPanelListTestSubmissionsRequest"> & {
1355
+ /**
1356
+ * @generated from field: string access_token = 1;
1357
+ */
1358
+ accessToken: string;
1359
+ /**
1360
+ * @generated from field: string access_id = 2;
1361
+ */
1362
+ accessId: string;
1363
+ /**
1364
+ * @generated from field: string test_id = 3;
1365
+ */
1366
+ testId: string;
1367
+ };
1368
+ /**
1369
+ * Describes the message public_api.v1.UserPanelListTestSubmissionsRequest.
1370
+ * Use `create(UserPanelListTestSubmissionsRequestSchema)` to create a new message.
1371
+ */
1372
+ declare const UserPanelListTestSubmissionsRequestSchema: GenMessage<UserPanelListTestSubmissionsRequest>;
1373
+ /**
1374
+ * @generated from message public_api.v1.UserPanelListTestSubmissionsResponse
1375
+ */
1376
+ type UserPanelListTestSubmissionsResponse = Message<"public_api.v1.UserPanelListTestSubmissionsResponse"> & {
1377
+ /**
1378
+ * @generated from oneof public_api.v1.UserPanelListTestSubmissionsResponse.result
1379
+ */
1380
+ result: {
1381
+ /**
1382
+ * @generated from field: public_api.v1.UserPanelListTestSubmissionsResponse.Result success = 1;
1383
+ */
1384
+ value: UserPanelListTestSubmissionsResponse_Result;
1385
+ case: "success";
1386
+ } | {
1387
+ /**
1388
+ * @generated from field: public_api.v1.PanelCourseFailure failure = 2;
1389
+ */
1390
+ value: PanelCourseFailure;
1391
+ case: "failure";
1392
+ } | {
1393
+ case: undefined;
1394
+ value?: undefined;
1395
+ };
1396
+ };
1397
+ /**
1398
+ * Describes the message public_api.v1.UserPanelListTestSubmissionsResponse.
1399
+ * Use `create(UserPanelListTestSubmissionsResponseSchema)` to create a new message.
1400
+ */
1401
+ declare const UserPanelListTestSubmissionsResponseSchema: GenMessage<UserPanelListTestSubmissionsResponse>;
1402
+ /**
1403
+ * @generated from message public_api.v1.UserPanelListTestSubmissionsResponse.Result
1404
+ */
1405
+ type UserPanelListTestSubmissionsResponse_Result = Message<"public_api.v1.UserPanelListTestSubmissionsResponse.Result"> & {
1406
+ /**
1407
+ * Newest first.
1408
+ *
1409
+ * @generated from field: repeated public_api.v1.PanelTestSubmission submissions = 1;
1410
+ */
1411
+ submissions: PanelTestSubmission[];
1412
+ /**
1413
+ * @generated from field: int32 best_score_percent = 2;
1414
+ */
1415
+ bestScorePercent: number;
1416
+ /**
1417
+ * @generated from field: int32 attempt_count = 3;
1418
+ */
1419
+ attemptCount: number;
1420
+ };
1421
+ /**
1422
+ * @generated from message public_api.v1.PanelQuestionAnswer
1423
+ */
1424
+ type PanelQuestionAnswer = Message<"public_api.v1.PanelQuestionAnswer"> & {
1425
+ /**
1426
+ * @generated from field: string content = 1;
1427
+ */
1428
+ content: string;
1429
+ /**
1430
+ * @generated from field: google.protobuf.Timestamp created_at = 2;
1431
+ */
1432
+ createdAt?: Timestamp;
1433
+ };
1434
+ /**
1435
+ * @generated from message public_api.v1.PanelLessonQuestion
1436
+ */
1437
+ type PanelLessonQuestion = Message<"public_api.v1.PanelLessonQuestion"> & {
1438
+ /**
1439
+ * @generated from field: string id = 1;
1440
+ */
1441
+ id: string;
1442
+ /**
1443
+ * @generated from field: string content = 2;
1444
+ */
1445
+ content: string;
1446
+ /**
1447
+ * Display name resolved by Bitsnap; empty for an anonymous customer.
1448
+ *
1449
+ * @generated from field: string author_name = 3;
1450
+ */
1451
+ authorName: string;
1452
+ /**
1453
+ * @generated from field: bool is_mine = 4;
1454
+ */
1455
+ isMine: boolean;
1456
+ /**
1457
+ * @generated from field: google.protobuf.Timestamp created_at = 5;
1458
+ */
1459
+ createdAt?: Timestamp;
1460
+ /**
1461
+ * Unset until the course team answers.
1462
+ *
1463
+ * @generated from field: optional public_api.v1.PanelQuestionAnswer answer = 6;
1464
+ */
1465
+ answer?: PanelQuestionAnswer;
1466
+ };
1467
+ /**
1468
+ * @generated from message public_api.v1.UserPanelListLessonQuestionsRequest
1469
+ */
1470
+ type UserPanelListLessonQuestionsRequest = Message<"public_api.v1.UserPanelListLessonQuestionsRequest"> & {
1471
+ /**
1472
+ * @generated from field: string access_token = 1;
1473
+ */
1474
+ accessToken: string;
1475
+ /**
1476
+ * @generated from field: string access_id = 2;
1477
+ */
1478
+ accessId: string;
1479
+ /**
1480
+ * @generated from field: string lesson_id = 3;
1481
+ */
1482
+ lessonId: string;
1483
+ };
1484
+ /**
1485
+ * Describes the message public_api.v1.UserPanelListLessonQuestionsRequest.
1486
+ * Use `create(UserPanelListLessonQuestionsRequestSchema)` to create a new message.
1487
+ */
1488
+ declare const UserPanelListLessonQuestionsRequestSchema: GenMessage<UserPanelListLessonQuestionsRequest>;
1489
+ /**
1490
+ * @generated from message public_api.v1.UserPanelListLessonQuestionsResponse
1491
+ */
1492
+ type UserPanelListLessonQuestionsResponse = Message<"public_api.v1.UserPanelListLessonQuestionsResponse"> & {
1493
+ /**
1494
+ * @generated from oneof public_api.v1.UserPanelListLessonQuestionsResponse.result
1495
+ */
1496
+ result: {
1497
+ /**
1498
+ * @generated from field: public_api.v1.UserPanelListLessonQuestionsResponse.Result success = 1;
1499
+ */
1500
+ value: UserPanelListLessonQuestionsResponse_Result;
1501
+ case: "success";
1502
+ } | {
1503
+ /**
1504
+ * @generated from field: public_api.v1.PanelCourseFailure failure = 2;
1505
+ */
1506
+ value: PanelCourseFailure;
1507
+ case: "failure";
1508
+ } | {
1509
+ case: undefined;
1510
+ value?: undefined;
1511
+ };
1512
+ };
1513
+ /**
1514
+ * Describes the message public_api.v1.UserPanelListLessonQuestionsResponse.
1515
+ * Use `create(UserPanelListLessonQuestionsResponseSchema)` to create a new message.
1516
+ */
1517
+ declare const UserPanelListLessonQuestionsResponseSchema: GenMessage<UserPanelListLessonQuestionsResponse>;
1518
+ /**
1519
+ * @generated from message public_api.v1.UserPanelListLessonQuestionsResponse.Result
1520
+ */
1521
+ type UserPanelListLessonQuestionsResponse_Result = Message<"public_api.v1.UserPanelListLessonQuestionsResponse.Result"> & {
1522
+ /**
1523
+ * Newest first.
1524
+ *
1525
+ * @generated from field: repeated public_api.v1.PanelLessonQuestion questions = 1;
1526
+ */
1527
+ questions: PanelLessonQuestion[];
1528
+ };
1529
+ /**
1530
+ * @generated from message public_api.v1.UserPanelAskLessonQuestionRequest
1531
+ */
1532
+ type UserPanelAskLessonQuestionRequest = Message<"public_api.v1.UserPanelAskLessonQuestionRequest"> & {
1533
+ /**
1534
+ * @generated from field: string access_token = 1;
1535
+ */
1536
+ accessToken: string;
1537
+ /**
1538
+ * @generated from field: string access_id = 2;
1539
+ */
1540
+ accessId: string;
1541
+ /**
1542
+ * @generated from field: string lesson_id = 3;
1543
+ */
1544
+ lessonId: string;
1545
+ /**
1546
+ * @generated from field: string content = 4;
1547
+ */
1548
+ content: string;
1549
+ };
1550
+ /**
1551
+ * Describes the message public_api.v1.UserPanelAskLessonQuestionRequest.
1552
+ * Use `create(UserPanelAskLessonQuestionRequestSchema)` to create a new message.
1553
+ */
1554
+ declare const UserPanelAskLessonQuestionRequestSchema: GenMessage<UserPanelAskLessonQuestionRequest>;
1555
+ /**
1556
+ * @generated from message public_api.v1.UserPanelAskLessonQuestionResponse
1557
+ */
1558
+ type UserPanelAskLessonQuestionResponse = Message<"public_api.v1.UserPanelAskLessonQuestionResponse"> & {
1559
+ /**
1560
+ * @generated from oneof public_api.v1.UserPanelAskLessonQuestionResponse.result
1561
+ */
1562
+ result: {
1563
+ /**
1564
+ * @generated from field: public_api.v1.PanelLessonQuestion success = 1;
1565
+ */
1566
+ value: PanelLessonQuestion;
1567
+ case: "success";
1568
+ } | {
1569
+ /**
1570
+ * @generated from field: public_api.v1.PanelCourseFailure failure = 2;
1571
+ */
1572
+ value: PanelCourseFailure;
1573
+ case: "failure";
1574
+ } | {
1575
+ case: undefined;
1576
+ value?: undefined;
1577
+ };
1578
+ };
1579
+ /**
1580
+ * Describes the message public_api.v1.UserPanelAskLessonQuestionResponse.
1581
+ * Use `create(UserPanelAskLessonQuestionResponseSchema)` to create a new message.
1582
+ */
1583
+ declare const UserPanelAskLessonQuestionResponseSchema: GenMessage<UserPanelAskLessonQuestionResponse>;
1584
+ /**
1585
+ * @generated from message public_api.v1.UserPanelRateLessonRequest
1586
+ */
1587
+ type UserPanelRateLessonRequest = Message<"public_api.v1.UserPanelRateLessonRequest"> & {
1588
+ /**
1589
+ * @generated from field: string access_token = 1;
1590
+ */
1591
+ accessToken: string;
1592
+ /**
1593
+ * @generated from field: string access_id = 2;
1594
+ */
1595
+ accessId: string;
1596
+ /**
1597
+ * @generated from field: string lesson_id = 3;
1598
+ */
1599
+ lessonId: string;
1600
+ /**
1601
+ * 1 to 5. Rating again replaces the previous rating.
1602
+ *
1603
+ * @generated from field: int32 score = 4;
1604
+ */
1605
+ score: number;
1606
+ /**
1607
+ * @generated from field: string comment = 5;
1608
+ */
1609
+ comment: string;
1610
+ };
1611
+ /**
1612
+ * Describes the message public_api.v1.UserPanelRateLessonRequest.
1613
+ * Use `create(UserPanelRateLessonRequestSchema)` to create a new message.
1614
+ */
1615
+ declare const UserPanelRateLessonRequestSchema: GenMessage<UserPanelRateLessonRequest>;
1616
+ /**
1617
+ * @generated from message public_api.v1.UserPanelRateLessonResponse
1618
+ */
1619
+ type UserPanelRateLessonResponse = Message<"public_api.v1.UserPanelRateLessonResponse"> & {
1620
+ /**
1621
+ * @generated from oneof public_api.v1.UserPanelRateLessonResponse.result
1622
+ */
1623
+ result: {
1624
+ /**
1625
+ * @generated from field: public_api.v1.UserPanelRateLessonResponse.Result success = 1;
1626
+ */
1627
+ value: UserPanelRateLessonResponse_Result;
1628
+ case: "success";
1629
+ } | {
1630
+ /**
1631
+ * @generated from field: public_api.v1.PanelCourseFailure failure = 2;
1632
+ */
1633
+ value: PanelCourseFailure;
1634
+ case: "failure";
1635
+ } | {
1636
+ case: undefined;
1637
+ value?: undefined;
1638
+ };
1639
+ };
1640
+ /**
1641
+ * Describes the message public_api.v1.UserPanelRateLessonResponse.
1642
+ * Use `create(UserPanelRateLessonResponseSchema)` to create a new message.
1643
+ */
1644
+ declare const UserPanelRateLessonResponseSchema: GenMessage<UserPanelRateLessonResponse>;
1645
+ /**
1646
+ * @generated from message public_api.v1.UserPanelRateLessonResponse.Result
1647
+ */
1648
+ type UserPanelRateLessonResponse_Result = Message<"public_api.v1.UserPanelRateLessonResponse.Result"> & {
1649
+ /**
1650
+ * @generated from field: int32 my_rating = 1;
1651
+ */
1652
+ myRating: number;
1653
+ /**
1654
+ * @generated from field: float average_rating = 2;
1655
+ */
1656
+ averageRating: number;
1657
+ /**
1658
+ * @generated from field: int32 rating_count = 3;
1659
+ */
1660
+ ratingCount: number;
1661
+ };
1662
+ /**
1663
+ * @generated from enum public_api.v1.PanelCourseFailure
1664
+ */
1665
+ declare enum PanelCourseFailure {
1666
+ /**
1667
+ * @generated from enum value: PANEL_COURSE_FAILURE_UNKNOWN = 0;
1668
+ */
1669
+ UNKNOWN = 0,
1670
+ /**
1671
+ * Missing, expired or foreign access token, or no paid access to access_id.
1672
+ *
1673
+ * @generated from enum value: PANEL_COURSE_FAILURE_UNAUTHORIZED = 1;
1674
+ */
1675
+ UNAUTHORIZED = 1,
1676
+ /**
1677
+ * @generated from enum value: PANEL_COURSE_FAILURE_COURSE_NOT_FOUND = 2;
1678
+ */
1679
+ COURSE_NOT_FOUND = 2,
1680
+ /**
1681
+ * Unknown lesson or test (or one of another course).
1682
+ *
1683
+ * @generated from enum value: PANEL_COURSE_FAILURE_ITEM_NOT_FOUND = 3;
1684
+ */
1685
+ ITEM_NOT_FOUND = 3,
1686
+ /**
1687
+ * The item is locked by a gating test (see PanelCourseItem.lock_reason).
1688
+ *
1689
+ * @generated from enum value: PANEL_COURSE_FAILURE_ITEM_LOCKED = 4;
1690
+ */
1691
+ ITEM_LOCKED = 4,
1692
+ /**
1693
+ * SubmitTest after the last allowed attempt.
1694
+ *
1695
+ * @generated from enum value: PANEL_COURSE_FAILURE_NO_ATTEMPTS_LEFT = 5;
1696
+ */
1697
+ NO_ATTEMPTS_LEFT = 5,
1698
+ /**
1699
+ * Malformed request, e.g. an answer to an unknown question, a rating out of
1700
+ * 1..5 or an empty question.
1701
+ *
1702
+ * @generated from enum value: PANEL_COURSE_FAILURE_INVALID_ARGUMENT = 6;
1703
+ */
1704
+ INVALID_ARGUMENT = 6,
1705
+ /**
1706
+ * @generated from enum value: PANEL_COURSE_FAILURE_RATE_LIMITED = 7;
1707
+ */
1708
+ RATE_LIMITED = 7,
1709
+ /**
1710
+ * LMS is not reachable. The client may retry.
1711
+ *
1712
+ * @generated from enum value: PANEL_COURSE_FAILURE_UNAVAILABLE = 8;
1713
+ */
1714
+ UNAVAILABLE = 8
1715
+ }
1716
+ /**
1717
+ * @generated from enum public_api.v1.PanelCourseType
1718
+ */
1719
+ declare enum PanelCourseType {
1720
+ /**
1721
+ * @generated from enum value: PANEL_COURSE_TYPE_UNKNOWN = 0;
1722
+ */
1723
+ UNKNOWN = 0,
1724
+ /**
1725
+ * Modules of lessons with HTML content, an optional video, attachments and
1726
+ * tests.
1727
+ *
1728
+ * @generated from enum value: PANEL_COURSE_TYPE_STANDARD = 1;
1729
+ */
1730
+ STANDARD = 1,
1731
+ /**
1732
+ * Sections of videos: a lesson is a video with a description, a thumbnail and
1733
+ * attachments.
1734
+ *
1735
+ * @generated from enum value: PANEL_COURSE_TYPE_VIDEO = 2;
1736
+ */
1737
+ VIDEO = 2
1738
+ }
1739
+ /**
1740
+ * @generated from enum public_api.v1.PanelCourseItemKind
1741
+ */
1742
+ declare enum PanelCourseItemKind {
1743
+ /**
1744
+ * @generated from enum value: PANEL_COURSE_ITEM_KIND_UNKNOWN = 0;
1745
+ */
1746
+ UNKNOWN = 0,
1747
+ /**
1748
+ * @generated from enum value: PANEL_COURSE_ITEM_KIND_LESSON = 1;
1749
+ */
1750
+ LESSON = 1,
1751
+ /**
1752
+ * @generated from enum value: PANEL_COURSE_ITEM_KIND_TEST = 2;
1753
+ */
1754
+ TEST = 2
1755
+ }
1756
+ /**
1757
+ * Course view of the customer panel (`bitsnap-react/course`).
1758
+ *
1759
+ * DRAFT. The panel talks only to Bitsnap's /api/rpc. Bitsnap checks the paid
1760
+ * access of the customer on every call, calls the internal LMS server to
1761
+ * server and returns content with URLs that are already signed:
1762
+ * - attachments: presigned S3 URLs,
1763
+ * - video: a Cloudflare Stream HLS manifest URL with a signed token.
1764
+ * The client never sees LMS ids or LMS credentials.
1765
+ *
1766
+ * Authentication follows the other UserPanel* calls (UserPanelGetCourseDetails,
1767
+ * UserPanelGetFileDetails): `access_token` is the panel session token and
1768
+ * `access_id` is UserProduct.access_id of the purchased course. The course is
1769
+ * resolved on the server from `access_id`, so there is no project_id and no
1770
+ * course_id in the requests. All other ids are opaque strings returned by
1771
+ * GetCourse.
1772
+ *
1773
+ * Every response is `oneof result { success, failure }` like the other panel
1774
+ * calls. Gateway level errors (network, 5xx) surface as Connect errors.
1775
+ *
1776
+ * @generated from service public_api.v1.UserPanelCourseService
1777
+ */
1778
+ declare const UserPanelCourseService: GenService<{
1779
+ /**
1780
+ * Course structure with the progress of the customer.
1781
+ *
1782
+ * @generated from rpc public_api.v1.UserPanelCourseService.GetCourse
1783
+ */
1784
+ getCourse: {
1785
+ methodKind: "unary";
1786
+ input: typeof UserPanelGetCourseRequestSchema;
1787
+ output: typeof UserPanelGetCourseResponseSchema;
1788
+ };
1789
+ /**
1790
+ * One lesson: content, signed video and attachment URLs.
1791
+ *
1792
+ * @generated from rpc public_api.v1.UserPanelCourseService.GetLesson
1793
+ */
1794
+ getLesson: {
1795
+ methodKind: "unary";
1796
+ input: typeof UserPanelGetLessonRequestSchema;
1797
+ output: typeof UserPanelGetLessonResponseSchema;
1798
+ };
1799
+ /**
1800
+ * Reports the playback position and/or completion of a lesson.
1801
+ *
1802
+ * @generated from rpc public_api.v1.UserPanelCourseService.SaveLessonProgress
1803
+ */
1804
+ saveLessonProgress: {
1805
+ methodKind: "unary";
1806
+ input: typeof UserPanelSaveLessonProgressRequestSchema;
1807
+ output: typeof UserPanelSaveLessonProgressResponseSchema;
1808
+ };
1809
+ /**
1810
+ * A test without the correct answers.
1811
+ *
1812
+ * @generated from rpc public_api.v1.UserPanelCourseService.GetTest
1813
+ */
1814
+ getTest: {
1815
+ methodKind: "unary";
1816
+ input: typeof UserPanelGetTestRequestSchema;
1817
+ output: typeof UserPanelGetTestResponseSchema;
1818
+ };
1819
+ /**
1820
+ * @generated from rpc public_api.v1.UserPanelCourseService.SubmitTest
1821
+ */
1822
+ submitTest: {
1823
+ methodKind: "unary";
1824
+ input: typeof UserPanelSubmitTestRequestSchema;
1825
+ output: typeof UserPanelSubmitTestResponseSchema;
1826
+ };
1827
+ /**
1828
+ * @generated from rpc public_api.v1.UserPanelCourseService.ListTestSubmissions
1829
+ */
1830
+ listTestSubmissions: {
1831
+ methodKind: "unary";
1832
+ input: typeof UserPanelListTestSubmissionsRequestSchema;
1833
+ output: typeof UserPanelListTestSubmissionsResponseSchema;
1834
+ };
1835
+ /**
1836
+ * @generated from rpc public_api.v1.UserPanelCourseService.ListLessonQuestions
1837
+ */
1838
+ listLessonQuestions: {
1839
+ methodKind: "unary";
1840
+ input: typeof UserPanelListLessonQuestionsRequestSchema;
1841
+ output: typeof UserPanelListLessonQuestionsResponseSchema;
1842
+ };
1843
+ /**
1844
+ * @generated from rpc public_api.v1.UserPanelCourseService.AskLessonQuestion
1845
+ */
1846
+ askLessonQuestion: {
1847
+ methodKind: "unary";
1848
+ input: typeof UserPanelAskLessonQuestionRequestSchema;
1849
+ output: typeof UserPanelAskLessonQuestionResponseSchema;
1850
+ };
1851
+ /**
1852
+ * @generated from rpc public_api.v1.UserPanelCourseService.RateLesson
1853
+ */
1854
+ rateLesson: {
1855
+ methodKind: "unary";
1856
+ input: typeof UserPanelRateLessonRequestSchema;
1857
+ output: typeof UserPanelRateLessonResponseSchema;
1858
+ };
1859
+ }>;
1860
+
1861
+ /** The part of the generated Connect client the data source calls. */
1862
+ type CourseRpcClient = Client<typeof UserPanelCourseService>;
1863
+ type CourseAuth = {
1864
+ /** `UserProduct.access_id` of the purchased course. */
1865
+ accessId: string;
1866
+ /** Panel session token; a function is read on every call. */
1867
+ accessToken: string | (() => string | undefined);
1868
+ };
1869
+ /**
1870
+ * Data source over `UserPanelCourseService`. Every call carries the access id
1871
+ * and the panel session token; failures become `CourseError`.
1872
+ */
1873
+ declare function createCourseDataSource(client: CourseRpcClient, auth: CourseAuth): CourseDataSource;
1874
+
1875
+ /**
1876
+ * Sanitizes the HTML of a lesson with the DOM of the browser. Returns an empty
1877
+ * string when there is no DOM, so call it on the client (inside an effect or
1878
+ * `useMemo` of a component that only renders content after loading).
1879
+ */
1880
+ declare function sanitizeLessonHtml(html: string | null | undefined): string;
1881
+
1882
+ export { COURSE_TEXT_TABLES, type Course, type CourseDataSource, CourseError, type CourseErrorCode, type CourseItem, type CourseItemKind, type CourseSection, type CourseTexts, type CourseType, type ItemRef, type Lesson, type LessonAttachment, type LessonQuestion, type LessonRating, type LessonVideo, type LockReason, PanelCourse$1 as PanelCourse, type PanelCourseProps, type ProgressSaved, type QuestionAnswer, type QuestionResult, type RpcCourseDataSourceOptions, type SaveProgressInput, type Test, type TestAnswers, type TestChoice, type TestQuestion, type TestQuestionConfig, type TestResult, type TestSubmission, type TestSubmissionList, createCourseDataSource, createRpcCourseDataSource, getCourseTexts, sanitizeLessonHtml };