facecog-liveness-showcase 0.0.1

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 (229) hide show
  1. package/.browserslistrc +15 -0
  2. package/.dockerignore +48 -0
  3. package/.editorconfig +16 -0
  4. package/.eslintrc.json +47 -0
  5. package/.vercelignore +7 -0
  6. package/.vscode/extensions.json +5 -0
  7. package/.vscode/settings.json +3 -0
  8. package/DOCKER.md +221 -0
  9. package/Dockerfile +33 -0
  10. package/README.md +268 -0
  11. package/angular.json +156 -0
  12. package/capacitor.config.ts +9 -0
  13. package/docker-compose.dev.yml +20 -0
  14. package/docker-compose.yml +18 -0
  15. package/ionic.config.json +7 -0
  16. package/jest.config.js +38 -0
  17. package/nginx.conf +50 -0
  18. package/package.json +131 -0
  19. package/patches/ng-packagr+20.3.2.patch +60 -0
  20. package/projects/facecog-liveness-verification/README.md +295 -0
  21. package/projects/facecog-liveness-verification/ng-package.json +7 -0
  22. package/projects/facecog-liveness-verification/package.json +48 -0
  23. package/projects/facecog-liveness-verification/scripts/build-with-wrapper-copy.js +38 -0
  24. package/projects/facecog-liveness-verification/scripts/copy-wrapper-after-ngc.js +35 -0
  25. package/projects/facecog-liveness-verification/sources/FaceLivenessReactWrapper.tsx +320 -0
  26. package/projects/facecog-liveness-verification/src/lib/components/aws-face-liveness/FaceLivenessReactWrapper.generated.d.ts +28 -0
  27. package/projects/facecog-liveness-verification/src/lib/components/aws-face-liveness/FaceLivenessReactWrapper.generated.js +247 -0
  28. package/projects/facecog-liveness-verification/src/lib/components/aws-face-liveness/FaceLivenessReactWrapper.generated.js.map +1 -0
  29. package/projects/facecog-liveness-verification/src/lib/components/aws-face-liveness/FaceLivenessReactWrapper.js.map +1 -0
  30. package/projects/facecog-liveness-verification/src/lib/components/aws-face-liveness/FaceLivenessReactWrapper.ts +5 -0
  31. package/projects/facecog-liveness-verification/src/lib/components/aws-face-liveness/aws-face-liveness.component.ts +500 -0
  32. package/projects/facecog-liveness-verification/src/lib/components/camera-permission/camera-permission.component.html +41 -0
  33. package/projects/facecog-liveness-verification/src/lib/components/camera-permission/camera-permission.component.scss +234 -0
  34. package/projects/facecog-liveness-verification/src/lib/components/camera-permission/camera-permission.component.spec.ts +158 -0
  35. package/projects/facecog-liveness-verification/src/lib/components/camera-permission/camera-permission.component.ts +58 -0
  36. package/projects/facecog-liveness-verification/src/lib/components/camera-verification/camera-verification.component.html +34 -0
  37. package/projects/facecog-liveness-verification/src/lib/components/camera-verification/camera-verification.component.ts +210 -0
  38. package/projects/facecog-liveness-verification/src/lib/components/dialogs/save-custom-pose-dialog.component.ts +174 -0
  39. package/projects/facecog-liveness-verification/src/lib/components/facetec-scan/facetec-scan.component.html +45 -0
  40. package/projects/facecog-liveness-verification/src/lib/components/facetec-scan/facetec-scan.component.scss +87 -0
  41. package/projects/facecog-liveness-verification/src/lib/components/facetec-scan/facetec-scan.component.ts +182 -0
  42. package/projects/facecog-liveness-verification/src/lib/components/intro/intro.component.html +394 -0
  43. package/projects/facecog-liveness-verification/src/lib/components/intro/intro.component.scss +1567 -0
  44. package/projects/facecog-liveness-verification/src/lib/components/intro/intro.component.spec.ts +699 -0
  45. package/projects/facecog-liveness-verification/src/lib/components/intro/intro.component.ts +721 -0
  46. package/projects/facecog-liveness-verification/src/lib/components/live-preview/live-preview.component.html +120 -0
  47. package/projects/facecog-liveness-verification/src/lib/components/live-preview/live-preview.component.scss +611 -0
  48. package/projects/facecog-liveness-verification/src/lib/components/live-preview/live-preview.component.spec.ts +605 -0
  49. package/projects/facecog-liveness-verification/src/lib/components/live-preview/live-preview.component.ts +524 -0
  50. package/projects/facecog-liveness-verification/src/lib/components/liveness-flow/liveness-flow.component.html +73 -0
  51. package/projects/facecog-liveness-verification/src/lib/components/liveness-flow/liveness-flow.component.scss +19 -0
  52. package/projects/facecog-liveness-verification/src/lib/components/liveness-flow/liveness-flow.component.spec.ts +673 -0
  53. package/projects/facecog-liveness-verification/src/lib/components/liveness-flow/liveness-flow.component.ts +963 -0
  54. package/projects/facecog-liveness-verification/src/lib/components/liveness-verification/liveness-verification.component.html +38 -0
  55. package/projects/facecog-liveness-verification/src/lib/components/liveness-verification/liveness-verification.component.scss +10 -0
  56. package/projects/facecog-liveness-verification/src/lib/components/liveness-verification/liveness-verification.component.ts +233 -0
  57. package/projects/facecog-liveness-verification/src/lib/components/pose-selection/pose-selection.component.html +17 -0
  58. package/projects/facecog-liveness-verification/src/lib/components/pose-selection/pose-selection.component.spec.ts +35 -0
  59. package/projects/facecog-liveness-verification/src/lib/components/pose-selection/pose-selection.component.ts +33 -0
  60. package/projects/facecog-liveness-verification/src/lib/components/processing/processing.component.html +17 -0
  61. package/projects/facecog-liveness-verification/src/lib/components/processing/processing.component.scss +156 -0
  62. package/projects/facecog-liveness-verification/src/lib/components/processing/processing.component.spec.ts +46 -0
  63. package/projects/facecog-liveness-verification/src/lib/components/processing/processing.component.ts +18 -0
  64. package/projects/facecog-liveness-verification/src/lib/components/verification-result/verification-result.component.html +190 -0
  65. package/projects/facecog-liveness-verification/src/lib/components/verification-result/verification-result.component.scss +534 -0
  66. package/projects/facecog-liveness-verification/src/lib/components/verification-result/verification-result.component.spec.ts +286 -0
  67. package/projects/facecog-liveness-verification/src/lib/components/verification-result/verification-result.component.ts +155 -0
  68. package/projects/facecog-liveness-verification/src/lib/interfaces/analyze-response.interface.ts +16 -0
  69. package/projects/facecog-liveness-verification/src/lib/interfaces/aws-face-liveness.interface.ts +46 -0
  70. package/projects/facecog-liveness-verification/src/lib/interfaces/backend-adapter.interface.ts +21 -0
  71. package/projects/facecog-liveness-verification/src/lib/interfaces/backend-http-client.interface.ts +93 -0
  72. package/projects/facecog-liveness-verification/src/lib/interfaces/backend-response.interface.ts +9 -0
  73. package/projects/facecog-liveness-verification/src/lib/interfaces/camera-provider.interface.ts +107 -0
  74. package/projects/facecog-liveness-verification/src/lib/interfaces/category-info.interface.ts +9 -0
  75. package/projects/facecog-liveness-verification/src/lib/interfaces/custom-pose-data.interface.ts +14 -0
  76. package/projects/facecog-liveness-verification/src/lib/interfaces/custom-pose-repository.interface.ts +48 -0
  77. package/projects/facecog-liveness-verification/src/lib/interfaces/custom-pose-response.interface.ts +14 -0
  78. package/projects/facecog-liveness-verification/src/lib/interfaces/index.ts +52 -0
  79. package/projects/facecog-liveness-verification/src/lib/interfaces/liveness-action-result.interface.ts +13 -0
  80. package/projects/facecog-liveness-verification/src/lib/interfaces/liveness-config.interface.ts +17 -0
  81. package/projects/facecog-liveness-verification/src/lib/interfaces/liveness-metadata.interface.ts +17 -0
  82. package/projects/facecog-liveness-verification/src/lib/interfaces/liveness-result.interface.ts +24 -0
  83. package/projects/facecog-liveness-verification/src/lib/interfaces/liveness-verification-config.interface.ts +41 -0
  84. package/projects/facecog-liveness-verification/src/lib/interfaces/multi-backend-analyze-response.interface.ts +21 -0
  85. package/projects/facecog-liveness-verification/src/lib/interfaces/multi-backend-liveness-result.interface.ts +14 -0
  86. package/projects/facecog-liveness-verification/src/lib/interfaces/pose-definition.interface.ts +35 -0
  87. package/projects/facecog-liveness-verification/src/lib/interfaces/pose-keypoint.interface.ts +12 -0
  88. package/projects/facecog-liveness-verification/src/lib/interfaces/pose-match-result.interface.ts +9 -0
  89. package/projects/facecog-liveness-verification/src/lib/interfaces/pose-verify-response.interface.ts +8 -0
  90. package/projects/facecog-liveness-verification/src/lib/interfaces/scan-results.interface.ts +29 -0
  91. package/projects/facecog-liveness-verification/src/lib/interfaces/verification-plan.interface.ts +42 -0
  92. package/projects/facecog-liveness-verification/src/lib/interfaces/verification-progress-event.interface.ts +12 -0
  93. package/projects/facecog-liveness-verification/src/lib/interfaces/verification-session.interface.ts +72 -0
  94. package/projects/facecog-liveness-verification/src/lib/interfaces/verification-step-change-event.interface.ts +11 -0
  95. package/projects/facecog-liveness-verification/src/lib/interfaces/video-recording.interface.ts +9 -0
  96. package/projects/facecog-liveness-verification/src/lib/liveness-verification.module.ts +123 -0
  97. package/projects/facecog-liveness-verification/src/lib/models/constants/aws-face-liveness-component.token.ts +23 -0
  98. package/projects/facecog-liveness-verification/src/lib/models/constants/category-info.constant.ts +14 -0
  99. package/projects/facecog-liveness-verification/src/lib/models/constants/default-liveness-config.constant.ts +18 -0
  100. package/projects/facecog-liveness-verification/src/lib/models/constants/index.ts +5 -0
  101. package/projects/facecog-liveness-verification/src/lib/models/constants/liveness-verification-config.token.ts +16 -0
  102. package/projects/facecog-liveness-verification/src/lib/models/constants/pose-definitions.constant.ts +377 -0
  103. package/projects/facecog-liveness-verification/src/lib/models/index.ts +5 -0
  104. package/projects/facecog-liveness-verification/src/lib/models/utils/index.ts +2 -0
  105. package/projects/facecog-liveness-verification/src/lib/models/utils/pose.utils.spec.ts +76 -0
  106. package/projects/facecog-liveness-verification/src/lib/models/utils/pose.utils.ts +59 -0
  107. package/projects/facecog-liveness-verification/src/lib/services/aws-face-liveness.service.ts +49 -0
  108. package/projects/facecog-liveness-verification/src/lib/services/backend-http.service.spec.ts +111 -0
  109. package/projects/facecog-liveness-verification/src/lib/services/backend-http.service.ts +130 -0
  110. package/projects/facecog-liveness-verification/src/lib/services/backends/azure-backend.service.spec.ts +69 -0
  111. package/projects/facecog-liveness-verification/src/lib/services/backends/azure-backend.service.ts +72 -0
  112. package/projects/facecog-liveness-verification/src/lib/services/backends/facetec-backend.service.spec.ts +24 -0
  113. package/projects/facecog-liveness-verification/src/lib/services/backends/facetec-backend.service.ts +35 -0
  114. package/projects/facecog-liveness-verification/src/lib/services/backends/mock-backend.service.spec.ts +36 -0
  115. package/projects/facecog-liveness-verification/src/lib/services/backends/mock-backend.service.ts +39 -0
  116. package/projects/facecog-liveness-verification/src/lib/services/backends/openpose-backend.service.spec.ts +81 -0
  117. package/projects/facecog-liveness-verification/src/lib/services/backends/openpose-backend.service.ts +72 -0
  118. package/projects/facecog-liveness-verification/src/lib/services/backends/rekognition-analysis-backend.service.spec.ts +69 -0
  119. package/projects/facecog-liveness-verification/src/lib/services/backends/rekognition-analysis-backend.service.ts +83 -0
  120. package/projects/facecog-liveness-verification/src/lib/services/camera.service.spec.ts +200 -0
  121. package/projects/facecog-liveness-verification/src/lib/services/camera.service.ts +155 -0
  122. package/projects/facecog-liveness-verification/src/lib/services/custom-poses-api.service.ts +117 -0
  123. package/projects/facecog-liveness-verification/src/lib/services/index.ts +18 -0
  124. package/projects/facecog-liveness-verification/src/lib/services/liveness-backend.service.spec.ts +103 -0
  125. package/projects/facecog-liveness-verification/src/lib/services/liveness-backend.service.ts +61 -0
  126. package/projects/facecog-liveness-verification/src/lib/services/liveness-config.service.spec.ts +109 -0
  127. package/projects/facecog-liveness-verification/src/lib/services/liveness-config.service.ts +70 -0
  128. package/projects/facecog-liveness-verification/src/lib/services/liveness-orchestrator.service.spec.ts +144 -0
  129. package/projects/facecog-liveness-verification/src/lib/services/liveness-orchestrator.service.ts +162 -0
  130. package/projects/facecog-liveness-verification/src/lib/services/pose-detection/hand-gesture-detection.service.ts +315 -0
  131. package/projects/facecog-liveness-verification/src/lib/services/pose-detection/index.ts +5 -0
  132. package/projects/facecog-liveness-verification/src/lib/services/pose-detection/openpose.service.ts +287 -0
  133. package/projects/facecog-liveness-verification/src/lib/services/pose-detection/pose-comparison.service.ts +353 -0
  134. package/projects/facecog-liveness-verification/src/lib/services/pose-detection/pose-matching.service.ts +2370 -0
  135. package/projects/facecog-liveness-verification/src/lib/services/pose-detection/reference-pose.service.ts +271 -0
  136. package/projects/facecog-liveness-verification/src/lib/services/pose-selection.service.spec.ts +183 -0
  137. package/projects/facecog-liveness-verification/src/lib/services/pose-selection.service.ts +179 -0
  138. package/projects/facecog-liveness-verification/src/lib/services/verification-api.service.spec.ts +159 -0
  139. package/projects/facecog-liveness-verification/src/lib/services/verification-api.service.ts +151 -0
  140. package/projects/facecog-liveness-verification/src/lib/services/verification-plan.service.spec.ts +184 -0
  141. package/projects/facecog-liveness-verification/src/lib/services/verification-plan.service.ts +94 -0
  142. package/projects/facecog-liveness-verification/src/lib/services/video-recorder.service.spec.ts +52 -0
  143. package/projects/facecog-liveness-verification/src/lib/services/video-recorder.service.ts +117 -0
  144. package/projects/facecog-liveness-verification/src/lib/types/detection-strategy.type.ts +5 -0
  145. package/projects/facecog-liveness-verification/src/lib/types/index.ts +7 -0
  146. package/projects/facecog-liveness-verification/src/lib/types/liveness-action.type.ts +31 -0
  147. package/projects/facecog-liveness-verification/src/lib/types/liveness-backend.type.ts +5 -0
  148. package/projects/facecog-liveness-verification/src/lib/types/pose-category.type.ts +5 -0
  149. package/projects/facecog-liveness-verification/src/lib/types/pose-difficulty.type.ts +5 -0
  150. package/projects/facecog-liveness-verification/src/lib/types/verification-flow-step.type.ts +5 -0
  151. package/projects/facecog-liveness-verification/src/lib/types/verification-step-kind.type.ts +4 -0
  152. package/projects/facecog-liveness-verification/src/public-api.ts +150 -0
  153. package/projects/facecog-liveness-verification/tsconfig.lib.json +20 -0
  154. package/projects/facecog-liveness-verification/tsconfig.lib.prod.json +11 -0
  155. package/projects/facecog-liveness-verification/tsconfig.spec.json +13 -0
  156. package/projects/facecog-liveness-verification/tsconfig.wrapper.json +15 -0
  157. package/projects/facecog-liveness-verification-test/src/app/app-routing.module.ts +22 -0
  158. package/projects/facecog-liveness-verification-test/src/app/app.component.html +3 -0
  159. package/projects/facecog-liveness-verification-test/src/app/app.component.scss +0 -0
  160. package/projects/facecog-liveness-verification-test/src/app/app.component.ts +11 -0
  161. package/projects/facecog-liveness-verification-test/src/app/app.module.ts +27 -0
  162. package/projects/facecog-liveness-verification-test/src/app/home/home-routing.module.ts +16 -0
  163. package/projects/facecog-liveness-verification-test/src/app/home/home.module.ts +19 -0
  164. package/projects/facecog-liveness-verification-test/src/app/home/home.page.html +39 -0
  165. package/projects/facecog-liveness-verification-test/src/app/home/home.page.scss +97 -0
  166. package/projects/facecog-liveness-verification-test/src/app/home/home.page.spec.ts +24 -0
  167. package/projects/facecog-liveness-verification-test/src/app/home/home.page.ts +92 -0
  168. package/projects/facecog-liveness-verification-test/src/app/home/verification-modal.component.ts +106 -0
  169. package/projects/facecog-liveness-verification-test/src/assets/fonts/gilroy/Gilroy-Bold_0.ttf +0 -0
  170. package/projects/facecog-liveness-verification-test/src/assets/fonts/gilroy/Gilroy-Medium_0.ttf +0 -0
  171. package/projects/facecog-liveness-verification-test/src/assets/fonts/gilroy/Gilroy-Regular_0.ttf +0 -0
  172. package/projects/facecog-liveness-verification-test/src/assets/fonts/gilroy/Gilroy-SemiBold_0.ttf +0 -0
  173. package/projects/facecog-liveness-verification-test/src/assets/fonts/gilroy/Gilroy-Thin_0.ttf +0 -0
  174. package/projects/facecog-liveness-verification-test/src/assets/icon/favicon.png +0 -0
  175. package/projects/facecog-liveness-verification-test/src/assets/images/poses/Five_Fingers_Left.jpg +0 -0
  176. package/projects/facecog-liveness-verification-test/src/assets/images/poses/Left_Palm.jpg +0 -0
  177. package/projects/facecog-liveness-verification-test/src/assets/images/poses/Ok_Sign_Right.jpg +0 -0
  178. package/projects/facecog-liveness-verification-test/src/assets/images/poses/Peace_Sign_Left.jpg +0 -0
  179. package/projects/facecog-liveness-verification-test/src/assets/images/poses/README.md +77 -0
  180. package/projects/facecog-liveness-verification-test/src/assets/images/poses/Right_Palm.jpg +0 -0
  181. package/projects/facecog-liveness-verification-test/src/assets/images/poses/Speak_Phrase.jpg +0 -0
  182. package/projects/facecog-liveness-verification-test/src/assets/images/poses/Three_Fingers_Right.jpg +0 -0
  183. package/projects/facecog-liveness-verification-test/src/assets/images/poses/Thumbs_Up_Left.jpg +0 -0
  184. package/projects/facecog-liveness-verification-test/src/assets/images/poses/Thumbs_Up_Right.jpg +0 -0
  185. package/projects/facecog-liveness-verification-test/src/assets/images/poses/Wave_Right.jpg +0 -0
  186. package/projects/facecog-liveness-verification-test/src/assets/images/poses/blink.jpeg +0 -0
  187. package/projects/facecog-liveness-verification-test/src/assets/images/poses/blink_twice.jpeg +0 -0
  188. package/projects/facecog-liveness-verification-test/src/assets/images/poses/center_face.png +0 -0
  189. package/projects/facecog-liveness-verification-test/src/assets/images/poses/clap.jpeg +0 -0
  190. package/projects/facecog-liveness-verification-test/src/assets/images/poses/cover_mouth.png +0 -0
  191. package/projects/facecog-liveness-verification-test/src/assets/images/poses/cover_right_eye.png +0 -0
  192. package/projects/facecog-liveness-verification-test/src/assets/images/poses/cross_arms.png +0 -0
  193. package/projects/facecog-liveness-verification-test/src/assets/images/poses/face_straight.png +0 -0
  194. package/projects/facecog-liveness-verification-test/src/assets/images/poses/follow_dot.png +0 -0
  195. package/projects/facecog-liveness-verification-test/src/assets/images/poses/look_down.png +0 -0
  196. package/projects/facecog-liveness-verification-test/src/assets/images/poses/look_up.png +0 -0
  197. package/projects/facecog-liveness-verification-test/src/assets/images/poses/move_closer.png +0 -0
  198. package/projects/facecog-liveness-verification-test/src/assets/images/poses/nod.png +0 -0
  199. package/projects/facecog-liveness-verification-test/src/assets/images/poses/open_mouth.png +0 -0
  200. package/projects/facecog-liveness-verification-test/src/assets/images/poses/raise_eyebrow.png +0 -0
  201. package/projects/facecog-liveness-verification-test/src/assets/images/poses/rotate_face.jpeg +0 -0
  202. package/projects/facecog-liveness-verification-test/src/assets/images/poses/shake_head.jpeg +0 -0
  203. package/projects/facecog-liveness-verification-test/src/assets/images/poses/smile.png +0 -0
  204. package/projects/facecog-liveness-verification-test/src/assets/images/poses/tilt_left.png +0 -0
  205. package/projects/facecog-liveness-verification-test/src/assets/images/poses/tilt_right.png +0 -0
  206. package/projects/facecog-liveness-verification-test/src/assets/images/poses/touch_chin_left.jpg +0 -0
  207. package/projects/facecog-liveness-verification-test/src/assets/images/poses/touch_left_cheek.jpeg +0 -0
  208. package/projects/facecog-liveness-verification-test/src/assets/images/poses/touch_nose_right.png +0 -0
  209. package/projects/facecog-liveness-verification-test/src/assets/images/poses/touch_right_cheek.jpeg +0 -0
  210. package/projects/facecog-liveness-verification-test/src/assets/images/poses/turn_left.png +0 -0
  211. package/projects/facecog-liveness-verification-test/src/assets/images/poses/turn_right.png +0 -0
  212. package/projects/facecog-liveness-verification-test/src/assets/images/poses/wink.jpeg +0 -0
  213. package/projects/facecog-liveness-verification-test/src/assets/images/reference-pose.jpg +0 -0
  214. package/projects/facecog-liveness-verification-test/src/assets/shapes.svg +1 -0
  215. package/projects/facecog-liveness-verification-test/src/environments/environment.prod.ts +4 -0
  216. package/projects/facecog-liveness-verification-test/src/environments/environment.ts +17 -0
  217. package/projects/facecog-liveness-verification-test/src/global.scss +288 -0
  218. package/projects/facecog-liveness-verification-test/src/index.html +31 -0
  219. package/projects/facecog-liveness-verification-test/src/main.ts +6 -0
  220. package/projects/facecog-liveness-verification-test/src/polyfills.ts +55 -0
  221. package/projects/facecog-liveness-verification-test/src/theme/nextsapien-theme.scss +174 -0
  222. package/projects/facecog-liveness-verification-test/src/theme/variables.scss +2 -0
  223. package/projects/facecog-liveness-verification-test/src/zone-flags.ts +6 -0
  224. package/projects/facecog-liveness-verification-test/tsconfig.app.json +15 -0
  225. package/projects/facecog-liveness-verification-test/tsconfig.spec.json +14 -0
  226. package/setup-jest.ts +118 -0
  227. package/tsconfig.json +41 -0
  228. package/tsconfig.spec.json +15 -0
  229. package/vercel.json +24 -0
@@ -0,0 +1,394 @@
1
+ <div class="intro-scroll-wrapper">
2
+ <div class="intro-container">
3
+ <div class="content-wrapper">
4
+ <div class="icon-container">
5
+ <ion-icon name="shield-checkmark" class="shield-icon" color="primary"></ion-icon>
6
+ </div>
7
+
8
+ <ion-text class="instruction-text">
9
+ <h2>Pose Verification</h2>
10
+ <p>Select a pose below and perform it when prompted to verify your identity.</p>
11
+ <p class="tip">Ensure you are in a well-lit area for best results.</p>
12
+ </ion-text>
13
+
14
+ <!-- Backend Selection Section (hidden in pose-specific flow) -->
15
+ <div class="backend-selection-section" *ngIf="!poseSpecificMode">
16
+ <div class="backend-header" (click)="toggleBackendSettings()">
17
+ <ion-icon [name]="showBackendSettings ? 'chevron-down' : 'chevron-forward'"></ion-icon>
18
+ <span>Verification Backends ({{ getSelectedBackendCount() }} selected)</span>
19
+ <ion-icon name="settings-outline" class="settings-icon"></ion-icon>
20
+ </div>
21
+
22
+ <div class="backend-options" *ngIf="showBackendSettings">
23
+ <p class="backend-description">Select which backend services to use for liveness verification:</p>
24
+ <div class="backend-checkboxes">
25
+ <ion-item *ngFor="let backend of backendOptions" lines="none" class="backend-item">
26
+ <ion-checkbox
27
+ slot="start"
28
+ [(ngModel)]="selectedBackends[backend.id]"
29
+ (ionChange)="onBackendChange()">
30
+ </ion-checkbox>
31
+ <ion-label>
32
+ <h3>{{ backend.name }}</h3>
33
+ <p>{{ backend.description }}</p>
34
+ </ion-label>
35
+ </ion-item>
36
+ </div>
37
+ <p class="backend-note" *ngIf="getSelectedBackendCount() > 1">
38
+ <ion-icon name="information-circle-outline"></ion-icon>
39
+ Multiple backends use voting consensus for more accurate results.
40
+ </p>
41
+ <p class="backend-note" *ngIf="getSelectedBackendCount() === 1">
42
+ <ion-icon name="information-circle-outline"></ion-icon>
43
+ Single backend mode - results from {{ getSelectedBackendName() }} only.
44
+ </p>
45
+
46
+ <!-- AWS Face Liveness Anti-Spoofing Section -->
47
+ <div class="aws-liveness-section">
48
+ <div class="section-divider"></div>
49
+ <h4 class="aws-liveness-title">
50
+ <ion-icon name="shield-checkmark"></ion-icon>
51
+ Anti-Spoofing Protection
52
+ </h4>
53
+
54
+ <ion-item lines="none" class="aws-liveness-item">
55
+ <ion-toggle
56
+ [(ngModel)]="useAwsFaceLiveness"
57
+ (ionChange)="onAwsFaceLivenessChange()">
58
+ </ion-toggle>
59
+ <ion-label>
60
+ <h3>AWS Face Liveness</h3>
61
+ <p>Real-time anti-spoofing with oval UI challenge</p>
62
+ </ion-label>
63
+ </ion-item>
64
+
65
+ <div class="liveness-explanation">
66
+ <div class="explanation-card" [class.inactive]="useAwsFaceLiveness">
67
+ <div class="card-header">
68
+ <ion-icon name="camera-outline"></ion-icon>
69
+ <span>Standard Mode (Current)</span>
70
+ </div>
71
+ <p>Uses <strong>DetectFaces API</strong> for image quality analysis. Checks face visibility, lighting, blur, and pose but does <strong>not detect spoofing attacks</strong> (photos, videos, masks).</p>
72
+ </div>
73
+
74
+ <div class="explanation-card recommended" [class.active]="useAwsFaceLiveness">
75
+ <div class="card-header">
76
+ <ion-icon name="shield-checkmark"></ion-icon>
77
+ <span>AWS Face Liveness</span>
78
+ <ion-badge color="success">Recommended</ion-badge>
79
+ </div>
80
+ <p>Uses <strong>Face Liveness API</strong> with an oval UI challenge-response flow. Detects and prevents <strong>spoofing attacks</strong> from photos, videos, and 3D masks in real-time.</p>
81
+ <div class="features">
82
+ <span><ion-icon name="checkmark-circle"></ion-icon> Photo attack prevention</span>
83
+ <span><ion-icon name="checkmark-circle"></ion-icon> Video replay detection</span>
84
+ <span><ion-icon name="checkmark-circle"></ion-icon> 3D mask detection</span>
85
+ </div>
86
+ </div>
87
+ </div>
88
+
89
+ <p class="aws-note" *ngIf="useAwsFaceLiveness && !isSafariBrowser">
90
+ <ion-icon name="information-circle"></ion-icon>
91
+ An oval guide will appear on screen. Follow the prompts to complete the liveness check.
92
+ </p>
93
+
94
+ <!-- Safari Browser Warning -->
95
+ <div class="browser-warning" *ngIf="useAwsFaceLiveness && isSafariBrowser">
96
+ <ion-icon name="warning"></ion-icon>
97
+ <div class="warning-content">
98
+ <strong>Safari Not Supported</strong>
99
+ <p>AWS Face Liveness requires Chrome or Edge browser. Please switch browsers for anti-spoofing protection.</p>
100
+ </div>
101
+ </div>
102
+ </div>
103
+ </div>
104
+ </div>
105
+
106
+ <!-- Pose Selection Section (hide headings in pose-specific flow) -->
107
+ <div class="pose-selection-section">
108
+ <h3 *ngIf="!poseSpecificMode">Select Your Challenge Pose</h3>
109
+ <p class="section-description" *ngIf="!poseSpecificMode">Choose a pose you'll need to match during verification</p>
110
+
111
+ <!-- Mode Toggle: Browse Poses vs Upload Custom Pose (hidden in pose-specific flow) -->
112
+ <div class="mode-toggle-container" *ngIf="!poseSpecificMode && !selectedPose && !referencePoseImage">
113
+ <ion-segment [(ngModel)]="poseSelectionMode" (ionChange)="onModeChange($event)">
114
+ <ion-segment-button value="browse">
115
+ <ion-icon name="grid-outline"></ion-icon>
116
+ <ion-label>Browse Poses</ion-label>
117
+ </ion-segment-button>
118
+ <ion-segment-button value="upload">
119
+ <ion-icon name="cloud-upload-outline"></ion-icon>
120
+ <ion-label>Upload Custom Pose</ion-label>
121
+ </ion-segment-button>
122
+ </ion-segment>
123
+ </div>
124
+
125
+ <!-- Selected Pose Display (Pre-defined) -->
126
+ <div class="selected-pose-display" *ngIf="selectedPose">
127
+ <div class="selected-badge">
128
+ <ion-icon name="checkmark-circle" color="success"></ion-icon>
129
+ <span>Selected:</span>
130
+ </div>
131
+ <div class="selected-pose-card">
132
+ <div class="pose-image-container">
133
+ <img [src]="selectedPose.imageUrl" [alt]="selectedPose.pose.name" (error)="onImageError($event)">
134
+ <ion-icon [name]="getCategoryIcon(selectedPose.pose.category)" class="fallback-icon" [color]="getCategoryColor(selectedPose.pose.category)"></ion-icon>
135
+ </div>
136
+ <div class="pose-details">
137
+ <h4>{{ selectedPose.pose.name }}</h4>
138
+ <p>{{ selectedPose.pose.description }}</p>
139
+ <div class="pose-badges">
140
+ <ion-badge [color]="getCategoryColor(selectedPose.pose.category)">
141
+ {{ selectedPose.pose.category }}
142
+ </ion-badge>
143
+ <ion-badge [color]="getDifficultyColor(selectedPose.pose.difficulty)">
144
+ {{ selectedPose.pose.difficulty }}
145
+ </ion-badge>
146
+ </div>
147
+ </div>
148
+ </div>
149
+ <button class="change-pose-link" *ngIf="!poseSpecificMode" (click)="clearPoseSelection()">
150
+ Change Pose
151
+ </button>
152
+ </div>
153
+
154
+ <!-- Uploaded Custom Pose Display -->
155
+ <div class="uploaded-pose-display" *ngIf="referencePoseImage">
156
+ <div class="selected-badge">
157
+ <ion-icon name="checkmark-circle" color="success"></ion-icon>
158
+ <span>Custom Pose Uploaded:</span>
159
+ </div>
160
+ <div class="uploaded-pose-card">
161
+ <div class="pose-image-container">
162
+ <img [src]="referencePoseImage" alt="Uploaded custom pose">
163
+ <!-- Pose keypoints overlay (optional visualization) -->
164
+ <canvas #poseCanvas class="pose-overlay-canvas"></canvas>
165
+ </div>
166
+ <div class="pose-details">
167
+ <h4>Your Custom Pose</h4>
168
+ <p>{{ referencePoseDescription || 'Pose detected successfully' }}</p>
169
+ <div class="pose-status" *ngIf="poseDetectionStatus">
170
+ <ion-badge [color]="poseDetectionStatus.success ? 'success' : 'danger'">
171
+ {{ poseDetectionStatus.message }}
172
+ </ion-badge>
173
+ </div>
174
+ </div>
175
+ </div>
176
+ <!-- Save as Custom Pose Button -->
177
+ <div class="save-custom-pose-section" *ngIf="poseDetectionStatus?.success && customPosesEnabled">
178
+ <ion-button expand="block" (click)="onSaveCustomPose()" color="success" [disabled]="isSavingCustomPose">
179
+ <ion-icon slot="start" [name]="isSavingCustomPose ? 'hourglass' : 'bookmark'"></ion-icon>
180
+ {{ isSavingCustomPose ? 'Saving...' : 'Save as Custom Pose' }}
181
+ </ion-button>
182
+ <p class="help-text">Save this pose to reuse it in future verifications</p>
183
+ </div>
184
+
185
+ <button class="change-pose-link" *ngIf="!poseSpecificMode" (click)="clearReferencePose()">
186
+ Change Pose
187
+ </button>
188
+ </div>
189
+
190
+ <!-- Upload Custom Pose Section -->
191
+ <div class="upload-pose-section" *ngIf="poseSelectionMode === 'upload' && !referencePoseImage && !selectedPose">
192
+ <div class="upload-container"
193
+ [class.dragging]="isDragging"
194
+ (dragover)="onDragOver($event)"
195
+ (dragleave)="onDragLeave($event)"
196
+ (drop)="onDrop($event)"
197
+ (click)="fileInput.click()">
198
+
199
+ <input #fileInput
200
+ type="file"
201
+ accept="image/*"
202
+ (change)="onFileSelected($event)"
203
+ style="display: none;">
204
+
205
+ <div class="upload-content" *ngIf="!isProcessingImage">
206
+ <ion-icon name="cloud-upload-outline" class="upload-icon" color="primary"></ion-icon>
207
+ <h4>Upload Your Pose Image</h4>
208
+ <p class="upload-instructions">
209
+ Drag and drop an image here, or click to browse
210
+ </p>
211
+ <p class="upload-hint">
212
+ Supported formats: JPEG, PNG, WebP (max 10MB)
213
+ </p>
214
+ <ion-button fill="outline" size="small">
215
+ <ion-icon slot="start" name="folder-open-outline"></ion-icon>
216
+ Choose File
217
+ </ion-button>
218
+ </div>
219
+
220
+ <div class="upload-processing" *ngIf="isProcessingImage">
221
+ <ion-spinner name="crescent"></ion-spinner>
222
+ <p>Detecting pose in your image...</p>
223
+ </div>
224
+ </div>
225
+
226
+ <!-- Upload Tips -->
227
+ <div class="upload-tips">
228
+ <h5>Tips for best results:</h5>
229
+ <ul>
230
+ <li>Use a clear, well-lit photo</li>
231
+ <li>Face and upper body should be visible</li>
232
+ <li>Stand against a plain background</li>
233
+ <li>Hold the pose clearly and steadily</li>
234
+ </ul>
235
+ </div>
236
+
237
+ <!-- Error/Status Message -->
238
+ <div class="upload-status" *ngIf="poseDetectionStatus && !referencePoseImage">
239
+ <ion-card [color]="poseDetectionStatus.success ? 'success' : 'danger'">
240
+ <ion-card-content>
241
+ <div class="status-content">
242
+ <ion-icon [name]="poseDetectionStatus.success ? 'checkmark-circle' : 'alert-circle'"></ion-icon>
243
+ <span>{{ poseDetectionStatus.message }}</span>
244
+ </div>
245
+ </ion-card-content>
246
+ </ion-card>
247
+ </div>
248
+ </div>
249
+
250
+ <!-- Filters & Search (only in browse mode; hidden in pose-specific flow) -->
251
+ <div class="filters-container" *ngIf="!poseSpecificMode && !selectedPose && !referencePoseImage && poseSelectionMode === 'browse'">
252
+ <div class="filter-header">
253
+ <ion-button fill="clear" size="small" (click)="toggleFilters()">
254
+ <ion-icon slot="start" name="filter"></ion-icon>
255
+ Filters
256
+ <ion-icon slot="end" [name]="showFilters ? 'chevron-up' : 'chevron-down'"></ion-icon>
257
+ </ion-button>
258
+ <div class="view-toggle">
259
+ <ion-button fill="clear" size="small" [color]="viewMode === 'grid' ? 'primary' : 'medium'" (click)="setViewMode('grid')">
260
+ <ion-icon slot="icon-only" name="grid"></ion-icon>
261
+ </ion-button>
262
+ <ion-button fill="clear" size="small" [color]="viewMode === 'list' ? 'primary' : 'medium'" (click)="setViewMode('list')">
263
+ <ion-icon slot="icon-only" name="list"></ion-icon>
264
+ </ion-button>
265
+ </div>
266
+ </div>
267
+
268
+ <!-- Expandable Filters -->
269
+ <div class="filters-content" *ngIf="showFilters">
270
+ <!-- Search Bar -->
271
+ <ion-searchbar
272
+ [(ngModel)]="searchQuery"
273
+ (ionInput)="onSearchChange($event)"
274
+ placeholder="Search poses..."
275
+ animated="true">
276
+ </ion-searchbar>
277
+
278
+ <!-- Category Filter -->
279
+ <div class="filter-group">
280
+ <label>Category:</label>
281
+ <div class="filter-chips">
282
+ <ion-chip
283
+ *ngFor="let cat of categories"
284
+ [color]="selectedCategory === cat.key ? 'primary' : 'medium'"
285
+ (click)="filterByCategory(cat.key)">
286
+ {{ cat.label }}
287
+ </ion-chip>
288
+ </div>
289
+ </div>
290
+
291
+ <!-- Difficulty Filter -->
292
+ <div class="filter-group">
293
+ <label>Difficulty:</label>
294
+ <div class="filter-chips">
295
+ <ion-chip
296
+ *ngFor="let diff of difficulties"
297
+ [color]="selectedDifficulty === diff.key ? 'primary' : 'medium'"
298
+ (click)="filterByDifficulty(diff.key)">
299
+ {{ diff.label }}
300
+ </ion-chip>
301
+ </div>
302
+ </div>
303
+
304
+ <!-- Clear Filters -->
305
+ <ion-button fill="clear" size="small" (click)="clearFilters()" *ngIf="selectedCategory !== 'all' || selectedDifficulty !== 'all' || searchQuery">
306
+ <ion-icon slot="start" name="close-circle"></ion-icon>
307
+ Clear Filters
308
+ </ion-button>
309
+ </div>
310
+ </div>
311
+
312
+ <!-- Pose Grid/List (only in browse mode; hidden in pose-specific flow) -->
313
+ <div class="poses-display" *ngIf="!poseSpecificMode && !selectedPose && !referencePoseImage && poseSelectionMode === 'browse'">
314
+ <p class="results-count">{{ filteredPoses.length }} pose(s) available</p>
315
+
316
+ <!-- Grid View -->
317
+ <div class="pose-grid" *ngIf="viewMode === 'grid'">
318
+ <div
319
+ *ngFor="let pose of filteredPoses"
320
+ class="pose-card"
321
+ [class.selected]="isPoseSelected(pose)"
322
+ [class.custom-pose]="pose.isCustom"
323
+ (click)="onSelectPose(pose)">
324
+
325
+ <!-- Custom Pose Badge -->
326
+ <ion-badge *ngIf="pose.isCustom" class="custom-badge" color="secondary">
327
+ <ion-icon name="star"></ion-icon>
328
+ Custom
329
+ </ion-badge>
330
+
331
+ <!-- Delete Button (Custom Poses Only) -->
332
+ <button
333
+ *ngIf="pose.isCustom && customPosesEnabled"
334
+ class="delete-pose-button"
335
+ (click)="onDeleteCustomPose(pose, $event)">
336
+ <ion-icon name="trash"></ion-icon>
337
+ </button>
338
+
339
+ <div class="pose-image-container">
340
+ <img [src]="pose.imageBlobUrl || pose.imagePath" [alt]="pose.name" (error)="onImageError($event)">
341
+ <ion-icon [name]="getCategoryIcon(pose.category)" class="fallback-icon" [color]="getCategoryColor(pose.category)"></ion-icon>
342
+ </div>
343
+ <div class="pose-info-compact">
344
+ <h4>{{ pose.name }}</h4>
345
+ <div class="badges-compact">
346
+ <ion-badge [color]="getDifficultyColor(pose.difficulty)" size="small">
347
+ {{ pose.difficulty }}
348
+ </ion-badge>
349
+ </div>
350
+ </div>
351
+ <div class="pose-number">{{ pose.id }}</div>
352
+ </div>
353
+ </div>
354
+
355
+ <!-- List View -->
356
+ <div class="pose-list" *ngIf="viewMode === 'list'">
357
+ <ion-item
358
+ *ngFor="let pose of filteredPoses"
359
+ button
360
+ [class.selected]="isPoseSelected(pose)"
361
+ (click)="onSelectPose(pose)"
362
+ lines="full">
363
+ <ion-icon [name]="getCategoryIcon(pose.category)" [color]="getCategoryColor(pose.category)" slot="start"></ion-icon>
364
+ <ion-label>
365
+ <h3>{{ pose.id }}. {{ pose.name }}</h3>
366
+ <p>{{ pose.description }}</p>
367
+ </ion-label>
368
+ <ion-badge [color]="getDifficultyColor(pose.difficulty)" slot="end">
369
+ {{ pose.difficulty }}
370
+ </ion-badge>
371
+ </ion-item>
372
+ </div>
373
+
374
+ <!-- No Results -->
375
+ <div class="no-results" *ngIf="filteredPoses.length === 0">
376
+ <ion-icon name="search" color="medium"></ion-icon>
377
+ <p>No poses match your filters</p>
378
+ <ion-button fill="clear" (click)="clearFilters()">Clear Filters</ion-button>
379
+ </div>
380
+ </div>
381
+ </div>
382
+
383
+ <div class="button-container">
384
+ <ion-button expand="block" (click)="onStart()">
385
+ Start Verification
386
+ </ion-button>
387
+
388
+ <button class="cancel-link" *ngIf="!poseSpecificMode" (click)="onCancel()">
389
+ Cancel
390
+ </button>
391
+ </div>
392
+ </div>
393
+ </div>
394
+ </div>