@tsocial/tvweb-sdk.msb 5.8.4 → 5.9.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.
@@ -1,167 +1,440 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width, user-scalable=no" />
6
- <meta name="description" content="Vanilla JS demo" />
7
- </head>
8
- <body>
9
- <noscript>You need to enable JavaScript to run this app.</noscript>
10
- <h2>Extract ID Info & Liveness detection</h2>
11
- <div id="container"></div>
12
-
13
- <div style="margin-bottom:10px">
14
- <label>
15
- Access key
16
- <input id="access-key" style="width:500px" />
17
- </label>
18
- </div>
19
- <div style="margin-bottom:10px">
20
- <label>
21
- Secret key
22
- <input id="secret-key" style="width:500px" />
23
- </label>
24
- </div>
25
- <div style="margin-bottom:10px">
26
- <label>
27
- API URL
28
- <input id="api-url" style="width:500px" />
29
- </label>
30
- </div>
31
- <div>
32
- Api check:
33
- <select id="select-api-check">
34
- <option value="false">false</option>
35
- <option value="true">true</option>
36
- </select>
37
- </div>
38
- <hr />
39
- <h4>Extract ID Info</h4>
40
- <button onclick="startExtractIDInfo()">Start</button>
41
- <div id="result-extract-id-info"></div>
42
- <hr />
43
- <h4>Liveness detection</h4>
44
- <div style="margin-bottom:10px">
45
- Mode:
46
- <select id="select-mode"></select>
47
- </div>
48
- <button onclick="startLivenessDetection()">Liveness detection</button>
49
- <div id="result-liveness-detection"></div>
50
- <script src="../../build/tvweb-sdk.msb.standalone.min.js"></script>
51
- <script type="text/javascript">
52
- const tv = new TVWebSDK.SDK({
53
- container: document.getElementById("container"),
54
- lang: "vi",
55
- assetRoot: "https://unpkg.com/@tsocial/tvweb-sdk.msb@latest/assets",
56
- });
57
- window.tv = tv;
58
- const resultExtractIdInfoEl = document.getElementById(
59
- "result-extract-id-info"
60
- );
61
- const resultLivenessDetectionEl = document.getElementById(
62
- "result-liveness-detection"
63
- );
64
- const selectModeEl = document.getElementById("select-mode");
65
- const selectApiCheckEl = document.getElementById("select-api-check");
66
- const selectEnableRecordingEl = document.getElementById("select-enable-recording");
67
- const inputAccessKey = document.getElementById("access-key");
68
- const inputSecretKey = document.getElementById("secret-key");
69
- const inputApiUrl = document.getElementById("api-url");
70
- inputAccessKey.value = "5767c20d-87aa-4cad-8dbb-f5429f76c34b"
71
- inputSecretKey.value = "c1446919-e60a-4575-a05d-304318212a1b"
72
- inputApiUrl.value = "https://tv-testing.trustingsocial.com/api"
73
-
74
- Object.keys(TVWebSDK.Constants.Mode).forEach((k) => {
75
- const option = document.createElement("option");
76
- option.appendChild(document.createTextNode(k));
77
- option.setAttribute("value", TVWebSDK.Constants.Mode[k]);
78
- selectModeEl.appendChild(option);
79
- });
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
6
+ <meta name="description" content="Vanilla JS demo" />
7
+ <link rel="stylesheet" href="./style.css" />
8
+ </head>
9
+ <body>
10
+ <noscript>You need to enable JavaScript to run this app.</noscript>
11
+ <h2>Extract ID Info & Liveness detection</h2>
12
+ <div id="container"></div>
80
13
 
81
- Object.keys(TVWebSDK.Constants.IDCardSide).forEach((k) => {
82
- const option = document.createElement("option");
83
- option.appendChild(document.createTextNode(k));
84
- option.setAttribute("value", TVWebSDK.Constants.IDCardSide[k]);
85
- });
14
+ <div style="margin-bottom: 10px">
15
+ Language
16
+ <select id="select-lang" onchange="onSelectLang()">
17
+ <option value="vi" selected>vi</option>
18
+ <option value="en">en</option>
19
+ </select>
20
+ </div>
21
+ <div style="margin-bottom: 10px">
22
+ <label>
23
+ Keys:
24
+ <select id="select-api-key" onchange="onSelectKey()">
25
+ <option value="0" selected>Web face tracking (..a31)</option>
26
+ <option value="1">QA (..217)</option>
27
+ <option value="2">Labeller test real data (..3b2)</option>
28
+ <option value="3">Labeller test fake data (..ac4)</option>
29
+ </select>
30
+ </label>
31
+ </div>
32
+ <div style="margin-bottom: 10px">
33
+ <label>
34
+ Access key
35
+ <input id="access-key" style="width: 500px" />
36
+ </label>
37
+ </div>
38
+ <div style="margin-bottom: 10px">
39
+ <label>
40
+ Secret key
41
+ <input id="secret-key" style="width: 500px" />
42
+ </label>
43
+ </div>
44
+ <div style="margin-bottom: 10px">
45
+ <label>
46
+ API URL
47
+ <input id="api-url" style="width: 500px" />
48
+ </label>
49
+ </div>
50
+ <div>
51
+ Api check
52
+ <select id="select-api-check">
53
+ <option value="false">false</option>
54
+ <option value="true" selected>true</option>
55
+ </select>
56
+ </div>
57
+
58
+ <div style="margin-top: 10px;">
59
+ <label>
60
+ Cached User ID
61
+ <input id="user-id" readonly style="width: 300px" />
62
+ </label>
63
+ <button onclick="clearUserId()">Clear user id (x-request-id)</button>
64
+ </div>
65
+
66
+ <div style="display: inline-block; margin-top: 10px;">
67
+ <div>
68
+ Tracking config
69
+ <select id="select-tracking-config-template" onchange="onSelectTrackingConfigTemplate()">
70
+ <option value="0" selected>default</option>
71
+ <option value="1">Engineering test (...9fe5)</option>
72
+ </select>
73
+ </div>
74
+ <textarea cols="55" rows="8" id="tracking-config"></textarea>
75
+ </div>
76
+
77
+ <hr />
78
+ <h4>Extract ID Info</h4>
79
+ <div style="display: inline-block; margin-right: 20px;">
80
+ <div>Settings (notice that if <strong>Api check: true</strong>, settings from api will overwrite these settings)</div>
81
+ <textarea cols="55" rows="15" id="id-card-settings"></textarea>
82
+ </div>
83
+ <div style="display: inline-block">
84
+ <div>Steps</div>
85
+ <textarea cols="55" rows="15" id="id-card-steps"></textarea>
86
+ </div>
87
+ <div style="margin-bottom: 10px">
88
+ <button onclick="runPreloadEKYCResources()">Preload Resources</button>
89
+ </div>
90
+ <div style="margin-bottom: 10px">
91
+ <button onclick="runWarmUpReadIDCard()">Warm up</button>
92
+ <span id="status-warmup-read-id-card"></span>
93
+ </div>
94
+ <button onclick="startExtractIDInfo()">Start</button>
95
+ <pre id="result-extract-id-info"></pre>
96
+ <div id="read-id-card-loading" style="margin-top: 10px; display: none;">
97
+ Api checking
98
+ <div class="dot-windmill"></div>
99
+ </div>
100
+
101
+ <hr />
102
+
103
+ <h4>Liveness detection</h4>
104
+ <div>
105
+ Mode:
106
+ <select id="select-mode"></select>
107
+ </div>
108
+ <div>
109
+ Camera:
110
+ <select id="select-camera">
111
+ <option value="true">Front</option>
112
+ <option value="false">Back</option>
113
+ </select>
114
+ </div>
115
+ <button onclick="startLivenessDetection()" id="btn-start-liveness">
116
+ Liveness detection
117
+ </button>
118
+ <div id="liveness-loading" style="padding-top: 10px; display: none;">
119
+ Api checking
120
+ <div class="dot-windmill"></div>
121
+ </div>
122
+ <div id="result-liveness-detection"></div>
123
+ <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
124
+ <script src="https://unpkg.com/@tsocial/trustvision-sdk@2.10.1/dist/trustvision-sdk.umd.js"></script>
125
+ <script src="../../build/tvweb-sdk.msb.standalone.min.js"></script>
126
+ <script>
127
+ const keys = [
128
+ {
129
+ accessKey: "f051dfd3-8a6e-4a15-a4e8-7ea8cdc84a31",
130
+ secretKey: "vgiKCenoKvhPq79KABbFmxCBu6WX1tdw",
131
+ },
132
+ {
133
+ accessKey: "b96f7a1a-a7f1-46e8-9d7f-5f43d2d51217",
134
+ secretKey: "SYsUyQ792pLm7rnDRQFfIL6cgAecZCOp",
135
+ },
136
+ {
137
+ accessKey: "db3d055f-ba7b-4177-b7e8-110068bda3b2",
138
+ secretKey: "R1zjKNbTH3RkT2xgO2CarxAsFbcLCdsf",
139
+ },
140
+ {
141
+ accessKey: "4e24c8f3-7fe0-4824-9339-9a1216a72ac4",
142
+ secretKey: "CkoyKslrfBGv4m53LIlH0Q8yJYf4O56e",
143
+ },
144
+ ];
145
+ function onSelectKey() {
146
+ const selectedKey = document.getElementById("select-api-key").value;
147
+ const { accessKey, secretKey } = keys[selectedKey];
148
+ inputAccessKey.value = accessKey;
149
+ inputSecretKey.value = secretKey;
150
+ }
151
+ function onSelectLang() {
152
+ const langEle = document.getElementById("select-lang");
153
+ localStorage.setItem('lang', langEle?.value);
154
+ location.reload();
155
+ }
156
+ </script>
157
+ <script type="text/javascript">
158
+ const lang = localStorage.getItem('lang');
159
+ if (lang) {
160
+ const langEle = document.getElementById("select-lang");
161
+ langEle.value = lang;
162
+ }
163
+ const tv = new TVWebSDK.SDK({
164
+ container: document.getElementById("container"),
165
+ lang: lang || "vi",
166
+ assetRoot: "https://unpkg.com/tv-model-prod@1.0.7/assets",
167
+ enableAntiDebug: false,
168
+ });
169
+ window.tv = tv;
170
+ const resultExtractIdInfoEl = document.getElementById(
171
+ "result-extract-id-info"
172
+ );
173
+ const resultLivenessDetectionEl = document.getElementById(
174
+ "result-liveness-detection"
175
+ );
176
+ const selectModeEl = document.getElementById("select-mode");
177
+ const selectApiCheckEl = document.getElementById("select-api-check");
178
+ const inputAccessKey = document.getElementById("access-key");
179
+ const inputSecretKey = document.getElementById("secret-key");
180
+ const inputApiUrl = document.getElementById("api-url");
181
+ const userIdEl = document.getElementById("user-id");
182
+ const trackingConfigEl = document.getElementById("tracking-config");
183
+ const readIdCardLoadingEl = document.getElementById("read-id-card-loading");
184
+ const statusWarmupReadIDCardEl = document.getElementById("status-warmup-read-id-card");
185
+ const livenessLoadingEl = document.getElementById("liveness-loading");
186
+ const startLivenessBtn = document.getElementById("btn-start-liveness");
187
+ const idCardSettingsEl = document.getElementById("id-card-settings");
188
+ const idCardStepsEl = document.getElementById("id-card-steps");
189
+ inputAccessKey.value = "f051dfd3-8a6e-4a15-a4e8-7ea8cdc84a31";
190
+ inputSecretKey.value = "vgiKCenoKvhPq79KABbFmxCBu6WX1tdw";
191
+ inputApiUrl.value = "https://tv-testing.trustingsocial.com/api";
192
+ userIdEl.value = JSON.parse(localStorage.getItem("user-id"));
193
+
194
+ const trackingConfigTemplates = [
195
+ TVWebSDK.TrackingContext.defaultTrackingConfig,
196
+ {
197
+ "enable": true,
198
+ "accessKey": "4df5f9b9-f34d-4ffa-829f-aa4889bc9fe5",
199
+ "secretKey": "dQDfxkVYXfAxpdReqdOd1zJP4pJ088Y7",
200
+ "apiUrl": "https://tv-testing.trustingsocial.com/api",
201
+ "userId": ""
202
+ },
203
+ ];
204
+ function onSelectTrackingConfigTemplate() {
205
+ const selected = document.getElementById("select-tracking-config-template").value;
206
+ trackingConfigEl.value = JSON.stringify(trackingConfigTemplates[selected], null, 2);
207
+ }
208
+
209
+ Object.keys(TVWebSDK.Constants.Mode).forEach((k) => {
210
+ const option = document.createElement("option");
211
+ option.appendChild(document.createTextNode(k));
212
+ option.setAttribute("value", TVWebSDK.Constants.Mode[k]);
213
+ selectModeEl.appendChild(option);
214
+ });
215
+
216
+ idCardSettingsEl.value = JSON.stringify(TVWebSDK.defaultClientSettings, null, 2);
217
+ idCardStepsEl.value = JSON.stringify(TVWebSDK.defaultReadIDCardSteps, null, 2);
218
+ trackingConfigEl.value = JSON.stringify(TVWebSDK.TrackingContext.defaultTrackingConfig, null, 2);
86
219
 
87
- function startExtractIDInfo() {
88
- const apiCheck = selectApiCheckEl.value === "true";
220
+ function clearUserId() {
221
+ window.localStorage.removeItem('user-id');
222
+ userIdEl.value = JSON.parse(localStorage.getItem("user-id"));
223
+ }
89
224
 
90
- tv.readIDCard({
91
- frontCamera: false,
92
- title: "Mặt trước CMND/CCCD",
93
- titleIcon: "id_card_front.svg",
94
- description: "Căn mặt trước CMND/CCCD vào khung",
95
- onSuccess: handleOnSuccess,
96
- });
225
+ function runWarmUpReadIDCard() {
226
+ statusWarmupReadIDCardEl.innerHTML = "..."
227
+ tv.runWarmUpReadIDCard().then(function() {
228
+ statusWarmupReadIDCardEl.innerHTML = "...done"
229
+ })
230
+ }
231
+
232
+ function runPreloadEKYCResources() {
233
+ tv.runPreloadEKYCResources();
234
+ }
235
+
236
+ function handleStepDoneIDCard ({ stepNumber, image, qrScannedResult, recordedVideos, apiResult }) {
237
+ const steps = JSON.parse(idCardStepsEl.value)
238
+ console.log('image', image)
239
+
240
+ resultExtractIdInfoEl.appendChild(document.createTextNode(`\n-----------------------------------------\n`))
241
+ resultExtractIdInfoEl.appendChild(document.createTextNode(`\nSTEP NUMBER ${stepNumber}:\n`));
242
+
243
+
244
+ const imgEl = document.createElement("img");
245
+ imgEl.width = "300";
246
+ imgEl.src = URL.createObjectURL(image.blob);
247
+ resultExtractIdInfoEl.appendChild(imgEl);
248
+ resultExtractIdInfoEl.appendChild(document.createElement("br"));
249
+ resultExtractIdInfoEl.appendChild(document.createTextNode(`Recorded videos: ${recordedVideos.length}\n`));
250
+
251
+ if (qrScannedResult) {
252
+ const { result, image } = qrScannedResult
253
+
254
+ const qrImgEl = document.createElement("img");
255
+ qrImgEl.width = "200";
256
+ qrImgEl.src = URL.createObjectURL(image.blob);
257
+ resultExtractIdInfoEl.appendChild(qrImgEl);
258
+ resultExtractIdInfoEl.appendChild(document.createTextNode(`\n${result}\n`));
259
+ }
260
+
261
+ if (apiResult) {
262
+ resultExtractIdInfoEl.appendChild(document.createTextNode("API Result:\n"));
263
+ const apiResultEl = document.createElement('textarea');
264
+ apiResultEl.value = JSON.stringify(apiResult, null, 2);
265
+ apiResultEl.cols = 55
266
+ apiResultEl.rows = 15
267
+ resultExtractIdInfoEl.appendChild(apiResultEl);
268
+ }
269
+
270
+ // all steps done
271
+ if (stepNumber === steps.length - 1) {
272
+ tv.destroyView();
273
+ readIdCardLoadingEl.style.display = 'none';
274
+ }
275
+ }
276
+
277
+ async function handleDetectIdCard (props) {
278
+ const { cardType, image, cardSide } = props
279
+ const apiClient = new trustvisionSdk.default(inputAccessKey.value, inputSecretKey.value, inputApiUrl.value);
280
+ const resultUpload = await apiClient.uploadImage({
281
+ file: image.blob,
282
+ label: `id_card.${cardType}.${cardSide}`,
283
+ });
284
+ const imageId = resultUpload.data.image_id
285
+ const resultDetect = await apiClient.httpClient.post('/v1/detect_id_cards_sync', {
286
+ card_type: cardType,
287
+ image: {
288
+ id: imageId,
97
289
  }
290
+ });
291
+ return _.get(resultDetect, 'data.image.cards.0')
292
+ }
293
+
294
+ function startExtractIDInfo() {
295
+ const apiCheck = selectApiCheckEl.value === "true";
296
+ resultExtractIdInfoEl.innerHTML = "";
98
297
 
99
- function startLivenessDetection() {
100
- const livenessDetectionMode = selectModeEl.value;
101
- const apiCheck = selectApiCheckEl.value === "true";
298
+ const commonProps = {
299
+ onError: (e) => {
300
+ resultExtractIdInfoEl.appendChild(
301
+ document.createTextNode(`Error:\n${JSON.stringify(e, null, 2)}`)
302
+ );
303
+ tv.destroyView();
304
+ readIdCardLoadingEl.style.display = 'none';
305
+ },
306
+ clientSettings: JSON.parse(idCardSettingsEl.value),
307
+ detectIdCard: handleDetectIdCard,
308
+ onStepDone: handleStepDoneIDCard,
309
+ steps: JSON.parse(idCardStepsEl.value),
310
+ tracking: JSON.parse(trackingConfigEl.value),
311
+ outputEncryptionSettings: { key: 'abc123' },
312
+ }
102
313
 
103
- tv.livenessDetection({
104
- apiCheck: apiCheck,
105
- mode: livenessDetectionMode,
314
+ if (apiCheck) {
315
+ console.log('With api call')
316
+ tv.readIDCardWithApiCall({
317
+ apiCredentials: {
106
318
  accessKey: inputAccessKey.value,
107
319
  secretKey: inputSecretKey.value,
108
320
  apiUrl: inputApiUrl.value,
109
- onLivenessDetectionDone: handleLivenessDetectionDone,
110
- onError: (e) => console.error(e),
111
- });
112
- }
321
+ },
322
+ ...commonProps,
323
+ })
324
+ } else {
325
+ console.log('UI only')
326
+ tv.readIDCardUIOnly(commonProps)
327
+ }
328
+ }
113
329
 
114
- function handleOnSuccess({ image }) {
115
- const imgEl = document.createElement("img");
116
- imgEl.width = "200";
117
- imgEl.src = URL.createObjectURL(image);
118
- resultExtractIdInfoEl.appendChild(imgEl);
119
-
120
- tv.destroyView();
121
- }
330
+ function startLivenessDetection() {
331
+ const livenessDetectionMode = selectModeEl.value;
332
+ const apiCheck = selectApiCheckEl.value === "true";
333
+ const cameraSelected = document.getElementById("select-camera");
334
+
335
+ tv.livenessDetection({
336
+ apiCheck: apiCheck,
337
+ mode: livenessDetectionMode,
338
+ apiCredentials: {
339
+ accessKey: inputAccessKey.value,
340
+ secretKey: inputSecretKey.value,
341
+ apiUrl: inputApiUrl.value,
342
+ },
343
+ onLivenessDetectionDone: handleLivenessDetectionDone,
344
+ captureFrameSettings: {
345
+ enable: true,
346
+ framesIntervalTime: 180,
347
+ framesBatchLength: 15,
348
+ },
349
+ onError: (e) => {
350
+ livenessLoadingEl.style.display = "none";
351
+ startLivenessBtn.disabled = false;
352
+ resultLivenessDetectionEl.appendChild(
353
+ document.createTextNode(`${JSON.stringify(e, null, 2)}`)
354
+ );
355
+ },
356
+ frontCamera: cameraSelected.value === "true",
357
+ onProcessing: () => {
358
+ livenessLoadingEl.style.display = "block";
359
+ startLivenessBtn.disabled = true;
122
360
 
123
- function handleLivenessDetectionDone(result) {
124
- const { frontalFaces, apiCheckPassed, steps } = result;
125
- const apiCheck = selectApiCheckEl.value === "true";
126
361
  resultLivenessDetectionEl.innerHTML = "";
127
- if (apiCheck === false) {
128
- setTimeout(function () {
129
- tv.destroyView();
130
- resultLivenessDetectionEl.appendChild(
131
- document.createTextNode("Random frontal faces detected: ")
132
- );
133
- frontalFaces.forEach((blob) => {
134
- const imgEl = document.createElement("img");
135
- imgEl.width = "200";
136
- imgEl.style.marginRight = "5px";
137
- imgEl.src = URL.createObjectURL(blob);
138
- resultLivenessDetectionEl.appendChild(imgEl);
139
- });
140
- resultLivenessDetectionEl.appendChild(document.createElement("br"));
141
- resultLivenessDetectionEl.appendChild(document.createElement("br"));
142
- resultLivenessDetectionEl.appendChild(
143
- document.createTextNode("Directional faces:")
144
- );
145
- steps.forEach((s) => {
146
- const imgEl = document.createElement("img");
147
- imgEl.width = "200";
148
- imgEl.style.marginRight = "5px";
149
- imgEl.src = URL.createObjectURL(s.image.blob);
150
- resultLivenessDetectionEl.appendChild(imgEl);
151
- });
152
- resultLivenessDetectionEl.appendChild(document.createElement("br"));
153
- resultLivenessDetectionEl.appendChild(document.createElement("br"));
154
- resultLivenessDetectionEl.appendChild(
155
- document.createTextNode("Video:")
156
- );
157
- }, 500);
158
- } else {
362
+
363
+ setTimeout(() => {
159
364
  tv.destroyView();
160
- resultLivenessDetectionEl.appendChild(
161
- document.createTextNode(`apiCheckPassed: ${apiCheckPassed}`)
162
- );
163
- }
365
+ }, 250);
366
+ },
367
+ });
368
+ }
369
+
370
+ function handleReadIDCardResult({ image, recordedVideos, apiResult }) {
371
+ const apiCheck = selectApiCheckEl.value === "true";
372
+
373
+ const imgEl = document.createElement("img");
374
+ imgEl.width = "200";
375
+ imgEl.src = URL.createObjectURL(image);
376
+ resultExtractIdInfoEl.appendChild(imgEl);
377
+ resultExtractIdInfoEl.appendChild(document.createElement("br"));
378
+ resultExtractIdInfoEl.appendChild(document.createTextNode(`Recorded videos: ${recordedVideos.length}\n`));
379
+
380
+ if (apiCheck) {
381
+ resultExtractIdInfoEl.appendChild(document.createTextNode("API Result:\n"));
382
+ resultExtractIdInfoEl.appendChild(
383
+ document.createTextNode(`${JSON.stringify(apiResult, null, 2)}`)
384
+ );
385
+ if (cardSide === TVWebSDK.Constants.IDCardSide.FRONT) {
386
+ const frontCardId = apiResult.cardInfo.image1.id;
387
+ inputFrontIdEl.value = frontCardId;
164
388
  }
165
- </script>
166
- </body>
389
+ }
390
+
391
+ tv.destroyView();
392
+ readIdCardLoadingEl.style.display = 'none';
393
+ }
394
+
395
+ function handleLivenessDetectionDone(result) {
396
+ const { frontalFaces, apiCheckPassed, steps } = result;
397
+ const apiCheck = selectApiCheckEl.value === "true";
398
+ resultLivenessDetectionEl.innerHTML = "";
399
+
400
+ if (apiCheck === false) {
401
+ livenessLoadingEl.style.display = "none";
402
+ startLivenessBtn.disabled = false;
403
+ resultLivenessDetectionEl.appendChild(
404
+ document.createTextNode("Random frontal faces detected: ")
405
+ );
406
+ frontalFaces.forEach((blob) => {
407
+ const imgEl = document.createElement("img");
408
+ imgEl.width = "200";
409
+ imgEl.style.marginRight = "5px";
410
+ imgEl.src = URL.createObjectURL(blob);
411
+ resultLivenessDetectionEl.appendChild(imgEl);
412
+ });
413
+ resultLivenessDetectionEl.appendChild(document.createElement("br"));
414
+ resultLivenessDetectionEl.appendChild(document.createElement("br"));
415
+ resultLivenessDetectionEl.appendChild(
416
+ document.createTextNode("Directional faces:")
417
+ );
418
+ steps.forEach((s) => {
419
+ const imgEl = document.createElement("img");
420
+ imgEl.width = "200";
421
+ imgEl.style.marginRight = "5px";
422
+ imgEl.src = URL.createObjectURL(s.image.blob);
423
+ resultLivenessDetectionEl.appendChild(imgEl);
424
+ });
425
+ resultLivenessDetectionEl.appendChild(document.createElement("br"));
426
+ resultLivenessDetectionEl.appendChild(document.createElement("br"));
427
+ resultLivenessDetectionEl.appendChild(
428
+ document.createTextNode("Video:")
429
+ );
430
+ } else {
431
+ livenessLoadingEl.style.display = "none";
432
+ startLivenessBtn.disabled = false;
433
+ resultLivenessDetectionEl.appendChild(
434
+ document.createTextNode(`apiCheckPassed: ${apiCheckPassed}`)
435
+ );
436
+ }
437
+ }
438
+ </script>
439
+ </body>
167
440
  </html>
@@ -0,0 +1,54 @@
1
+ .dot-windmill {
2
+ position: relative;
3
+ top: -10px;
4
+ width: 10px;
5
+ height: 10px;
6
+ border-radius: 5px;
7
+ background-color: #9880ff;
8
+ color: #9880ff;
9
+ transform-origin: 5px 15px;
10
+ animation: dotWindmill 2s infinite linear;
11
+ margin-left: 100px;
12
+ margin-top: -10px;
13
+ }
14
+
15
+ .dot-windmill::before,
16
+ .dot-windmill::after {
17
+ content: "";
18
+ display: inline-block;
19
+ position: absolute;
20
+ }
21
+
22
+ .dot-windmill::before {
23
+ left: -8.66px;
24
+ top: 15px;
25
+ width: 10px;
26
+ height: 10px;
27
+ border-radius: 5px;
28
+ background-color: #9880ff;
29
+ color: #9880ff;
30
+ }
31
+
32
+ .dot-windmill::after {
33
+ left: 8.66px;
34
+ top: 15px;
35
+ width: 10px;
36
+ height: 10px;
37
+ border-radius: 5px;
38
+ background-color: #9880ff;
39
+ color: #9880ff;
40
+ }
41
+
42
+ @keyframes dotWindmill {
43
+ 0% {
44
+ transform: rotateZ(0deg) translate3d(0, 0, 0);
45
+ }
46
+ 100% {
47
+ transform: rotateZ(720deg) translate3d(0, 0, 0);
48
+ }
49
+ }
50
+
51
+ #btn-start-liveness {
52
+ margin-top: 20px;
53
+ }
54
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsocial/tvweb-sdk.msb",
3
- "version": "5.8.4",
3
+ "version": "5.9.2",
4
4
  "description": "TV Web SDK - The Standalone MSB SDK",
5
5
  "keywords": [],
6
6
  "author": "Nha Hoang <nha.hoang@trustingsocial.com>, Son T. Ng <son.nguyen.thai@trustingsocial.com>",
@@ -24,8 +24,8 @@
24
24
  },
25
25
  "dependencies": {
26
26
  "@tsocial/trustvision-sdk": "2.10.1",
27
- "@tsocial/tvweb-core": "^5.8.4",
28
- "@tsocial/tvweb-ui": "^5.8.4",
27
+ "@tsocial/tvweb-core": "^5.9.2",
28
+ "@tsocial/tvweb-ui": "^5.9.2",
29
29
  "invariant": "^2.2.4",
30
30
  "react": "^16.14.0",
31
31
  "react-app-polyfill": "^2.0.0",
@@ -33,7 +33,7 @@
33
33
  "styled-components": "^5.2.1"
34
34
  },
35
35
  "devDependencies": {
36
- "@tsocial/tvweb-builder": "^5.8.4"
36
+ "@tsocial/tvweb-builder": "^5.9.2"
37
37
  },
38
- "gitHead": "d330d6c589e78189a304fba43bf4f4d3d1aa27a9"
38
+ "gitHead": "942f9f1cedd7e384766e99e37c7d7d4217f1f641"
39
39
  }