pipwave-ekyc-uikit 3.0.5-beta.1 → 3.0.5
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.
- package/.claude/settings.local.json +8 -0
- package/.env.development +1 -1
- package/.env.production +1 -1
- package/dist/pw-bundle.js +4 -4
- package/package.json +4 -5
package/.env.development
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
FACE_MODEL=/face-models
|
|
1
|
+
FACE_MODEL=/face-models
|
package/.env.production
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
FACE_MODEL=https://assets.pipwave.com/ekyc/sdk/face-models
|
|
1
|
+
FACE_MODEL=https://assets.pipwave.com/ekyc/sdk/face-models
|
package/dist/pw-bundle.js
CHANGED
|
@@ -26,7 +26,7 @@ return /******/ (() => { // webpackBootstrap
|
|
|
26
26
|
/***/ ((module, __webpack_exports__, __webpack_require__) => {
|
|
27
27
|
|
|
28
28
|
"use strict";
|
|
29
|
-
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ \"./node_modules/css-loader/dist/runtime/noSourceMaps.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _node_modules_css_loader_dist_cjs_js_pikaday_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! -!../../../node_modules/css-loader/dist/cjs.js!./pikaday.css */ \"./node_modules/css-loader/dist/cjs.js!./src/assets/scss/pikaday.css\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../node_modules/css-loader/dist/runtime/getUrl.js */ \"./node_modules/css-loader/dist/runtime/getUrl.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_3__);\n// Imports\n\n\n\n\nvar ___CSS_LOADER_URL_IMPORT_0___ = new URL(/* asset import */ __webpack_require__(/*! ../img/mask-smile.webp */ \"./src/assets/img/mask-smile.webp\"), __webpack_require__.b);\nvar ___CSS_LOADER_URL_IMPORT_1___ = new URL(/* asset import */ __webpack_require__(/*! ../img/mask-neutral.webp */ \"./src/assets/img/mask-neutral.webp\"), __webpack_require__.b);\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n___CSS_LOADER_EXPORT___.push([module.id, \"@import url(https://fonts.googleapis.com/css2?family=Roboto+Flex:ital,wght@0,400;0,600;1,400;1,600&display=swap);\"]);\n___CSS_LOADER_EXPORT___.push([module.id, \"@import url(https://fonts.googleapis.com/icon?family=Material+Icons);\"]);\n___CSS_LOADER_EXPORT___.push([module.id, \"@import url(https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200);\"]);\n___CSS_LOADER_EXPORT___.i(_node_modules_css_loader_dist_cjs_js_pikaday_css__WEBPACK_IMPORTED_MODULE_2__[\"default\"]);\nvar ___CSS_LOADER_URL_REPLACEMENT_0___ = _node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_3___default()(___CSS_LOADER_URL_IMPORT_0___);\nvar ___CSS_LOADER_URL_REPLACEMENT_1___ = _node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_3___default()(___CSS_LOADER_URL_IMPORT_1___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `@charset \"UTF-8\";\n*, ::before, ::after {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgba(59, 130, 246, 0.5);\n --tw-ring-offset-shadow: 0 0 rgba(0,0,0,0);\n --tw-ring-shadow: 0 0 rgba(0,0,0,0);\n --tw-shadow: 0 0 rgba(0,0,0,0);\n --tw-shadow-colored: 0 0 rgba(0,0,0,0);\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n}\n\n::backdrop {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgba(59, 130, 246, 0.5);\n --tw-ring-offset-shadow: 0 0 rgba(0,0,0,0);\n --tw-ring-shadow: 0 0 rgba(0,0,0,0);\n --tw-shadow: 0 0 rgba(0,0,0,0);\n --tw-shadow-colored: 0 0 rgba(0,0,0,0);\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n}\n\n.pw-pointer-events-none {\n pointer-events: none;\n}\n\n.pw-invisible {\n visibility: hidden;\n}\n\n.\\\\!pw-absolute {\n position: absolute !important;\n}\n\n.pw-absolute {\n position: absolute;\n}\n\n.pw-relative {\n position: relative;\n}\n\n.pw-inset-0 {\n top: 0px;\n right: 0px;\n bottom: 0px;\n left: 0px;\n}\n\n.pw-bottom-0 {\n bottom: 0px;\n}\n\n.pw-bottom-16 {\n bottom: 4rem;\n}\n\n.pw-bottom-\\\\[10\\\\%\\\\] {\n bottom: 10%;\n}\n\n.pw-left-0 {\n left: 0px;\n}\n\n.pw-left-1\\\\/2 {\n left: 50%;\n}\n\n.pw-left-10 {\n left: 2.5rem;\n}\n\n.pw-left-2 {\n left: 0.5rem;\n}\n\n.pw-left-4 {\n left: 1rem;\n}\n\n.pw-left-8 {\n left: 2rem;\n}\n\n.pw-left-\\\\[100\\\\%\\\\] {\n left: 100%;\n}\n\n.pw-right-0 {\n right: 0px;\n}\n\n.pw-right-3 {\n right: 0.75rem;\n}\n\n.pw-right-5 {\n right: 1.25rem;\n}\n\n.pw-top-0 {\n top: 0px;\n}\n\n.pw-top-1 {\n top: 0.25rem;\n}\n\n.pw-top-1\\\\/2 {\n top: 50%;\n}\n\n.pw-top-1\\\\/3 {\n top: 33.333333%;\n}\n\n.pw-top-2\\\\/4 {\n top: 50%;\n}\n\n.pw-top-4 {\n top: 1rem;\n}\n\n.pw-top-\\\\[14px\\\\] {\n top: 14px;\n}\n\n.pw-z-10 {\n z-index: 10;\n}\n\n.pw-z-40 {\n z-index: 40;\n}\n\n.pw-z-50 {\n z-index: 50;\n}\n\n.pw-z-\\\\[2\\\\] {\n z-index: 2;\n}\n\n.pw-z-\\\\[9999\\\\] {\n z-index: 9999;\n}\n\n.pw-order-1 {\n order: 1;\n}\n\n.pw-order-2 {\n order: 2;\n}\n\n.pw-m-0 {\n margin: 0px;\n}\n\n.pw-m-5 {\n margin: 1.25rem;\n}\n\n.pw-mx-0 {\n margin-left: 0px;\n margin-right: 0px;\n}\n\n.pw-mx-5 {\n margin-left: 1.25rem;\n margin-right: 1.25rem;\n}\n\n.pw-mx-auto {\n margin-left: auto;\n margin-right: auto;\n}\n\n.pw-my-4 {\n margin-top: 1rem;\n margin-bottom: 1rem;\n}\n\n.pw-mb-0 {\n margin-bottom: 0px;\n}\n\n.pw-mb-10 {\n margin-bottom: 2.5rem;\n}\n\n.pw-mb-2 {\n margin-bottom: 0.5rem;\n}\n\n.pw-mb-3 {\n margin-bottom: 0.75rem;\n}\n\n.pw-mb-4 {\n margin-bottom: 1rem;\n}\n\n.pw-mb-5 {\n margin-bottom: 1.25rem;\n}\n\n.pw-mb-6 {\n margin-bottom: 1.5rem;\n}\n\n.pw-mb-\\\\[0\\\\.3rem\\\\] {\n margin-bottom: 0.3rem;\n}\n\n.pw-ml-2 {\n margin-left: 0.5rem;\n}\n\n.pw-mr-4 {\n margin-right: 1rem;\n}\n\n.pw-mt-2 {\n margin-top: 0.5rem;\n}\n\n.pw-mt-3 {\n margin-top: 0.75rem;\n}\n\n.pw-mt-4 {\n margin-top: 1rem;\n}\n\n.pw-mt-6 {\n margin-top: 1.5rem;\n}\n\n.pw-box-border {\n box-sizing: border-box;\n}\n\n.pw-block {\n display: block;\n}\n\n.pw-inline-block {\n display: inline-block;\n}\n\n.pw-flex {\n display: flex;\n}\n\n.pw-grid {\n display: grid;\n}\n\n.pw-hidden {\n display: none;\n}\n\n.\\\\!pw-h-px {\n height: 1px !important;\n}\n\n.pw-h-1 {\n height: 0.25rem;\n}\n\n.pw-h-10 {\n height: 2.5rem;\n}\n\n.pw-h-11 {\n height: 2.75rem;\n}\n\n.pw-h-12 {\n height: 3rem;\n}\n\n.pw-h-14 {\n height: 3.5rem;\n}\n\n.pw-h-16 {\n height: 4rem;\n}\n\n.pw-h-3 {\n height: 0.75rem;\n}\n\n.pw-h-\\\\[calc\\\\(100\\\\%-2\\\\*1rem\\\\)\\\\] {\n height: calc(100% - 2rem);\n}\n\n.pw-h-full {\n height: 100%;\n}\n\n.pw-h-screen {\n height: 100vh;\n}\n\n.pw-max-h-80 {\n max-height: 20rem;\n}\n\n.pw-max-h-\\\\[90vh\\\\] {\n max-height: 90vh;\n}\n\n.pw-min-h-0 {\n min-height: 0px;\n}\n\n.pw-min-h-\\\\[256px\\\\] {\n min-height: 256px;\n}\n\n.\\\\!pw-w-px {\n width: 1px !important;\n}\n\n.pw-w-10 {\n width: 2.5rem;\n}\n\n.pw-w-11 {\n width: 2.75rem;\n}\n\n.pw-w-16 {\n width: 4rem;\n}\n\n.pw-w-36 {\n width: 9rem;\n}\n\n.pw-w-6 {\n width: 1.5rem;\n}\n\n.pw-w-\\\\[calc\\\\(100\\\\%-2\\\\*1\\\\.25rem\\\\)\\\\] {\n width: calc(100% - 2.5rem);\n}\n\n.pw-w-\\\\[calc\\\\(100\\\\%-32px\\\\)\\\\] {\n width: calc(100% - 32px);\n}\n\n.pw-w-full {\n width: 100%;\n}\n\n.pw-w-screen {\n width: 100vw;\n}\n\n.pw-max-w-\\\\[1400px\\\\] {\n max-width: 1400px;\n}\n\n.pw-max-w-md {\n max-width: 28rem;\n}\n\n.pw-flex-1 {\n flex: 1 1 0%;\n}\n\n.pw-flex-shrink-0 {\n flex-shrink: 0;\n}\n\n.pw-grow {\n flex-grow: 1;\n}\n\n.-pw-translate-x-1\\\\/2 {\n --tw-translate-x: -50%;\n transform: translate(-50%, var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n\n.-pw-translate-y-1\\\\/2 {\n --tw-translate-y: -50%;\n transform: translate(var(--tw-translate-x), -50%) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n\n.-pw-translate-y-2\\\\/4 {\n --tw-translate-y: -50%;\n transform: translate(var(--tw-translate-x), -50%) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n\n.pw-translate-y-full {\n --tw-translate-y: 100%;\n transform: translate(var(--tw-translate-x), 100%) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n\n@keyframes pw-camera-rotation {\n 0% {\n transform: rotate3d(0, 1, 0, 0deg);\n }\n 100% {\n transform: rotate3d(0, 1, 0, 180deg);\n }\n}\n.pw-animate-camera {\n animation: pw-camera-rotation 1s ease-out 0.5s 1;\n}\n\n@keyframes pw-loading {\n 0% {\n transform: translateX(-100%);\n }\n 50% {\n transform: translateX(0%);\n }\n 100% {\n transform: translateX(100%);\n }\n}\n.pw-animate-loading {\n animation: pw-loading 1.25s linear infinite;\n}\n\n@keyframes pw-spin {\n to {\n transform: rotate(360deg);\n }\n}\n.pw-animate-spin {\n animation: pw-spin 1s linear infinite;\n}\n\n.pw-cursor-pointer {\n cursor: pointer;\n}\n\n.pw-resize-none {\n resize: none;\n}\n\n.pw-list-disc {\n list-style-type: disc;\n}\n\n.pw-grid-cols-1 {\n grid-template-columns: repeat(1, minmax(0, 1fr));\n}\n\n.pw-flex-col {\n flex-direction: column;\n}\n\n.pw-items-start {\n align-items: flex-start;\n}\n\n.pw-items-end {\n align-items: flex-end;\n}\n\n.pw-items-center {\n align-items: center;\n}\n\n.pw-justify-end {\n justify-content: flex-end;\n}\n\n.pw-justify-center {\n justify-content: center;\n}\n\n.pw-justify-between {\n justify-content: space-between;\n}\n\n.pw-gap-1 {\n gap: 0.25rem;\n}\n\n.pw-gap-4 {\n gap: 1rem;\n}\n\n.pw-gap-x-1 {\n -moz-column-gap: 0.25rem;\n column-gap: 0.25rem;\n}\n\n.pw-gap-x-3 {\n -moz-column-gap: 0.75rem;\n column-gap: 0.75rem;\n}\n\n.pw-space-y-1 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: 0.25rem;\n margin-top: calc(0.25rem * (1 - var(--tw-space-y-reverse)));\n margin-top: 0.25rem;\n margin-top: calc(0.25rem * (1 - var(--tw-space-y-reverse)));\n margin-bottom: 0rem;\n margin-bottom: calc(0.25rem * var(--tw-space-y-reverse));\n}\n\n.pw-overflow-auto {\n overflow: auto;\n}\n\n.\\\\!pw-overflow-hidden {\n overflow: hidden !important;\n}\n\n.pw-overflow-hidden {\n overflow: hidden;\n}\n\n.pw-overflow-y-auto {\n overflow-y: auto;\n}\n\n.pw-overflow-x-hidden {\n overflow-x: hidden;\n}\n\n.pw-overflow-y-hidden {\n overflow-y: hidden;\n}\n\n.\\\\!pw-whitespace-nowrap {\n white-space: nowrap !important;\n}\n\n.pw-rounded-2xl {\n border-radius: 1rem;\n}\n\n.pw-rounded-full {\n border-radius: 9999px;\n}\n\n.pw-rounded-lg {\n border-radius: 0.5rem;\n}\n\n.pw-rounded-none {\n border-radius: 0px;\n}\n\n.pw-rounded-xl {\n border-radius: 0.75rem;\n}\n\n.pw-rounded-b-lg {\n border-bottom-right-radius: 0.5rem;\n border-bottom-left-radius: 0.5rem;\n}\n\n.\\\\!pw-border-0 {\n border-width: 0px !important;\n}\n\n.pw-border {\n border-width: 1px;\n}\n\n.pw-border-0 {\n border-width: 0px;\n}\n\n.pw-border-4 {\n border-width: 4px;\n}\n\n.pw-border-b {\n border-bottom-width: 1px;\n}\n\n.pw-border-t-0 {\n border-top-width: 0px;\n}\n\n.pw-border-solid {\n border-style: solid;\n}\n\n.pw-border-none {\n border-style: none;\n}\n\n.pw-border-current {\n border-color: currentColor;\n}\n\n.pw-border-gray-200 {\n --tw-border-opacity: 1;\n border-color: rgb(229, 231, 235);\n border-color: rgba(229, 231, 235, var(--tw-border-opacity));\n}\n\n.pw-border-grey-5 {\n --tw-border-opacity: 1;\n border-color: rgb(201, 201, 201);\n border-color: rgba(201, 201, 201, var(--tw-border-opacity));\n}\n\n.pw-border-red-500 {\n --tw-border-opacity: 1;\n border-color: rgb(239, 68, 68);\n border-color: rgba(239, 68, 68, var(--tw-border-opacity));\n}\n\n.pw-border-white {\n --tw-border-opacity: 1;\n border-color: rgb(255, 255, 255);\n border-color: rgba(255, 255, 255, var(--tw-border-opacity));\n}\n\n.pw-border-r-transparent {\n border-right-color: transparent;\n}\n\n.pw-bg-black {\n --tw-bg-opacity: 1;\n background-color: rgb(0, 0, 0);\n background-color: rgba(0, 0, 0, var(--tw-bg-opacity));\n}\n\n.pw-bg-grey-10 {\n --tw-bg-opacity: 1;\n background-color: rgb(29, 30, 34);\n background-color: rgba(29, 30, 34, var(--tw-bg-opacity));\n}\n\n.pw-bg-grey-2 {\n --tw-bg-opacity: 1;\n background-color: rgb(250, 250, 252);\n background-color: rgba(250, 250, 252, var(--tw-bg-opacity));\n}\n\n.pw-bg-grey-3 {\n --tw-bg-opacity: 1;\n background-color: rgb(247, 247, 250);\n background-color: rgba(247, 247, 250, var(--tw-bg-opacity));\n}\n\n.pw-bg-grey-4 {\n --tw-bg-opacity: 1;\n background-color: rgb(231, 231, 236);\n background-color: rgba(231, 231, 236, var(--tw-bg-opacity));\n}\n\n.pw-bg-grey-6 {\n --tw-bg-opacity: 1;\n background-color: rgb(158, 158, 158);\n background-color: rgba(158, 158, 158, var(--tw-bg-opacity));\n}\n\n.pw-bg-primary {\n --tw-bg-opacity: 1;\n background-color: rgb(210, 28, 62);\n background-color: rgba(210, 28, 62, var(--tw-bg-opacity));\n}\n\n.pw-bg-white {\n --tw-bg-opacity: 1;\n background-color: rgb(255, 255, 255);\n background-color: rgba(255, 255, 255, var(--tw-bg-opacity));\n}\n\n.pw-bg-opacity-20 {\n --tw-bg-opacity: 0.2;\n}\n\n.pw-bg-opacity-70 {\n --tw-bg-opacity: 0.7;\n}\n\n.pw-bg-opacity-90 {\n --tw-bg-opacity: 0.9;\n}\n\n.pw-bg-gradient-to-r {\n background-image: linear-gradient(to right, var(--tw-gradient-stops));\n}\n\n.pw-from-\\\\[\\\\#D21C3E\\\\] {\n --tw-gradient-from: #D21C3E var(--tw-gradient-from-position);\n --tw-gradient-to: rgba(210, 28, 62, 0) var(--tw-gradient-to-position);\n --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);\n}\n\n.pw-to-\\\\[\\\\#D03C58\\\\] {\n --tw-gradient-to: #D03C58 var(--tw-gradient-to-position);\n}\n\n.\\\\!pw-p-0 {\n padding: 0px !important;\n}\n\n.pw-p-0 {\n padding: 0px;\n}\n\n.pw-p-3 {\n padding: 0.75rem;\n}\n\n.pw-p-4 {\n padding: 1rem;\n}\n\n.pw-p-5 {\n padding: 1.25rem;\n}\n\n.pw-p-6 {\n padding: 1.5rem;\n}\n\n.pw-p-\\\\[30px\\\\] {\n padding: 30px;\n}\n\n.pw-px-0 {\n padding-left: 0px;\n padding-right: 0px;\n}\n\n.pw-px-2 {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n\n.pw-px-3 {\n padding-left: 0.75rem;\n padding-right: 0.75rem;\n}\n\n.pw-px-4 {\n padding-left: 1rem;\n padding-right: 1rem;\n}\n\n.pw-px-5 {\n padding-left: 1.25rem;\n padding-right: 1.25rem;\n}\n\n.pw-px-6 {\n padding-left: 1.5rem;\n padding-right: 1.5rem;\n}\n\n.pw-py-1 {\n padding-top: 0.25rem;\n padding-bottom: 0.25rem;\n}\n\n.pw-py-2 {\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n\n.pw-py-3 {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n}\n\n.pw-py-4 {\n padding-top: 1rem;\n padding-bottom: 1rem;\n}\n\n.pw-py-6 {\n padding-top: 1.5rem;\n padding-bottom: 1.5rem;\n}\n\n.pw-pb-2 {\n padding-bottom: 0.5rem;\n}\n\n.pw-pb-3 {\n padding-bottom: 0.75rem;\n}\n\n.pw-pb-4 {\n padding-bottom: 1rem;\n}\n\n.pw-pl-10 {\n padding-left: 2.5rem;\n}\n\n.pw-pl-5 {\n padding-left: 1.25rem;\n}\n\n.pw-pl-8 {\n padding-left: 2rem;\n}\n\n.pw-pr-2 {\n padding-right: 0.5rem;\n}\n\n.pw-pt-0 {\n padding-top: 0px;\n}\n\n.pw-pt-0\\\\.5 {\n padding-top: 0.125rem;\n}\n\n.pw-pt-1 {\n padding-top: 0.25rem;\n}\n\n.pw-pt-3 {\n padding-top: 0.75rem;\n}\n\n.pw-pt-4 {\n padding-top: 1rem;\n}\n\n.pw-pt-6 {\n padding-top: 1.5rem;\n}\n\n.pw-pt-8 {\n padding-top: 2rem;\n}\n\n.pw-pt-\\\\[14px\\\\] {\n padding-top: 14px;\n}\n\n.pw-pt-\\\\[22px\\\\] {\n padding-top: 22px;\n}\n\n.pw-text-left {\n text-align: left;\n}\n\n.pw-text-center {\n text-align: center;\n}\n\n.pw-text-right {\n text-align: right;\n}\n\n.pw-align-\\\\[-0\\\\.125em\\\\] {\n vertical-align: -0.125em;\n}\n\n.pw-font-\\\\[\\\\'Roboto_Flex\\\\'\\\\] {\n font-family: \"Roboto Flex\";\n}\n\n.pw-font-pw {\n font-family: Roboto Flex;\n}\n\n.pw-text-2xl {\n font-size: 1.5rem;\n line-height: 2rem;\n}\n\n.pw-text-4xl {\n font-size: 2.25rem;\n line-height: 2.5rem;\n}\n\n.pw-text-6xl {\n font-size: 3.75rem;\n line-height: 1;\n}\n\n.pw-text-lg {\n font-size: 1.125rem;\n line-height: 1.75rem;\n}\n\n.pw-text-sm {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n\n.pw-text-xl {\n font-size: 1.25rem;\n line-height: 1.75rem;\n}\n\n.pw-text-xs {\n font-size: 0.75rem;\n line-height: 1rem;\n}\n\n.pw-font-bold {\n font-weight: 700;\n}\n\n.pw-font-medium {\n font-weight: 500;\n}\n\n.pw-text-black {\n --tw-text-opacity: 1;\n color: rgb(0, 0, 0);\n color: rgba(0, 0, 0, var(--tw-text-opacity));\n}\n\n.pw-text-gray-400 {\n --tw-text-opacity: 1;\n color: rgb(156, 163, 175);\n color: rgba(156, 163, 175, var(--tw-text-opacity));\n}\n\n.pw-text-green-500 {\n --tw-text-opacity: 1;\n color: rgb(34, 197, 94);\n color: rgba(34, 197, 94, var(--tw-text-opacity));\n}\n\n.pw-text-grey-10 {\n --tw-text-opacity: 1;\n color: rgb(29, 30, 34);\n color: rgba(29, 30, 34, var(--tw-text-opacity));\n}\n\n.pw-text-grey-2 {\n --tw-text-opacity: 1;\n color: rgb(250, 250, 252);\n color: rgba(250, 250, 252, var(--tw-text-opacity));\n}\n\n.pw-text-grey-5 {\n --tw-text-opacity: 1;\n color: rgb(201, 201, 201);\n color: rgba(201, 201, 201, var(--tw-text-opacity));\n}\n\n.pw-text-grey-6 {\n --tw-text-opacity: 1;\n color: rgb(158, 158, 158);\n color: rgba(158, 158, 158, var(--tw-text-opacity));\n}\n\n.pw-text-grey-7 {\n --tw-text-opacity: 1;\n color: rgb(117, 117, 117);\n color: rgba(117, 117, 117, var(--tw-text-opacity));\n}\n\n.pw-text-info {\n --tw-text-opacity: 1;\n color: rgb(81, 139, 255);\n color: rgba(81, 139, 255, var(--tw-text-opacity));\n}\n\n.pw-text-orange-400 {\n --tw-text-opacity: 1;\n color: rgb(251, 146, 60);\n color: rgba(251, 146, 60, var(--tw-text-opacity));\n}\n\n.pw-text-red-500 {\n --tw-text-opacity: 1;\n color: rgb(239, 68, 68);\n color: rgba(239, 68, 68, var(--tw-text-opacity));\n}\n\n.pw-text-secondary {\n --tw-text-opacity: 1;\n color: rgb(117, 117, 117);\n color: rgba(117, 117, 117, var(--tw-text-opacity));\n}\n\n.pw-text-white {\n --tw-text-opacity: 1;\n color: rgb(255, 255, 255);\n color: rgba(255, 255, 255, var(--tw-text-opacity));\n}\n\n.pw-opacity-40 {\n opacity: 0.4;\n}\n\n.pw-shadow-button-shadow {\n --tw-shadow: 0px 3px 5px 0px rgba(115,115,123,0.30196);\n --tw-shadow-colored: 0px 3px 5px 0px var(--tw-shadow-color);\n box-shadow: 0 0 rgba(0, 0, 0, 0), 0 0 rgba(0, 0, 0, 0), 0px 3px 5px 0px rgba(115, 115, 123, 0.30196);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 rgba(0, 0, 0, 0)), var(--tw-ring-shadow, 0 0 rgba(0, 0, 0, 0)), var(--tw-shadow);\n}\n\n.pw-shadow-lg {\n --tw-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);\n --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);\n box-shadow: 0 0 rgba(0, 0, 0, 0), 0 0 rgba(0, 0, 0, 0), 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 rgba(0, 0, 0, 0)), var(--tw-ring-shadow, 0 0 rgba(0, 0, 0, 0)), var(--tw-shadow);\n}\n\n.pw-outline-none {\n outline: 2px solid transparent;\n outline-offset: 2px;\n}\n\n.pw-outline-dashed {\n outline-style: dashed;\n}\n\n.pw-outline-grey-5 {\n outline-color: #C9C9C9;\n}\n\n.pw-outline-grey-6 {\n outline-color: #9E9E9E;\n}\n\n.pw-transition-all {\n transition-property: all;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n\n.pw-duration-100 {\n transition-duration: 100ms;\n}\n\n.pw-duration-200 {\n transition-duration: 200ms;\n}\n\n.pw-duration-500 {\n transition-duration: 500ms;\n}\n\n/* Ensure full-screen camera on all devices */\n.camera-bg {\n height: 100%;\n width: 100%;\n}\n\n/* Responsive container adjustments */\n.pwsdk-ui {\n transition-property: all;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 300ms;\n}\n\n/* Desktop-specific adjustments */\n@media (min-width: 768px) {\n .pwsdk-ui {\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);\n }\n}\n.\\\\!\\\\[clip\\\\:pw-rect\\\\(0\\\\,0\\\\,0\\\\,0\\\\)\\\\] {\n clip: pw-rect(0, 0, 0, 0) !important;\n}\n\n.pw-bg-disabled,\ninput:disabled {\n background: #f0f0f5;\n}\n\n.pw-watermark {\n position: absolute;\n transform: rotate(-25deg);\n opacity: 0.5;\n font-weight: 500;\n font-size: 20px;\n text-transform: capitalize;\n color: #9e9e9e;\n white-space: nowrap;\n overflow: hidden;\n -webkit-text-stroke-width: 0.3px;\n -webkit-text-stroke-color: #1d1e22;\n}\n\n.pw-drag-drop.highlight {\n outline-color: #d21c3e;\n}\n\n/* Chrome, Safari, Edge, Opera */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n -webkit-appearance: none;\n margin: 0;\n}\n\n/* Firefox */\ninput[type=number] {\n -moz-appearance: textfield;\n}\n\n.camera-bg {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 2;\n margin: 0;\n height: 100%;\n width: 100%;\n background-color: black;\n}\n.camera-bg-color {\n background-color: black;\n}\n.camera-header-area {\n position: absolute;\n text-align: center;\n z-index: 2;\n top: 5%;\n width: 100%;\n}\n.camera-header-area .title {\n color: white;\n}\n.camera-body-area {\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n flex-direction: column;\n}\n.camera-body-area .video-container {\n z-index: -1;\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100vw;\n height: 100vh;\n /* overflow:hidden removed — video is already sized to its native ratio so\n nothing overflows, and the description text above the overlay must not\n be clipped when it extends beyond the container top */\n}\n.camera-body-area .video-element {\n object-fit: cover;\n width: 100%;\n height: 100%;\n}\n.camera-body-area .canvas-element {\n position: absolute;\n z-index: 9;\n}\n.camera-body-area .overlay-container {\n position: absolute;\n margin: auto;\n z-index: 1;\n}\n.camera-body-area .overlay-element {\n position: relative;\n background-position: center center;\n background-repeat: no-repeat;\n background-size: cover;\n box-shadow: 0 0 150px 0 rgba(255, 255, 255, 0.3), 0 0 0 9999px rgb(34, 34, 34);\n}\n@media (max-width: 767px) {\n .camera-body-area .overlay-element {\n box-shadow: 0 0 250px 0 rgba(255, 255, 255, 0.3), 0 0 0 9999px rgb(34, 34, 34);\n }\n}\n.camera-body-area .border-element {\n position: absolute;\n width: 100%;\n height: 100%;\n}\n.camera-body-area .border-id-element:before,\n.camera-body-area .border-id-element:after {\n top: -2px;\n left: -2px;\n position: absolute;\n content: \"\";\n width: 100%;\n height: calc(100% + 50px);\n border-radius: 16px;\n border: 2px solid white;\n}\n.camera-body-area .outlide-id-bottom {\n position: absolute;\n top: 100%;\n width: 100%;\n background-color: white;\n height: 50px;\n display: flex;\n justify-content: center;\n align-items: center;\n border-bottom-left-radius: 8px;\n border-bottom-right-radius: 8px;\n}\n.camera-body-area .border-top-element:before,\n.camera-body-area .border-top-element:after,\n.camera-body-area .border-bottom-element:before,\n.camera-body-area .border-bottom-element:after {\n position: absolute;\n content: \"\";\n width: 10%;\n height: 15%;\n border-color: white;\n border-style: solid;\n transition: border-color 0.12s ease;\n}\n.camera-body-area .border-top-element:before {\n top: -2px;\n left: -2px;\n border-width: 4px 0 0 4px;\n border-top-left-radius: 15px;\n}\n.camera-body-area .border-top-element:after {\n top: -2px;\n right: -2px;\n border-width: 4px 4px 0 0;\n border-top-right-radius: 15px;\n}\n.camera-body-area .border-bottom-element:before {\n bottom: -2px;\n right: -2px;\n border-width: 0 4px 4px 0;\n border-bottom-right-radius: 15px;\n}\n.camera-body-area .border-bottom-element:after {\n bottom: -2px;\n left: -2px;\n border-width: 0 0 4px 4px;\n border-bottom-left-radius: 15px;\n}\n.camera-body-area .border-element--valid:before,\n.camera-body-area .border-element--valid:after {\n border-color: #8ede34 !important;\n}\n.camera-body-area .border-element--invalid:before,\n.camera-body-area .border-element--invalid:after {\n border-color: #ef4444 !important;\n}\n.camera-body-area .overlay-element--active {\n border-color: #8ede34 !important;\n}\n.camera-body-area .overlay-element--selfie-smile {\n background-size: contain;\n background-position: center center;\n background-image: url(${___CSS_LOADER_URL_REPLACEMENT_0___});\n}\n.camera-body-area .overlay-element--selfie-neutral {\n background-size: contain;\n background-position: center center;\n background-image: url(${___CSS_LOADER_URL_REPLACEMENT_1___});\n}\n.camera-footer-area {\n position: absolute;\n text-align: center;\n z-index: 2;\n bottom: 10%;\n width: 100%;\n}\n.camera-footer-area .instruction {\n color: white;\n}\n\n/* Responsive utilities */\n.hover\\\\:pw-bg-grey-3:hover {\n --tw-bg-opacity: 1;\n background-color: rgb(247, 247, 250);\n background-color: rgba(247, 247, 250, var(--tw-bg-opacity));\n}\n\n.active\\\\:pw-scale-90:active {\n --tw-scale-x: .9;\n --tw-scale-y: .9;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(0.9) scaleY(0.9);\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n\n.pw-peer:-moz-placeholder-shown ~ .peer-placeholder-shown\\\\:pw-visible {\n visibility: visible;\n}\n\n.pw-peer:placeholder-shown ~ .peer-placeholder-shown\\\\:pw-visible {\n visibility: visible;\n}\n\n.pw-peer:-moz-placeholder-shown ~ .peer-placeholder-shown\\\\:pw-top-\\\\[30px\\\\] {\n top: 30px;\n}\n\n.pw-peer:placeholder-shown ~ .peer-placeholder-shown\\\\:pw-top-\\\\[30px\\\\] {\n top: 30px;\n}\n\n.pw-peer:-moz-placeholder-shown ~ .peer-placeholder-shown\\\\:-pw-translate-y-2\\\\/4 {\n --tw-translate-y: -50%;\n transform: translate(var(--tw-translate-x), -50%) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n\n.pw-peer:placeholder-shown ~ .peer-placeholder-shown\\\\:-pw-translate-y-2\\\\/4 {\n --tw-translate-y: -50%;\n transform: translate(var(--tw-translate-x), -50%) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n\n.pw-peer:-moz-placeholder-shown ~ .peer-placeholder-shown\\\\:pw-text-sm {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n\n.pw-peer:placeholder-shown ~ .peer-placeholder-shown\\\\:pw-text-sm {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n\n.pw-peer:focus ~ .peer-focus\\\\:pw-invisible {\n visibility: hidden;\n}\n\n.pw-peer:focus ~ .peer-focus\\\\:pw-top-\\\\[14px\\\\] {\n top: 14px;\n}\n\n.pw-peer:focus ~ .peer-focus\\\\:pw-text-xs {\n font-size: 0.75rem;\n line-height: 1rem;\n}\n\n@media (min-width: 768px) {\n .pw-md\\\\:pw-order-1 {\n order: 1;\n }\n .pw-md\\\\:pw-order-2 {\n order: 2;\n }\n .pw-md\\\\:pw-mb-6 {\n margin-bottom: 1.5rem;\n }\n .pw-md\\\\:pw-w-auto {\n width: auto;\n }\n .pw-md\\\\:pw-max-w-\\\\[300px\\\\] {\n max-width: 300px;\n }\n .pw-md\\\\:pw-max-w-\\\\[480px\\\\] {\n max-width: 480px;\n }\n .pw-md\\\\:pw-grid-cols-2 {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n }\n .pw-md\\\\:pw-gap-6 {\n gap: 1.5rem;\n }\n .pw-md\\\\:pw-rounded-2xl {\n border-radius: 1rem;\n }\n .pw-md\\\\:pw-border {\n border-width: 1px;\n }\n .pw-md\\\\:pw-border-grey-5 {\n --tw-border-opacity: 1;\n border-color: rgb(201, 201, 201);\n border-color: rgba(201, 201, 201, var(--tw-border-opacity));\n }\n}`, \"\"]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://PWUISDK/./src/assets/scss/index.scss?./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./node_modules/postcss-loader/dist/cjs.js");
|
|
29
|
+
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ \"./node_modules/css-loader/dist/runtime/noSourceMaps.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _node_modules_css_loader_dist_cjs_js_pikaday_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! -!../../../node_modules/css-loader/dist/cjs.js!./pikaday.css */ \"./node_modules/css-loader/dist/cjs.js!./src/assets/scss/pikaday.css\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../node_modules/css-loader/dist/runtime/getUrl.js */ \"./node_modules/css-loader/dist/runtime/getUrl.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_3__);\n// Imports\n\n\n\n\nvar ___CSS_LOADER_URL_IMPORT_0___ = new URL(/* asset import */ __webpack_require__(/*! ../img/mask-smile.webp */ \"./src/assets/img/mask-smile.webp\"), __webpack_require__.b);\nvar ___CSS_LOADER_URL_IMPORT_1___ = new URL(/* asset import */ __webpack_require__(/*! ../img/mask-neutral.webp */ \"./src/assets/img/mask-neutral.webp\"), __webpack_require__.b);\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n___CSS_LOADER_EXPORT___.push([module.id, \"@import url(https://fonts.googleapis.com/css2?family=Roboto+Flex:ital,wght@0,400;0,600;1,400;1,600&display=swap);\"]);\n___CSS_LOADER_EXPORT___.push([module.id, \"@import url(https://fonts.googleapis.com/icon?family=Material+Icons);\"]);\n___CSS_LOADER_EXPORT___.push([module.id, \"@import url(https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200);\"]);\n___CSS_LOADER_EXPORT___.i(_node_modules_css_loader_dist_cjs_js_pikaday_css__WEBPACK_IMPORTED_MODULE_2__[\"default\"]);\nvar ___CSS_LOADER_URL_REPLACEMENT_0___ = _node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_3___default()(___CSS_LOADER_URL_IMPORT_0___);\nvar ___CSS_LOADER_URL_REPLACEMENT_1___ = _node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_3___default()(___CSS_LOADER_URL_IMPORT_1___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `@charset \"UTF-8\";\n*, ::before, ::after {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgba(59, 130, 246, 0.5);\n --tw-ring-offset-shadow: 0 0 rgba(0,0,0,0);\n --tw-ring-shadow: 0 0 rgba(0,0,0,0);\n --tw-shadow: 0 0 rgba(0,0,0,0);\n --tw-shadow-colored: 0 0 rgba(0,0,0,0);\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n}\n\n::backdrop {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgba(59, 130, 246, 0.5);\n --tw-ring-offset-shadow: 0 0 rgba(0,0,0,0);\n --tw-ring-shadow: 0 0 rgba(0,0,0,0);\n --tw-shadow: 0 0 rgba(0,0,0,0);\n --tw-shadow-colored: 0 0 rgba(0,0,0,0);\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n}\n\n.pw-invisible {\n visibility: hidden;\n}\n\n.\\\\!pw-absolute {\n position: absolute !important;\n}\n\n.pw-absolute {\n position: absolute;\n}\n\n.pw-relative {\n position: relative;\n}\n\n.pw-inset-0 {\n top: 0px;\n right: 0px;\n bottom: 0px;\n left: 0px;\n}\n\n.pw-bottom-0 {\n bottom: 0px;\n}\n\n.pw-bottom-16 {\n bottom: 4rem;\n}\n\n.pw-bottom-\\\\[10\\\\%\\\\] {\n bottom: 10%;\n}\n\n.pw-left-0 {\n left: 0px;\n}\n\n.pw-left-1\\\\/2 {\n left: 50%;\n}\n\n.pw-left-10 {\n left: 2.5rem;\n}\n\n.pw-left-2 {\n left: 0.5rem;\n}\n\n.pw-left-4 {\n left: 1rem;\n}\n\n.pw-left-8 {\n left: 2rem;\n}\n\n.pw-left-\\\\[100\\\\%\\\\] {\n left: 100%;\n}\n\n.pw-right-0 {\n right: 0px;\n}\n\n.pw-right-3 {\n right: 0.75rem;\n}\n\n.pw-right-5 {\n right: 1.25rem;\n}\n\n.pw-top-0 {\n top: 0px;\n}\n\n.pw-top-1 {\n top: 0.25rem;\n}\n\n.pw-top-1\\\\/2 {\n top: 50%;\n}\n\n.pw-top-1\\\\/3 {\n top: 33.333333%;\n}\n\n.pw-top-2\\\\/4 {\n top: 50%;\n}\n\n.pw-top-4 {\n top: 1rem;\n}\n\n.pw-top-\\\\[14px\\\\] {\n top: 14px;\n}\n\n.pw-z-10 {\n z-index: 10;\n}\n\n.pw-z-40 {\n z-index: 40;\n}\n\n.pw-z-50 {\n z-index: 50;\n}\n\n.pw-z-\\\\[2\\\\] {\n z-index: 2;\n}\n\n.pw-z-\\\\[9999\\\\] {\n z-index: 9999;\n}\n\n.pw-order-1 {\n order: 1;\n}\n\n.pw-order-2 {\n order: 2;\n}\n\n.pw-m-0 {\n margin: 0px;\n}\n\n.pw-m-5 {\n margin: 1.25rem;\n}\n\n.pw-mx-0 {\n margin-left: 0px;\n margin-right: 0px;\n}\n\n.pw-mx-5 {\n margin-left: 1.25rem;\n margin-right: 1.25rem;\n}\n\n.pw-mx-auto {\n margin-left: auto;\n margin-right: auto;\n}\n\n.pw-my-4 {\n margin-top: 1rem;\n margin-bottom: 1rem;\n}\n\n.pw-mb-0 {\n margin-bottom: 0px;\n}\n\n.pw-mb-10 {\n margin-bottom: 2.5rem;\n}\n\n.pw-mb-2 {\n margin-bottom: 0.5rem;\n}\n\n.pw-mb-3 {\n margin-bottom: 0.75rem;\n}\n\n.pw-mb-4 {\n margin-bottom: 1rem;\n}\n\n.pw-mb-5 {\n margin-bottom: 1.25rem;\n}\n\n.pw-mb-6 {\n margin-bottom: 1.5rem;\n}\n\n.pw-mb-\\\\[0\\\\.3rem\\\\] {\n margin-bottom: 0.3rem;\n}\n\n.pw-ml-2 {\n margin-left: 0.5rem;\n}\n\n.pw-mr-4 {\n margin-right: 1rem;\n}\n\n.pw-mt-2 {\n margin-top: 0.5rem;\n}\n\n.pw-mt-3 {\n margin-top: 0.75rem;\n}\n\n.pw-mt-4 {\n margin-top: 1rem;\n}\n\n.pw-mt-6 {\n margin-top: 1.5rem;\n}\n\n.pw-box-border {\n box-sizing: border-box;\n}\n\n.pw-block {\n display: block;\n}\n\n.pw-inline-block {\n display: inline-block;\n}\n\n.pw-flex {\n display: flex;\n}\n\n.pw-grid {\n display: grid;\n}\n\n.pw-hidden {\n display: none;\n}\n\n.\\\\!pw-h-px {\n height: 1px !important;\n}\n\n.pw-h-1 {\n height: 0.25rem;\n}\n\n.pw-h-10 {\n height: 2.5rem;\n}\n\n.pw-h-11 {\n height: 2.75rem;\n}\n\n.pw-h-12 {\n height: 3rem;\n}\n\n.pw-h-14 {\n height: 3.5rem;\n}\n\n.pw-h-16 {\n height: 4rem;\n}\n\n.pw-h-3 {\n height: 0.75rem;\n}\n\n.pw-h-\\\\[calc\\\\(100\\\\%-2\\\\*1rem\\\\)\\\\] {\n height: calc(100% - 2rem);\n}\n\n.pw-h-full {\n height: 100%;\n}\n\n.pw-h-screen {\n height: 100vh;\n}\n\n.pw-max-h-80 {\n max-height: 20rem;\n}\n\n.pw-max-h-\\\\[90vh\\\\] {\n max-height: 90vh;\n}\n\n.pw-min-h-0 {\n min-height: 0px;\n}\n\n.pw-min-h-\\\\[256px\\\\] {\n min-height: 256px;\n}\n\n.\\\\!pw-w-px {\n width: 1px !important;\n}\n\n.pw-w-10 {\n width: 2.5rem;\n}\n\n.pw-w-11 {\n width: 2.75rem;\n}\n\n.pw-w-16 {\n width: 4rem;\n}\n\n.pw-w-36 {\n width: 9rem;\n}\n\n.pw-w-6 {\n width: 1.5rem;\n}\n\n.pw-w-\\\\[calc\\\\(100\\\\%-2\\\\*1\\\\.25rem\\\\)\\\\] {\n width: calc(100% - 2.5rem);\n}\n\n.pw-w-\\\\[calc\\\\(100\\\\%-32px\\\\)\\\\] {\n width: calc(100% - 32px);\n}\n\n.pw-w-full {\n width: 100%;\n}\n\n.pw-w-screen {\n width: 100vw;\n}\n\n.pw-max-w-\\\\[1400px\\\\] {\n max-width: 1400px;\n}\n\n.pw-max-w-md {\n max-width: 28rem;\n}\n\n.pw-flex-1 {\n flex: 1 1 0%;\n}\n\n.pw-flex-shrink-0 {\n flex-shrink: 0;\n}\n\n.pw-grow {\n flex-grow: 1;\n}\n\n.-pw-translate-x-1\\\\/2 {\n --tw-translate-x: -50%;\n transform: translate(-50%, var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n\n.-pw-translate-y-1\\\\/2 {\n --tw-translate-y: -50%;\n transform: translate(var(--tw-translate-x), -50%) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n\n.-pw-translate-y-2\\\\/4 {\n --tw-translate-y: -50%;\n transform: translate(var(--tw-translate-x), -50%) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n\n.pw-translate-y-full {\n --tw-translate-y: 100%;\n transform: translate(var(--tw-translate-x), 100%) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n\n@keyframes pw-camera-rotation {\n 0% {\n transform: rotate3d(0, 1, 0, 0deg);\n }\n 100% {\n transform: rotate3d(0, 1, 0, 180deg);\n }\n}\n.pw-animate-camera {\n animation: pw-camera-rotation 1s ease-out 0.5s 1;\n}\n\n@keyframes pw-loading {\n 0% {\n transform: translateX(-100%);\n }\n 50% {\n transform: translateX(0%);\n }\n 100% {\n transform: translateX(100%);\n }\n}\n.pw-animate-loading {\n animation: pw-loading 1.25s linear infinite;\n}\n\n@keyframes pw-spin {\n to {\n transform: rotate(360deg);\n }\n}\n.pw-animate-spin {\n animation: pw-spin 1s linear infinite;\n}\n\n.pw-cursor-pointer {\n cursor: pointer;\n}\n\n.pw-resize-none {\n resize: none;\n}\n\n.pw-list-disc {\n list-style-type: disc;\n}\n\n.pw-grid-cols-1 {\n grid-template-columns: repeat(1, minmax(0, 1fr));\n}\n\n.pw-flex-col {\n flex-direction: column;\n}\n\n.pw-items-start {\n align-items: flex-start;\n}\n\n.pw-items-end {\n align-items: flex-end;\n}\n\n.pw-items-center {\n align-items: center;\n}\n\n.pw-justify-end {\n justify-content: flex-end;\n}\n\n.pw-justify-center {\n justify-content: center;\n}\n\n.pw-justify-between {\n justify-content: space-between;\n}\n\n.pw-gap-1 {\n gap: 0.25rem;\n}\n\n.pw-gap-4 {\n gap: 1rem;\n}\n\n.pw-gap-x-1 {\n -moz-column-gap: 0.25rem;\n column-gap: 0.25rem;\n}\n\n.pw-gap-x-3 {\n -moz-column-gap: 0.75rem;\n column-gap: 0.75rem;\n}\n\n.pw-space-y-1 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: 0.25rem;\n margin-top: calc(0.25rem * (1 - var(--tw-space-y-reverse)));\n margin-top: 0.25rem;\n margin-top: calc(0.25rem * (1 - var(--tw-space-y-reverse)));\n margin-bottom: 0rem;\n margin-bottom: calc(0.25rem * var(--tw-space-y-reverse));\n}\n\n.pw-overflow-auto {\n overflow: auto;\n}\n\n.\\\\!pw-overflow-hidden {\n overflow: hidden !important;\n}\n\n.pw-overflow-hidden {\n overflow: hidden;\n}\n\n.pw-overflow-y-auto {\n overflow-y: auto;\n}\n\n.pw-overflow-x-hidden {\n overflow-x: hidden;\n}\n\n.pw-overflow-y-hidden {\n overflow-y: hidden;\n}\n\n.\\\\!pw-whitespace-nowrap {\n white-space: nowrap !important;\n}\n\n.pw-rounded-2xl {\n border-radius: 1rem;\n}\n\n.pw-rounded-full {\n border-radius: 9999px;\n}\n\n.pw-rounded-lg {\n border-radius: 0.5rem;\n}\n\n.pw-rounded-none {\n border-radius: 0px;\n}\n\n.pw-rounded-xl {\n border-radius: 0.75rem;\n}\n\n.pw-rounded-b-lg {\n border-bottom-right-radius: 0.5rem;\n border-bottom-left-radius: 0.5rem;\n}\n\n.\\\\!pw-border-0 {\n border-width: 0px !important;\n}\n\n.pw-border {\n border-width: 1px;\n}\n\n.pw-border-0 {\n border-width: 0px;\n}\n\n.pw-border-4 {\n border-width: 4px;\n}\n\n.pw-border-b {\n border-bottom-width: 1px;\n}\n\n.pw-border-t-0 {\n border-top-width: 0px;\n}\n\n.pw-border-solid {\n border-style: solid;\n}\n\n.pw-border-none {\n border-style: none;\n}\n\n.pw-border-current {\n border-color: currentColor;\n}\n\n.pw-border-gray-200 {\n --tw-border-opacity: 1;\n border-color: rgb(229, 231, 235);\n border-color: rgba(229, 231, 235, var(--tw-border-opacity));\n}\n\n.pw-border-grey-5 {\n --tw-border-opacity: 1;\n border-color: rgb(201, 201, 201);\n border-color: rgba(201, 201, 201, var(--tw-border-opacity));\n}\n\n.pw-border-red-500 {\n --tw-border-opacity: 1;\n border-color: rgb(239, 68, 68);\n border-color: rgba(239, 68, 68, var(--tw-border-opacity));\n}\n\n.pw-border-white {\n --tw-border-opacity: 1;\n border-color: rgb(255, 255, 255);\n border-color: rgba(255, 255, 255, var(--tw-border-opacity));\n}\n\n.pw-border-r-transparent {\n border-right-color: transparent;\n}\n\n.pw-bg-black {\n --tw-bg-opacity: 1;\n background-color: rgb(0, 0, 0);\n background-color: rgba(0, 0, 0, var(--tw-bg-opacity));\n}\n\n.pw-bg-grey-10 {\n --tw-bg-opacity: 1;\n background-color: rgb(29, 30, 34);\n background-color: rgba(29, 30, 34, var(--tw-bg-opacity));\n}\n\n.pw-bg-grey-2 {\n --tw-bg-opacity: 1;\n background-color: rgb(250, 250, 252);\n background-color: rgba(250, 250, 252, var(--tw-bg-opacity));\n}\n\n.pw-bg-grey-3 {\n --tw-bg-opacity: 1;\n background-color: rgb(247, 247, 250);\n background-color: rgba(247, 247, 250, var(--tw-bg-opacity));\n}\n\n.pw-bg-grey-4 {\n --tw-bg-opacity: 1;\n background-color: rgb(231, 231, 236);\n background-color: rgba(231, 231, 236, var(--tw-bg-opacity));\n}\n\n.pw-bg-grey-6 {\n --tw-bg-opacity: 1;\n background-color: rgb(158, 158, 158);\n background-color: rgba(158, 158, 158, var(--tw-bg-opacity));\n}\n\n.pw-bg-primary {\n --tw-bg-opacity: 1;\n background-color: rgb(210, 28, 62);\n background-color: rgba(210, 28, 62, var(--tw-bg-opacity));\n}\n\n.pw-bg-white {\n --tw-bg-opacity: 1;\n background-color: rgb(255, 255, 255);\n background-color: rgba(255, 255, 255, var(--tw-bg-opacity));\n}\n\n.pw-bg-opacity-20 {\n --tw-bg-opacity: 0.2;\n}\n\n.pw-bg-opacity-70 {\n --tw-bg-opacity: 0.7;\n}\n\n.pw-bg-opacity-90 {\n --tw-bg-opacity: 0.9;\n}\n\n.pw-bg-gradient-to-r {\n background-image: linear-gradient(to right, var(--tw-gradient-stops));\n}\n\n.pw-from-\\\\[\\\\#D21C3E\\\\] {\n --tw-gradient-from: #D21C3E var(--tw-gradient-from-position);\n --tw-gradient-to: rgba(210, 28, 62, 0) var(--tw-gradient-to-position);\n --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);\n}\n\n.pw-to-\\\\[\\\\#D03C58\\\\] {\n --tw-gradient-to: #D03C58 var(--tw-gradient-to-position);\n}\n\n.\\\\!pw-p-0 {\n padding: 0px !important;\n}\n\n.pw-p-0 {\n padding: 0px;\n}\n\n.pw-p-3 {\n padding: 0.75rem;\n}\n\n.pw-p-4 {\n padding: 1rem;\n}\n\n.pw-p-5 {\n padding: 1.25rem;\n}\n\n.pw-p-6 {\n padding: 1.5rem;\n}\n\n.pw-p-\\\\[30px\\\\] {\n padding: 30px;\n}\n\n.pw-px-0 {\n padding-left: 0px;\n padding-right: 0px;\n}\n\n.pw-px-2 {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n\n.pw-px-3 {\n padding-left: 0.75rem;\n padding-right: 0.75rem;\n}\n\n.pw-px-4 {\n padding-left: 1rem;\n padding-right: 1rem;\n}\n\n.pw-px-5 {\n padding-left: 1.25rem;\n padding-right: 1.25rem;\n}\n\n.pw-px-6 {\n padding-left: 1.5rem;\n padding-right: 1.5rem;\n}\n\n.pw-py-1 {\n padding-top: 0.25rem;\n padding-bottom: 0.25rem;\n}\n\n.pw-py-2 {\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n\n.pw-py-3 {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n}\n\n.pw-py-4 {\n padding-top: 1rem;\n padding-bottom: 1rem;\n}\n\n.pw-py-6 {\n padding-top: 1.5rem;\n padding-bottom: 1.5rem;\n}\n\n.pw-pb-2 {\n padding-bottom: 0.5rem;\n}\n\n.pw-pb-3 {\n padding-bottom: 0.75rem;\n}\n\n.pw-pb-4 {\n padding-bottom: 1rem;\n}\n\n.pw-pl-10 {\n padding-left: 2.5rem;\n}\n\n.pw-pl-5 {\n padding-left: 1.25rem;\n}\n\n.pw-pl-8 {\n padding-left: 2rem;\n}\n\n.pw-pr-2 {\n padding-right: 0.5rem;\n}\n\n.pw-pt-0 {\n padding-top: 0px;\n}\n\n.pw-pt-0\\\\.5 {\n padding-top: 0.125rem;\n}\n\n.pw-pt-1 {\n padding-top: 0.25rem;\n}\n\n.pw-pt-3 {\n padding-top: 0.75rem;\n}\n\n.pw-pt-4 {\n padding-top: 1rem;\n}\n\n.pw-pt-6 {\n padding-top: 1.5rem;\n}\n\n.pw-pt-8 {\n padding-top: 2rem;\n}\n\n.pw-pt-\\\\[14px\\\\] {\n padding-top: 14px;\n}\n\n.pw-pt-\\\\[22px\\\\] {\n padding-top: 22px;\n}\n\n.pw-text-left {\n text-align: left;\n}\n\n.pw-text-center {\n text-align: center;\n}\n\n.pw-text-right {\n text-align: right;\n}\n\n.pw-align-\\\\[-0\\\\.125em\\\\] {\n vertical-align: -0.125em;\n}\n\n.pw-font-\\\\[\\\\'Roboto_Flex\\\\'\\\\] {\n font-family: \"Roboto Flex\";\n}\n\n.pw-font-pw {\n font-family: Roboto Flex;\n}\n\n.pw-text-2xl {\n font-size: 1.5rem;\n line-height: 2rem;\n}\n\n.pw-text-4xl {\n font-size: 2.25rem;\n line-height: 2.5rem;\n}\n\n.pw-text-6xl {\n font-size: 3.75rem;\n line-height: 1;\n}\n\n.pw-text-lg {\n font-size: 1.125rem;\n line-height: 1.75rem;\n}\n\n.pw-text-sm {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n\n.pw-text-xl {\n font-size: 1.25rem;\n line-height: 1.75rem;\n}\n\n.pw-text-xs {\n font-size: 0.75rem;\n line-height: 1rem;\n}\n\n.pw-font-bold {\n font-weight: 700;\n}\n\n.pw-font-medium {\n font-weight: 500;\n}\n\n.pw-text-black {\n --tw-text-opacity: 1;\n color: rgb(0, 0, 0);\n color: rgba(0, 0, 0, var(--tw-text-opacity));\n}\n\n.pw-text-gray-400 {\n --tw-text-opacity: 1;\n color: rgb(156, 163, 175);\n color: rgba(156, 163, 175, var(--tw-text-opacity));\n}\n\n.pw-text-green-500 {\n --tw-text-opacity: 1;\n color: rgb(34, 197, 94);\n color: rgba(34, 197, 94, var(--tw-text-opacity));\n}\n\n.pw-text-grey-10 {\n --tw-text-opacity: 1;\n color: rgb(29, 30, 34);\n color: rgba(29, 30, 34, var(--tw-text-opacity));\n}\n\n.pw-text-grey-2 {\n --tw-text-opacity: 1;\n color: rgb(250, 250, 252);\n color: rgba(250, 250, 252, var(--tw-text-opacity));\n}\n\n.pw-text-grey-5 {\n --tw-text-opacity: 1;\n color: rgb(201, 201, 201);\n color: rgba(201, 201, 201, var(--tw-text-opacity));\n}\n\n.pw-text-grey-6 {\n --tw-text-opacity: 1;\n color: rgb(158, 158, 158);\n color: rgba(158, 158, 158, var(--tw-text-opacity));\n}\n\n.pw-text-grey-7 {\n --tw-text-opacity: 1;\n color: rgb(117, 117, 117);\n color: rgba(117, 117, 117, var(--tw-text-opacity));\n}\n\n.pw-text-info {\n --tw-text-opacity: 1;\n color: rgb(81, 139, 255);\n color: rgba(81, 139, 255, var(--tw-text-opacity));\n}\n\n.pw-text-orange-400 {\n --tw-text-opacity: 1;\n color: rgb(251, 146, 60);\n color: rgba(251, 146, 60, var(--tw-text-opacity));\n}\n\n.pw-text-red-500 {\n --tw-text-opacity: 1;\n color: rgb(239, 68, 68);\n color: rgba(239, 68, 68, var(--tw-text-opacity));\n}\n\n.pw-text-secondary {\n --tw-text-opacity: 1;\n color: rgb(117, 117, 117);\n color: rgba(117, 117, 117, var(--tw-text-opacity));\n}\n\n.pw-text-white {\n --tw-text-opacity: 1;\n color: rgb(255, 255, 255);\n color: rgba(255, 255, 255, var(--tw-text-opacity));\n}\n\n.pw-shadow-button-shadow {\n --tw-shadow: 0px 3px 5px 0px rgba(115,115,123,0.30196);\n --tw-shadow-colored: 0px 3px 5px 0px var(--tw-shadow-color);\n box-shadow: 0 0 rgba(0, 0, 0, 0), 0 0 rgba(0, 0, 0, 0), 0px 3px 5px 0px rgba(115, 115, 123, 0.30196);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 rgba(0, 0, 0, 0)), var(--tw-ring-shadow, 0 0 rgba(0, 0, 0, 0)), var(--tw-shadow);\n}\n\n.pw-shadow-lg {\n --tw-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);\n --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);\n box-shadow: 0 0 rgba(0, 0, 0, 0), 0 0 rgba(0, 0, 0, 0), 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 rgba(0, 0, 0, 0)), var(--tw-ring-shadow, 0 0 rgba(0, 0, 0, 0)), var(--tw-shadow);\n}\n\n.pw-outline-none {\n outline: 2px solid transparent;\n outline-offset: 2px;\n}\n\n.pw-outline-dashed {\n outline-style: dashed;\n}\n\n.pw-outline-grey-5 {\n outline-color: #C9C9C9;\n}\n\n.pw-outline-grey-6 {\n outline-color: #9E9E9E;\n}\n\n.pw-transition-all {\n transition-property: all;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n\n.pw-duration-100 {\n transition-duration: 100ms;\n}\n\n.pw-duration-200 {\n transition-duration: 200ms;\n}\n\n.pw-duration-500 {\n transition-duration: 500ms;\n}\n\n/* Ensure full-screen camera on all devices */\n.camera-bg {\n height: 100%;\n width: 100%;\n}\n\n/* Responsive container adjustments */\n.pwsdk-ui {\n transition-property: all;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 300ms;\n}\n\n/* Desktop-specific adjustments */\n@media (min-width: 768px) {\n .pwsdk-ui {\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);\n }\n}\n.\\\\!\\\\[clip\\\\:pw-rect\\\\(0\\\\,0\\\\,0\\\\,0\\\\)\\\\] {\n clip: pw-rect(0, 0, 0, 0) !important;\n}\n\n.pw-bg-disabled,\ninput:disabled {\n background: #f0f0f5;\n}\n\n.pw-watermark {\n position: absolute;\n transform: rotate(-25deg);\n opacity: 0.5;\n font-weight: 500;\n font-size: 20px;\n text-transform: capitalize;\n color: #9e9e9e;\n white-space: nowrap;\n overflow: hidden;\n -webkit-text-stroke-width: 0.3px;\n -webkit-text-stroke-color: #1d1e22;\n}\n\n.pw-drag-drop.highlight {\n outline-color: #d21c3e;\n}\n\n/* Chrome, Safari, Edge, Opera */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n -webkit-appearance: none;\n margin: 0;\n}\n\n/* Firefox */\ninput[type=number] {\n -moz-appearance: textfield;\n}\n\n.camera-bg {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 2;\n margin: 0;\n height: 100%;\n width: 100%;\n background-color: black;\n}\n.camera-bg-color {\n background-color: black;\n}\n.camera-header-area {\n position: absolute;\n text-align: center;\n z-index: 2;\n top: 5%;\n width: 100%;\n}\n.camera-header-area .title {\n color: white;\n}\n.camera-body-area {\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n flex-direction: column;\n}\n.camera-body-area .video-container {\n z-index: -1;\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100vw;\n height: 100vh;\n /* overflow:hidden removed — video is already sized to its native ratio so\n nothing overflows, and the description text above the overlay must not\n be clipped when it extends beyond the container top */\n}\n.camera-body-area .video-element {\n object-fit: cover;\n width: 100%;\n height: 100%;\n}\n.camera-body-area .canvas-element {\n position: absolute;\n z-index: 9;\n}\n.camera-body-area .overlay-container {\n position: absolute;\n margin: auto;\n z-index: 1;\n}\n.camera-body-area .overlay-element {\n position: relative;\n background-position: center center;\n background-repeat: no-repeat;\n background-size: cover;\n box-shadow: 0 0 150px 0 rgba(255, 255, 255, 0.3), 0 0 0 9999px rgb(34, 34, 34);\n}\n@media (max-width: 767px) {\n .camera-body-area .overlay-element {\n box-shadow: 0 0 250px 0 rgba(255, 255, 255, 0.3), 0 0 0 9999px rgb(34, 34, 34);\n }\n}\n.camera-body-area .border-element {\n position: absolute;\n width: 100%;\n height: 100%;\n}\n.camera-body-area .border-id-element:before,\n.camera-body-area .border-id-element:after {\n top: -2px;\n left: -2px;\n position: absolute;\n content: \"\";\n width: 100%;\n height: calc(100% + 50px);\n border-radius: 16px;\n border: 2px solid white;\n}\n.camera-body-area .outlide-id-bottom {\n position: absolute;\n top: 100%;\n width: 100%;\n background-color: white;\n height: 50px;\n display: flex;\n justify-content: center;\n align-items: center;\n border-bottom-left-radius: 8px;\n border-bottom-right-radius: 8px;\n}\n.camera-body-area .border-top-element:before,\n.camera-body-area .border-top-element:after,\n.camera-body-area .border-bottom-element:before,\n.camera-body-area .border-bottom-element:after {\n position: absolute;\n content: \"\";\n width: 10%;\n height: 15%;\n border-color: white;\n border-style: solid;\n}\n.camera-body-area .border-top-element:before {\n top: -2px;\n left: -2px;\n border-width: 4px 0 0 4px;\n border-top-left-radius: 15px;\n}\n.camera-body-area .border-top-element:after {\n top: -2px;\n right: -2px;\n border-width: 4px 4px 0 0;\n border-top-right-radius: 15px;\n}\n.camera-body-area .border-bottom-element:before {\n bottom: -2px;\n right: -2px;\n border-width: 0 4px 4px 0;\n border-bottom-right-radius: 15px;\n}\n.camera-body-area .border-bottom-element:after {\n bottom: -2px;\n left: -2px;\n border-width: 0 0 4px 4px;\n border-bottom-left-radius: 15px;\n}\n.camera-body-area .overlay-element--active {\n border-color: #8ede34 !important;\n}\n.camera-body-area .overlay-element--selfie-smile {\n background-size: contain;\n background-position: center center;\n background-image: url(${___CSS_LOADER_URL_REPLACEMENT_0___});\n}\n.camera-body-area .overlay-element--selfie-neutral {\n background-size: contain;\n background-position: center center;\n background-image: url(${___CSS_LOADER_URL_REPLACEMENT_1___});\n}\n.camera-footer-area {\n position: absolute;\n text-align: center;\n z-index: 2;\n bottom: 10%;\n width: 100%;\n}\n.camera-footer-area .instruction {\n color: white;\n}\n\n/* Responsive utilities */\n.hover\\\\:pw-bg-grey-3:hover {\n --tw-bg-opacity: 1;\n background-color: rgb(247, 247, 250);\n background-color: rgba(247, 247, 250, var(--tw-bg-opacity));\n}\n\n.active\\\\:pw-scale-90:active {\n --tw-scale-x: .9;\n --tw-scale-y: .9;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(0.9) scaleY(0.9);\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n\n.pw-peer:-moz-placeholder-shown ~ .peer-placeholder-shown\\\\:pw-visible {\n visibility: visible;\n}\n\n.pw-peer:placeholder-shown ~ .peer-placeholder-shown\\\\:pw-visible {\n visibility: visible;\n}\n\n.pw-peer:-moz-placeholder-shown ~ .peer-placeholder-shown\\\\:pw-top-\\\\[30px\\\\] {\n top: 30px;\n}\n\n.pw-peer:placeholder-shown ~ .peer-placeholder-shown\\\\:pw-top-\\\\[30px\\\\] {\n top: 30px;\n}\n\n.pw-peer:-moz-placeholder-shown ~ .peer-placeholder-shown\\\\:-pw-translate-y-2\\\\/4 {\n --tw-translate-y: -50%;\n transform: translate(var(--tw-translate-x), -50%) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n\n.pw-peer:placeholder-shown ~ .peer-placeholder-shown\\\\:-pw-translate-y-2\\\\/4 {\n --tw-translate-y: -50%;\n transform: translate(var(--tw-translate-x), -50%) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n\n.pw-peer:-moz-placeholder-shown ~ .peer-placeholder-shown\\\\:pw-text-sm {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n\n.pw-peer:placeholder-shown ~ .peer-placeholder-shown\\\\:pw-text-sm {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n\n.pw-peer:focus ~ .peer-focus\\\\:pw-invisible {\n visibility: hidden;\n}\n\n.pw-peer:focus ~ .peer-focus\\\\:pw-top-\\\\[14px\\\\] {\n top: 14px;\n}\n\n.pw-peer:focus ~ .peer-focus\\\\:pw-text-xs {\n font-size: 0.75rem;\n line-height: 1rem;\n}\n\n@media (min-width: 768px) {\n .pw-md\\\\:pw-order-1 {\n order: 1;\n }\n .pw-md\\\\:pw-order-2 {\n order: 2;\n }\n .pw-md\\\\:pw-mb-6 {\n margin-bottom: 1.5rem;\n }\n .pw-md\\\\:pw-w-auto {\n width: auto;\n }\n .pw-md\\\\:pw-max-w-\\\\[300px\\\\] {\n max-width: 300px;\n }\n .pw-md\\\\:pw-max-w-\\\\[480px\\\\] {\n max-width: 480px;\n }\n .pw-md\\\\:pw-grid-cols-2 {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n }\n .pw-md\\\\:pw-gap-6 {\n gap: 1.5rem;\n }\n .pw-md\\\\:pw-rounded-2xl {\n border-radius: 1rem;\n }\n .pw-md\\\\:pw-border {\n border-width: 1px;\n }\n .pw-md\\\\:pw-border-grey-5 {\n --tw-border-opacity: 1;\n border-color: rgb(201, 201, 201);\n border-color: rgba(201, 201, 201, var(--tw-border-opacity));\n }\n}`, \"\"]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://PWUISDK/./src/assets/scss/index.scss?./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./node_modules/postcss-loader/dist/cjs.js");
|
|
30
30
|
|
|
31
31
|
/***/ }),
|
|
32
32
|
|
|
@@ -4000,7 +4000,7 @@ eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _argument
|
|
|
4000
4000
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
4001
4001
|
|
|
4002
4002
|
"use strict";
|
|
4003
|
-
eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst card_detection_1 = __importDefault(__webpack_require__(/*! ./card-detection */ \"./src/plugins/card-detection.ts\"));\nconst translations_1 = __webpack_require__(/*! ../translations */ \"./src/translations/index.ts\");\nconst deviceDetection_1 = __webpack_require__(/*! ../helper/deviceDetection */ \"./src/helper/deviceDetection.ts\");\nconst camera_1 = __webpack_require__(/*! ../models/camera */ \"./src/models/camera.ts\");\nconst camera_instruction_1 = __webpack_require__(/*! ../constant/camera-instruction */ \"./src/constant/camera-instruction.ts\");\nconst baseDialog_1 = __importDefault(__webpack_require__(/*! ../components/baseDialog */ \"./src/components/baseDialog.ts\"));\nconst components_1 = __webpack_require__(/*! ../components/components */ \"./src/components/components.ts\");\nconst navigationBar_1 = __importDefault(__webpack_require__(/*! ../components/navigationBar */ \"./src/components/navigationBar.ts\"));\nconst cameraViewport_1 = __importDefault(__webpack_require__(/*! ../components/cameraViewport */ \"./src/components/cameraViewport.ts\"));\nconst footer_1 = __importDefault(__webpack_require__(/*! ../components/footer */ \"./src/components/footer.ts\"));\nconst MainPage_1 = __webpack_require__(/*! ../classes/MainPage */ \"./src/classes/MainPage.ts\");\nconst imagesHelper_1 = __webpack_require__(/*! ../helper/imagesHelper */ \"./src/helper/imagesHelper.ts\");\nclass CardCamera {\n constructor(cameraId, cardType, mainScreenId = \"\") {\n this.cameraTimeLimit = 90000;\n this._onWindowResize = () => { this.resizeElement(); };\n this._onBeforeUnload = () => { this._cleanup(); };\n this.videoElement = null;\n this.canvasElement = null;\n this.overlayElement = null;\n this.titleElement = null;\n this.footerElement = null;\n this.cameraId = cameraId;\n this.cardType = cardType;\n this.mainScreenId = mainScreenId;\n }\n isMobile() {\n // Use extracted helper function\n return (0, deviceDetection_1.isMobileDevice)();\n }\n captureImage() {\n var _a, _b, _c, _d, _e, _f, _g;\n return __awaiter(this, void 0, void 0, function* () {\n const bitmap = this.videoElement;\n // 1. full image\n let canvas = document.createElement(\"canvas\");\n let context = canvas.getContext(\"2d\");\n canvas.width = bitmap.videoWidth;\n canvas.height = bitmap.videoHeight;\n context.drawImage(bitmap, 0, 0, bitmap.videoWidth, bitmap.videoHeight);\n // 2. cropped image — region corresponds exactly to what the overlay shows\n let cropCanvas = document.createElement(\"canvas\");\n let cropContext = cropCanvas.getContext(\"2d\");\n cropCanvas.width = bitmap.videoWidth;\n cropCanvas.height = bitmap.videoHeight;\n cropContext.drawImage(bitmap, 0, 0, bitmap.videoWidth, bitmap.videoHeight);\n // Scale factor: stream pixels per display pixel\n const scaleX = bitmap.videoWidth / ((_b = (_a = this.videoElement) === null || _a === void 0 ? void 0 : _a.clientWidth) !== null && _b !== void 0 ? _b : bitmap.videoWidth);\n const scaleY = bitmap.videoHeight / ((_d = (_c = this.videoElement) === null || _c === void 0 ? void 0 : _c.clientHeight) !== null && _d !== void 0 ? _d : bitmap.videoHeight);\n // Use overlay's actual on-screen position as the crop region\n const overlayRect = (_e = this.overlayElement) === null || _e === void 0 ? void 0 : _e.getBoundingClientRect();\n const videoRect = (_f = this.videoElement) === null || _f === void 0 ? void 0 : _f.getBoundingClientRect();\n let cropX, cropY, cropW, cropH;\n if (overlayRect && videoRect) {\n cropX = Math.round((overlayRect.left - videoRect.left) * scaleX);\n cropY = Math.round((overlayRect.top - videoRect.top) * scaleY);\n cropW = Math.round(overlayRect.width * scaleX);\n cropH = Math.round(overlayRect.height * scaleY);\n }\n else {\n // Fallback: derive from calculateHeightNWidth + manual scale\n const { width, height } = this.cardDetectionSdk.calculateHeightNWidth(bitmap.videoWidth, bitmap.videoHeight);\n cropW = Math.round(width * scaleX);\n cropH = Math.round(height * scaleY);\n cropX = Math.round((bitmap.videoWidth - cropW) / 2);\n cropY = Math.round((bitmap.videoHeight - cropH) / 2);\n }\n // Clamp to stream bounds\n cropX = Math.max(0, cropX);\n cropY = Math.max(0, cropY);\n cropW = Math.min(cropW, bitmap.videoWidth - cropX);\n cropH = Math.min(cropH, bitmap.videoHeight - cropY);\n // crop the selected part image (viewport frame region)\n const imgData = cropContext.getImageData(cropX, cropY, cropW, cropH);\n cropCanvas.width = cropW;\n cropCanvas.height = cropH;\n cropContext.putImageData(imgData, 0, 0);\n // Determine card type prefix for file naming\n const cardTypePrefix = this.cardType === camera_1.CARD_TYPES.ID ? 'id-front' :\n this.cardType === camera_1.CARD_TYPES.ID_BACK ? 'id-back' :\n this.cardType === camera_1.CARD_TYPES.LICENSE ? 'license-front' :\n this.cardType === camera_1.CARD_TYPES.LICENSE_BACK ? 'license-back' :\n this.cardType === camera_1.CARD_TYPES.PASSPORT ? 'passport' :\n this.cardType === camera_1.CARD_TYPES.CC ? 'cc-front' : 'cc-back';\n // TEMP: Download BEFORE resize for comparison (only if debug enabled)\n if (MainPage_1.enableImageDebug) {\n const beforeResizeFullCanvas = canvas.cloneNode();\n const beforeResizeFullCtx = beforeResizeFullCanvas.getContext(\"2d\");\n beforeResizeFullCanvas.width = canvas.width;\n beforeResizeFullCanvas.height = canvas.height;\n beforeResizeFullCtx.drawImage(canvas, 0, 0);\n const beforeResizeCropCanvas = cropCanvas.cloneNode();\n const beforeResizeCropCtx = beforeResizeCropCanvas.getContext(\"2d\");\n beforeResizeCropCanvas.width = cropCanvas.width;\n beforeResizeCropCanvas.height = cropCanvas.height;\n beforeResizeCropCtx.drawImage(cropCanvas, 0, 0);\n console.log(`[DEBUG] ${cardTypePrefix} BEFORE resize - Full: ${beforeResizeFullCanvas.width}x${beforeResizeFullCanvas.height}, Cropped: ${beforeResizeCropCanvas.width}x${beforeResizeCropCanvas.height}`);\n this.downloadImage(beforeResizeFullCanvas.toDataURL(\"image/jpeg\"), `${cardTypePrefix}-full-BEFORE-${beforeResizeFullCanvas.width}x${beforeResizeFullCanvas.height}.jpg`);\n this.downloadImage(beforeResizeCropCanvas.toDataURL(\"image/jpeg\"), `${cardTypePrefix}-cropped-BEFORE-${beforeResizeCropCanvas.width}x${beforeResizeCropCanvas.height}.jpg`);\n }\n // 3. resize the canvas\n try {\n canvas = (0, imagesHelper_1.resizeCanvas)(canvas, imagesHelper_1.maxFullImage.width, imagesHelper_1.maxFullImage.height);\n cropCanvas = (0, imagesHelper_1.resizeCanvas)(cropCanvas, imagesHelper_1.maxCroppedImage.width, imagesHelper_1.maxCroppedImage.height);\n }\n catch (err) {\n console.error(\"doc resize image error\", err);\n }\n // 4. construct payload - convert to desired file format\n const { width: displayWidth = \"\", height: displayHeight = \"\" } = ((_g = this.overlayElement) === null || _g === void 0 ? void 0 : _g.style) || {};\n const payload = {\n fullImage: canvas.toDataURL(\"image/jpeg\"),\n croppedImage: cropCanvas.toDataURL(\"image/jpeg\"),\n displaySize: {\n width: Number(displayWidth.replace(\"px\", \"\")),\n height: Number(displayHeight.replace(\"px\", \"\")),\n },\n };\n // TEMP: Download AFTER resize for comparison (only if debug enabled)\n if (MainPage_1.enableImageDebug) {\n console.log(`[DEBUG] ${cardTypePrefix} AFTER resize - Full: ${canvas.width}x${canvas.height}, Cropped: ${cropCanvas.width}x${cropCanvas.height}`);\n if (payload.fullImage)\n this.downloadImage(payload.fullImage, `${cardTypePrefix}-full-AFTER-${canvas.width}x${canvas.height}.jpg`);\n if (payload.croppedImage)\n this.downloadImage(payload.croppedImage, `${cardTypePrefix}-cropped-AFTER-${cropCanvas.width}x${cropCanvas.height}.jpg`);\n }\n return payload;\n });\n }\n // TEMP: Helper method to download image\n downloadImage(dataUrl, filename) {\n const link = document.createElement(\"a\");\n link.href = dataUrl;\n link.download = filename;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n }\n init() {\n try {\n // show loading spinner in full pg\n (0, components_1.createFullLoading)(this.cameraId, \"Initializing Camera...\");\n // 1. Draw the camera display\n this.drawCameraDisplay();\n // 2. Setup related SDK\n const { videoElement, canvasElement, overlayElement, titleElement } = this;\n this.cardDetectionSdk = new card_detection_1.default({\n videoElement,\n canvasElement,\n overlayElement,\n titleElement,\n });\n // 3. Get the camera permission and trigger the card detection\n this.cameraInit();\n // 4. Start timer to close camera\n this.timer = setTimeout(() => {\n this.stopVideoStream();\n // open idle dialog\n const idleDialog = new baseDialog_1.default();\n idleDialog.render(this.mainScreenId, (0, translations_1.$t)(\"idle_message\"), (0, translations_1.$t)(\"btn_okay\"));\n }, this.cameraTimeLimit);\n }\n finally {\n // hide loading spinner in full pg\n (0, components_1.hideFullLoading)(this.cameraId);\n }\n }\n drawCameraDisplay() {\n // 1. header section\n const header = document.createElement(\"div\");\n header.id = camera_1.ELEMENT_IDS.HEADER;\n // header.classList.add(\"camera-header-area\");\n header.classList.add(\"pw-absolute\", \"pw-z-[2]\", \"pw-w-full\", \"pw-text-white\");\n const navigationDiv = new navigationBar_1.default().render(() => {\n this.stopVideoStream();\n });\n header.appendChild(navigationDiv);\n const body = document.createElement(\"div\");\n body.id = camera_1.ELEMENT_IDS.BODY;\n body.classList.add(\"camera-body-area\");\n const videoContainer = document.createElement(\"div\");\n videoContainer.id = camera_1.ELEMENT_IDS.VIDEO_CONTAINER;\n videoContainer.classList.add(\"video-container\");\n const overlayContainer = document.createElement(\"div\");\n overlayContainer.id = camera_1.ELEMENT_IDS.OVERLAY_CONTAINER;\n overlayContainer.classList.add(\"overlay-container\");\n // Use CameraViewport component for consistent viewport design\n const cameraViewport = new cameraViewport_1.default(this.cardType);\n const overlayElement = cameraViewport.render();\n overlayElement.classList.add(\"pw-relative\");\n // Container for title and description - positioned above the overlay\n const headerContainer = document.createElement(\"div\");\n headerContainer.classList.add(\"pw-absolute\");\n headerContainer.style.zIndex = \"1\";\n headerContainer.style.left = \"50%\";\n headerContainer.style.bottom = \"100%\";\n headerContainer.style.transform = \"translate(-50%, -20px)\";\n headerContainer.style.width = \"calc(100vw - 48px)\";\n headerContainer.style.maxWidth = \"1400px\";\n // Set Title\n const titleDiv = document.createElement(\"div\");\n titleDiv.id = \"pw-camera-title\";\n titleDiv.classList.add(\"pw-text-2xl\", \"pw-text-center\", \"pw-text-white\", \"pw-mb-4\");\n titleDiv.innerHTML = camera_instruction_1.CAMERA_INSTRUCTION[this.cardType].title;\n this.titleElement = titleDiv;\n headerContainer.appendChild(titleDiv);\n // Set Description\n const descriptionDiv = document.createElement(\"div\");\n descriptionDiv.classList.add(\"pw-text-center\", \"pw-px-5\", \"pw-text-xl\", \"pw-text-white\");\n descriptionDiv.innerHTML = camera_instruction_1.CAMERA_INSTRUCTION[this.cardType].description;\n headerContainer.appendChild(descriptionDiv);\n overlayElement.appendChild(headerContainer);\n const canvasElement = document.createElement(\"canvas\");\n canvasElement.id = camera_1.ELEMENT_IDS.CANVAS;\n canvasElement.classList.add(\"video-element\");\n canvasElement.classList.add(\"canvas-element\");\n // Mirror canvas to match video when not on mobile device (desktop/laptop)\n if (!(0, deviceDetection_1.isMobileDevice)()) {\n canvasElement.style.transform = \"scaleX(-1)\";\n }\n const videoElement = document.createElement(\"video\");\n videoElement.id = camera_1.ELEMENT_IDS.VIDEO;\n videoElement.autoplay = true;\n videoElement.playsInline = true;\n videoElement.preload = \"auto\";\n videoElement.loop = true;\n videoElement.classList.add(\"video-element\");\n // Mirror horizontally when not on mobile device (desktop/laptop front camera UX)\n if (!(0, deviceDetection_1.isMobileDevice)()) {\n videoElement.style.transform = \"scaleX(-1)\";\n }\n // 2.1\n this.videoElement = videoElement;\n this.overlayElement = overlayElement;\n this.canvasElement = canvasElement;\n overlayContainer.appendChild(overlayElement);\n videoContainer.appendChild(overlayContainer);\n videoContainer.appendChild(canvasElement);\n videoContainer.appendChild(videoElement);\n body.appendChild(videoContainer);\n // 3. append child\n const mainBody = document.getElementById(this.cameraId);\n if (!mainBody)\n return;\n mainBody.classList.add(\"camera-bg\", \"pw-overflow-y-hidden\");\n mainBody.appendChild(header);\n mainBody.appendChild(body);\n }\n listenToCardCapture(cb) {\n const cameraBody = document.getElementById(this.cameraId);\n cameraBody === null || cameraBody === void 0 ? void 0 : cameraBody.addEventListener(\"captureImage\", (e) => {\n cb(e);\n });\n }\n // here also is where the take picture button resides\n renderCameraBottomUi() {\n const footer = document.createElement(\"div\");\n footer.id = camera_1.ELEMENT_IDS.FOOTER;\n footer.classList.add(\"pw-absolute\", \"pw-bottom-[10%]\", \"pw-z-[2]\", \"pw-w-full\", \"pw-text-white\", \"pw-relative\");\n const takePicButton = document.createElement(\"div\");\n takePicButton.id = \"takePicButton\";\n takePicButton.classList.add(\"pw-box-border\", \"pw-mx-auto\", \"pw-absolute\", \"pw-bottom-16\", \"pw-relative\", \"pw-rounded-full\", \"pw-h-16\", \"pw-w-16\", \"pw-border-solid\", \"pw-border-white\", \"pw-border-4\", \"pw-cursor-pointer\", \"pw-opacity-40\", \"pw-pointer-events-none\");\n const smallCircleContainer = document.createElement(\"div\");\n smallCircleContainer.classList.add(\"pw-absolute\", \"pw-top-1/2\", \"-pw-translate-y-1/2\", \"pw-left-1/2\", \"-pw-translate-x-1/2\");\n takePicButton.appendChild(smallCircleContainer);\n const smallCircle = document.createElement(\"div\");\n smallCircle.classList.add(\"pw-w-11\", \"pw-h-11\", \"pw-bg-white\", \"pw-rounded-full\", \"pw-transition-all\", \"pw-duration-100\", \"active:pw-scale-90\");\n smallCircleContainer.appendChild(smallCircle);\n footer.appendChild(takePicButton);\n takePicButton.addEventListener(\"click\", () => __awaiter(this, void 0, void 0, function* () {\n const mainBody = document.getElementById(this.cameraId);\n const image = yield this.captureImage();\n const event = new CustomEvent(\"captureImage\", {\n detail: {\n image,\n type: this.cardType,\n },\n });\n mainBody === null || mainBody === void 0 ? void 0 : mainBody.dispatchEvent(event);\n }));\n const mainBody = document.getElementById(this.cameraId);\n this.footerElement = footer;\n mainBody === null || mainBody === void 0 ? void 0 : mainBody.appendChild(footer);\n // Powered by pipwave at bottom of viewport\n const poweredByWrapper = document.createElement(\"div\");\n poweredByWrapper.classList.add(\"pw-absolute\", \"pw-bottom-0\", \"pw-left-0\", \"pw-right-0\", \"pw-pb-4\", \"pw-z-[2]\", \"pw-flex\", \"pw-justify-center\", \"pw-items-center\", \"pw-text-white\");\n const poweredByFooter = new footer_1.default().render(true);\n poweredByWrapper.appendChild(poweredByFooter);\n mainBody === null || mainBody === void 0 ? void 0 : mainBody.appendChild(poweredByWrapper);\n }\n pauseVideoStream() {\n var _a;\n return __awaiter(this, void 0, void 0, function* () {\n this.cardDetectionSdk.stopDetectionLoop();\n // stop the video\n (_a = this.videoElement) === null || _a === void 0 ? void 0 : _a.pause();\n // stop idle timeout\n if (this.timer) {\n clearTimeout(this.timer);\n }\n });\n }\n resumeVideoStream(cardType) {\n var _a;\n return __awaiter(this, void 0, void 0, function* () {\n this.updateType(cardType);\n // resume the video\n (_a = this.videoElement) === null || _a === void 0 ? void 0 : _a.play();\n this.cardDetectionSdk.startDetectionLoop((framed) => {\n this.setShutterEnabled(framed);\n });\n // start idle timeout\n this.timer = setTimeout(() => {\n this.stopVideoStream();\n // open idle dialog\n const idleDialog = new baseDialog_1.default();\n idleDialog.render(this.mainScreenId, (0, translations_1.$t)(\"idle_message\"), (0, translations_1.$t)(\"btn_okay\"));\n }, this.cameraTimeLimit);\n (0, components_1.hideFullLoading)(this.cameraId);\n });\n }\n stopVideoStream() {\n this._cleanup();\n const cameraDiv = document.getElementById(this.cameraId);\n cameraDiv === null || cameraDiv === void 0 ? void 0 : cameraDiv.remove();\n (0, components_1.hideFullLoading)(this.cameraId);\n }\n _cleanup() {\n var _a;\n (_a = this.cardDetectionSdk) === null || _a === void 0 ? void 0 : _a.dispose();\n if (this.videoElement && this.videoElement.srcObject) {\n const stream = this.videoElement.srcObject;\n stream.getTracks().forEach(t => t.stop());\n this.videoElement.srcObject = null;\n }\n if (this.timer)\n clearTimeout(this.timer);\n window.removeEventListener(\"resize\", this._onWindowResize);\n window.removeEventListener(\"beforeunload\", this._onBeforeUnload);\n }\n updateType(cardType) {\n this.cardType = cardType;\n // update title\n const title = document.getElementById(\"pw-camera-title\");\n if (title)\n title.innerHTML = camera_instruction_1.CAMERA_INSTRUCTION[this.cardType].title;\n }\n loadVideoStream(videoElement) {\n const initialConstraints = {\n facingMode: \"environment\",\n width: {\n ideal: 1280, // 1280, 1024, 640\n },\n height: {\n ideal: 960, // 960, 768, 480\n },\n video: true,\n };\n // Mirror video when not on mobile device (desktop/laptop front camera UX)\n if (!(0, deviceDetection_1.isMobileDevice)()) {\n videoElement.style.transform = \"scaleX(-1)\";\n }\n // Load the video stream\n const nav = window.navigator.mediaDevices\n ? window.navigator.mediaDevices\n : window.navigator;\n if (!nav)\n return;\n nav\n .getUserMedia({ video: initialConstraints })\n .then((stream) => {\n videoElement.srcObject = stream;\n })\n .catch((err) => {\n console.error(\"Error accessing the camera:\", err);\n });\n }\n cameraInit() {\n var _a;\n if (!this.videoElement)\n return;\n this.loadVideoStream(this.videoElement);\n // Fire model load concurrently — typically ready by the time video starts.\n this.cardDetectionSdk.loadModel();\n // video event listeners\n this.videoElement.addEventListener(\"loadedmetadata\", () => {\n var _a;\n this.cardDetectionSdk.init(this.cardType);\n (_a = this.overlayElement) === null || _a === void 0 ? void 0 : _a.classList.remove(\"pw-hidden\");\n // Set initial video dimensions based on orientation\n this.resizeElement();\n this.cardDetectionSdk.startDetectionLoop((framed) => {\n this.setShutterEnabled(framed);\n });\n });\n this.videoElement.addEventListener(\"resize\", () => {\n const isFooterExist = document.getElementById(camera_1.ELEMENT_IDS.FOOTER);\n if (!isFooterExist) {\n this.renderCameraBottomUi();\n }\n this.resizeElement();\n });\n window.addEventListener(\"resize\", this._onWindowResize);\n window.addEventListener(\"beforeunload\", this._onBeforeUnload);\n (_a = screen.orientation) === null || _a === void 0 ? void 0 : _a.addEventListener(\"change\", () => {\n const orientationType = screen.orientation.type;\n if (!orientationType || !this.isMobile)\n return;\n if ([\"landscape-primary\", \"landscape-secondary\"].includes(orientationType)) {\n // TO ADD DIALOG ASK USER TO USE POTRAIT VIEW\n }\n else if ([\"portrait-secondary\", \"portrait-primary\"].includes(orientationType)) {\n // TO BE CONFIRM IF NEED CLOSE DIALOG\n }\n });\n }\n setShutterEnabled(enabled) {\n const btn = document.getElementById(\"takePicButton\");\n if (!btn)\n return;\n btn.classList.toggle(\"pw-opacity-40\", !enabled);\n btn.classList.toggle(\"pw-pointer-events-none\", !enabled);\n }\n resizeElement() {\n const videoContainer = document.getElementById(camera_1.ELEMENT_IDS.VIDEO_CONTAINER);\n const videoElement = this.videoElement;\n if (videoElement && videoElement.videoWidth && videoElement.videoHeight) {\n const vpW = window.innerWidth;\n const vpH = window.innerHeight;\n const videoAspect = videoElement.videoWidth / videoElement.videoHeight;\n // Fit the container to the camera's native aspect ratio within the viewport\n let containerW;\n let containerH;\n if (vpW / vpH > videoAspect) {\n containerH = vpH; // viewport wider than video — constrain by height\n containerW = vpH * videoAspect;\n }\n else {\n containerW = vpW; // viewport taller than video — constrain by width\n containerH = vpW / videoAspect;\n }\n if (videoContainer) {\n videoContainer.style.width = `${containerW}px`;\n videoContainer.style.height = `${containerH}px`;\n }\n videoElement.style.width = \"100%\";\n videoElement.style.height = \"100%\";\n videoElement.style.minWidth = \"\";\n videoElement.style.minHeight = \"\";\n }\n this.cardDetectionSdk.resizeElement();\n }\n}\nexports[\"default\"] = CardCamera;\n\n\n//# sourceURL=webpack://PWUISDK/./src/plugins/card-camera.ts?");
|
|
4003
|
+
eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst card_detection_1 = __importDefault(__webpack_require__(/*! ./card-detection */ \"./src/plugins/card-detection.ts\"));\nconst translations_1 = __webpack_require__(/*! ../translations */ \"./src/translations/index.ts\");\nconst deviceDetection_1 = __webpack_require__(/*! ../helper/deviceDetection */ \"./src/helper/deviceDetection.ts\");\nconst camera_1 = __webpack_require__(/*! ../models/camera */ \"./src/models/camera.ts\");\nconst camera_instruction_1 = __webpack_require__(/*! ../constant/camera-instruction */ \"./src/constant/camera-instruction.ts\");\nconst baseDialog_1 = __importDefault(__webpack_require__(/*! ../components/baseDialog */ \"./src/components/baseDialog.ts\"));\nconst components_1 = __webpack_require__(/*! ../components/components */ \"./src/components/components.ts\");\nconst navigationBar_1 = __importDefault(__webpack_require__(/*! ../components/navigationBar */ \"./src/components/navigationBar.ts\"));\nconst cameraViewport_1 = __importDefault(__webpack_require__(/*! ../components/cameraViewport */ \"./src/components/cameraViewport.ts\"));\nconst footer_1 = __importDefault(__webpack_require__(/*! ../components/footer */ \"./src/components/footer.ts\"));\nconst MainPage_1 = __webpack_require__(/*! ../classes/MainPage */ \"./src/classes/MainPage.ts\");\nconst imagesHelper_1 = __webpack_require__(/*! ../helper/imagesHelper */ \"./src/helper/imagesHelper.ts\");\nclass CardCamera {\n constructor(cameraId, cardType, mainScreenId = \"\") {\n this.cameraTimeLimit = 90000;\n this.videoElement = null;\n this.canvasElement = null;\n this.overlayElement = null;\n this.titleElement = null;\n this.footerElement = null;\n this.cameraId = cameraId;\n this.cardType = cardType;\n this.mainScreenId = mainScreenId;\n }\n isMobile() {\n // Use extracted helper function\n return (0, deviceDetection_1.isMobileDevice)();\n }\n captureImage() {\n var _a, _b, _c, _d, _e, _f, _g;\n return __awaiter(this, void 0, void 0, function* () {\n const bitmap = this.videoElement;\n // 1. full image\n let canvas = document.createElement(\"canvas\");\n let context = canvas.getContext(\"2d\");\n canvas.width = bitmap.videoWidth;\n canvas.height = bitmap.videoHeight;\n context.drawImage(bitmap, 0, 0, bitmap.videoWidth, bitmap.videoHeight);\n // 2. cropped image — region corresponds exactly to what the overlay shows\n let cropCanvas = document.createElement(\"canvas\");\n let cropContext = cropCanvas.getContext(\"2d\");\n cropCanvas.width = bitmap.videoWidth;\n cropCanvas.height = bitmap.videoHeight;\n cropContext.drawImage(bitmap, 0, 0, bitmap.videoWidth, bitmap.videoHeight);\n // Scale factor: stream pixels per display pixel\n const scaleX = bitmap.videoWidth / ((_b = (_a = this.videoElement) === null || _a === void 0 ? void 0 : _a.clientWidth) !== null && _b !== void 0 ? _b : bitmap.videoWidth);\n const scaleY = bitmap.videoHeight / ((_d = (_c = this.videoElement) === null || _c === void 0 ? void 0 : _c.clientHeight) !== null && _d !== void 0 ? _d : bitmap.videoHeight);\n // Use overlay's actual on-screen position as the crop region\n const overlayRect = (_e = this.overlayElement) === null || _e === void 0 ? void 0 : _e.getBoundingClientRect();\n const videoRect = (_f = this.videoElement) === null || _f === void 0 ? void 0 : _f.getBoundingClientRect();\n let cropX, cropY, cropW, cropH;\n if (overlayRect && videoRect) {\n cropX = Math.round((overlayRect.left - videoRect.left) * scaleX);\n cropY = Math.round((overlayRect.top - videoRect.top) * scaleY);\n cropW = Math.round(overlayRect.width * scaleX);\n cropH = Math.round(overlayRect.height * scaleY);\n }\n else {\n // Fallback: derive from calculateHeightNWidth + manual scale\n const { width, height } = this.cardDetectionSdk.calculateHeightNWidth(bitmap.videoWidth, bitmap.videoHeight);\n cropW = Math.round(width * scaleX);\n cropH = Math.round(height * scaleY);\n cropX = Math.round((bitmap.videoWidth - cropW) / 2);\n cropY = Math.round((bitmap.videoHeight - cropH) / 2);\n }\n // Clamp to stream bounds\n cropX = Math.max(0, cropX);\n cropY = Math.max(0, cropY);\n cropW = Math.min(cropW, bitmap.videoWidth - cropX);\n cropH = Math.min(cropH, bitmap.videoHeight - cropY);\n // crop the selected part image (viewport frame region)\n const imgData = cropContext.getImageData(cropX, cropY, cropW, cropH);\n cropCanvas.width = cropW;\n cropCanvas.height = cropH;\n cropContext.putImageData(imgData, 0, 0);\n // Determine card type prefix for file naming\n const cardTypePrefix = this.cardType === camera_1.CARD_TYPES.ID ? 'id-front' :\n this.cardType === camera_1.CARD_TYPES.ID_BACK ? 'id-back' :\n this.cardType === camera_1.CARD_TYPES.LICENSE ? 'license-front' :\n this.cardType === camera_1.CARD_TYPES.LICENSE_BACK ? 'license-back' :\n this.cardType === camera_1.CARD_TYPES.PASSPORT ? 'passport' :\n this.cardType === camera_1.CARD_TYPES.CC ? 'cc-front' : 'cc-back';\n // TEMP: Download BEFORE resize for comparison (only if debug enabled)\n if (MainPage_1.enableImageDebug) {\n const beforeResizeFullCanvas = canvas.cloneNode();\n const beforeResizeFullCtx = beforeResizeFullCanvas.getContext(\"2d\");\n beforeResizeFullCanvas.width = canvas.width;\n beforeResizeFullCanvas.height = canvas.height;\n beforeResizeFullCtx.drawImage(canvas, 0, 0);\n const beforeResizeCropCanvas = cropCanvas.cloneNode();\n const beforeResizeCropCtx = beforeResizeCropCanvas.getContext(\"2d\");\n beforeResizeCropCanvas.width = cropCanvas.width;\n beforeResizeCropCanvas.height = cropCanvas.height;\n beforeResizeCropCtx.drawImage(cropCanvas, 0, 0);\n console.log(`[DEBUG] ${cardTypePrefix} BEFORE resize - Full: ${beforeResizeFullCanvas.width}x${beforeResizeFullCanvas.height}, Cropped: ${beforeResizeCropCanvas.width}x${beforeResizeCropCanvas.height}`);\n this.downloadImage(beforeResizeFullCanvas.toDataURL(\"image/jpeg\"), `${cardTypePrefix}-full-BEFORE-${beforeResizeFullCanvas.width}x${beforeResizeFullCanvas.height}.jpg`);\n this.downloadImage(beforeResizeCropCanvas.toDataURL(\"image/jpeg\"), `${cardTypePrefix}-cropped-BEFORE-${beforeResizeCropCanvas.width}x${beforeResizeCropCanvas.height}.jpg`);\n }\n // 3. resize the canvas\n try {\n canvas = (0, imagesHelper_1.resizeCanvas)(canvas, imagesHelper_1.maxFullImage.width, imagesHelper_1.maxFullImage.height);\n cropCanvas = (0, imagesHelper_1.resizeCanvas)(cropCanvas, imagesHelper_1.maxCroppedImage.width, imagesHelper_1.maxCroppedImage.height);\n }\n catch (err) {\n console.error(\"doc resize image error\", err);\n }\n // 4. construct payload - convert to desired file format\n const { width: displayWidth = \"\", height: displayHeight = \"\" } = ((_g = this.overlayElement) === null || _g === void 0 ? void 0 : _g.style) || {};\n const payload = {\n fullImage: canvas.toDataURL(\"image/jpeg\"),\n croppedImage: cropCanvas.toDataURL(\"image/jpeg\"),\n displaySize: {\n width: Number(displayWidth.replace(\"px\", \"\")),\n height: Number(displayHeight.replace(\"px\", \"\")),\n },\n };\n // TEMP: Download AFTER resize for comparison (only if debug enabled)\n if (MainPage_1.enableImageDebug) {\n console.log(`[DEBUG] ${cardTypePrefix} AFTER resize - Full: ${canvas.width}x${canvas.height}, Cropped: ${cropCanvas.width}x${cropCanvas.height}`);\n if (payload.fullImage)\n this.downloadImage(payload.fullImage, `${cardTypePrefix}-full-AFTER-${canvas.width}x${canvas.height}.jpg`);\n if (payload.croppedImage)\n this.downloadImage(payload.croppedImage, `${cardTypePrefix}-cropped-AFTER-${cropCanvas.width}x${cropCanvas.height}.jpg`);\n }\n return payload;\n });\n }\n // TEMP: Helper method to download image\n downloadImage(dataUrl, filename) {\n const link = document.createElement(\"a\");\n link.href = dataUrl;\n link.download = filename;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n }\n init() {\n try {\n // show loading spinner in full pg\n (0, components_1.createFullLoading)(this.cameraId, \"Initializing Camera...\");\n // 1. Draw the camera display\n this.drawCameraDisplay();\n // 2. Setup related SDK\n const { videoElement, canvasElement, overlayElement, titleElement } = this;\n this.cardDetectionSdk = new card_detection_1.default({\n videoElement,\n canvasElement,\n overlayElement,\n titleElement,\n });\n // 3. Get the camera permission and trigger the card detection\n this.cameraInit();\n // 4. Start timer to close camera\n this.timer = setTimeout(() => {\n this.stopVideoStream();\n // open idle dialog\n const idleDialog = new baseDialog_1.default();\n idleDialog.render(this.mainScreenId, (0, translations_1.$t)(\"idle_message\"), (0, translations_1.$t)(\"btn_okay\"));\n }, this.cameraTimeLimit);\n }\n finally {\n // hide loading spinner in full pg\n (0, components_1.hideFullLoading)(this.cameraId);\n }\n }\n drawCameraDisplay() {\n // 1. header section\n const header = document.createElement(\"div\");\n header.id = camera_1.ELEMENT_IDS.HEADER;\n // header.classList.add(\"camera-header-area\");\n header.classList.add(\"pw-absolute\", \"pw-z-[2]\", \"pw-w-full\", \"pw-text-white\");\n const navigationDiv = new navigationBar_1.default().render(() => {\n this.stopVideoStream();\n });\n header.appendChild(navigationDiv);\n const body = document.createElement(\"div\");\n body.id = camera_1.ELEMENT_IDS.BODY;\n body.classList.add(\"camera-body-area\");\n const videoContainer = document.createElement(\"div\");\n videoContainer.id = camera_1.ELEMENT_IDS.VIDEO_CONTAINER;\n videoContainer.classList.add(\"video-container\");\n const overlayContainer = document.createElement(\"div\");\n overlayContainer.id = camera_1.ELEMENT_IDS.OVERLAY_CONTAINER;\n overlayContainer.classList.add(\"overlay-container\");\n // Use CameraViewport component for consistent viewport design\n const cameraViewport = new cameraViewport_1.default(this.cardType);\n const overlayElement = cameraViewport.render();\n overlayElement.classList.add(\"pw-relative\");\n // Container for title and description - positioned above the overlay\n const headerContainer = document.createElement(\"div\");\n headerContainer.classList.add(\"pw-absolute\");\n headerContainer.style.zIndex = \"1\";\n headerContainer.style.left = \"50%\";\n headerContainer.style.bottom = \"100%\";\n headerContainer.style.transform = \"translate(-50%, -20px)\";\n headerContainer.style.width = \"calc(100vw - 48px)\";\n headerContainer.style.maxWidth = \"1400px\";\n // Set Title\n const titleDiv = document.createElement(\"div\");\n titleDiv.id = \"pw-camera-title\";\n titleDiv.classList.add(\"pw-text-2xl\", \"pw-text-center\", \"pw-text-white\", \"pw-mb-4\");\n titleDiv.innerHTML = camera_instruction_1.CAMERA_INSTRUCTION[this.cardType].title;\n this.titleElement = titleDiv;\n headerContainer.appendChild(titleDiv);\n // Set Description\n const descriptionDiv = document.createElement(\"div\");\n descriptionDiv.classList.add(\"pw-text-center\", \"pw-px-5\", \"pw-text-xl\", \"pw-text-white\");\n descriptionDiv.innerHTML = camera_instruction_1.CAMERA_INSTRUCTION[this.cardType].description;\n headerContainer.appendChild(descriptionDiv);\n overlayElement.appendChild(headerContainer);\n const canvasElement = document.createElement(\"canvas\");\n canvasElement.id = camera_1.ELEMENT_IDS.CANVAS;\n canvasElement.classList.add(\"video-element\");\n canvasElement.classList.add(\"canvas-element\");\n // Mirror canvas to match video when not on mobile device (desktop/laptop)\n if (!(0, deviceDetection_1.isMobileDevice)()) {\n canvasElement.style.transform = \"scaleX(-1)\";\n }\n const videoElement = document.createElement(\"video\");\n videoElement.id = camera_1.ELEMENT_IDS.VIDEO;\n videoElement.autoplay = true;\n videoElement.playsInline = true;\n videoElement.preload = \"auto\";\n videoElement.loop = true;\n videoElement.classList.add(\"video-element\");\n // Mirror horizontally when not on mobile device (desktop/laptop front camera UX)\n if (!(0, deviceDetection_1.isMobileDevice)()) {\n videoElement.style.transform = \"scaleX(-1)\";\n }\n // 2.1\n this.videoElement = videoElement;\n this.overlayElement = overlayElement;\n this.canvasElement = canvasElement;\n overlayContainer.appendChild(overlayElement);\n videoContainer.appendChild(overlayContainer);\n videoContainer.appendChild(canvasElement);\n videoContainer.appendChild(videoElement);\n body.appendChild(videoContainer);\n // 3. append child\n const mainBody = document.getElementById(this.cameraId);\n if (!mainBody)\n return;\n mainBody.classList.add(\"camera-bg\", \"pw-overflow-y-hidden\");\n mainBody.appendChild(header);\n mainBody.appendChild(body);\n }\n listenToCardCapture(cb) {\n const cameraBody = document.getElementById(this.cameraId);\n cameraBody === null || cameraBody === void 0 ? void 0 : cameraBody.addEventListener(\"captureImage\", (e) => {\n cb(e);\n });\n }\n // here also is where the take picture button resides\n renderCameraBottomUi() {\n const footer = document.createElement(\"div\");\n footer.id = camera_1.ELEMENT_IDS.FOOTER;\n footer.classList.add(\"pw-absolute\", \"pw-bottom-[10%]\", \"pw-z-[2]\", \"pw-w-full\", \"pw-text-white\", \"pw-relative\");\n const takePicButton = document.createElement(\"div\");\n takePicButton.id = \"takePicButton\";\n takePicButton.classList.add(\"pw-box-border\", \"pw-mx-auto\", \"pw-absolute\", \"pw-bottom-16\", \"pw-relative\", \"pw-rounded-full\", \"pw-h-16\", \"pw-w-16\", \"pw-border-solid\", \"pw-border-white\", \"pw-border-4\", \"pw-cursor-pointer\");\n const smallCircleContainer = document.createElement(\"div\");\n smallCircleContainer.classList.add(\"pw-absolute\", \"pw-top-1/2\", \"-pw-translate-y-1/2\", \"pw-left-1/2\", \"-pw-translate-x-1/2\");\n takePicButton.appendChild(smallCircleContainer);\n const smallCircle = document.createElement(\"div\");\n smallCircle.classList.add(\"pw-w-11\", \"pw-h-11\", \"pw-bg-white\", \"pw-rounded-full\", \"pw-transition-all\", \"pw-duration-100\", \"active:pw-scale-90\");\n smallCircleContainer.appendChild(smallCircle);\n footer.appendChild(takePicButton);\n takePicButton.addEventListener(\"click\", () => __awaiter(this, void 0, void 0, function* () {\n const mainBody = document.getElementById(this.cameraId);\n const image = yield this.captureImage();\n const event = new CustomEvent(\"captureImage\", {\n detail: {\n image,\n type: this.cardType,\n },\n });\n mainBody === null || mainBody === void 0 ? void 0 : mainBody.dispatchEvent(event);\n }));\n const mainBody = document.getElementById(this.cameraId);\n this.footerElement = footer;\n mainBody === null || mainBody === void 0 ? void 0 : mainBody.appendChild(footer);\n // Powered by pipwave at bottom of viewport\n const poweredByWrapper = document.createElement(\"div\");\n poweredByWrapper.classList.add(\"pw-absolute\", \"pw-bottom-0\", \"pw-left-0\", \"pw-right-0\", \"pw-pb-4\", \"pw-z-[2]\", \"pw-flex\", \"pw-justify-center\", \"pw-items-center\", \"pw-text-white\");\n const poweredByFooter = new footer_1.default().render(true);\n poweredByWrapper.appendChild(poweredByFooter);\n mainBody === null || mainBody === void 0 ? void 0 : mainBody.appendChild(poweredByWrapper);\n }\n pauseVideoStream() {\n var _a;\n return __awaiter(this, void 0, void 0, function* () {\n // stop the video\n (_a = this.videoElement) === null || _a === void 0 ? void 0 : _a.pause();\n // stop idle timeout\n if (this.timer) {\n clearTimeout(this.timer);\n }\n });\n }\n resumeVideoStream(cardType) {\n var _a;\n return __awaiter(this, void 0, void 0, function* () {\n this.updateType(cardType);\n // resume the video\n (_a = this.videoElement) === null || _a === void 0 ? void 0 : _a.play();\n // start idle timeout\n this.timer = setTimeout(() => {\n this.stopVideoStream();\n // open idle dialog\n const idleDialog = new baseDialog_1.default();\n idleDialog.render(this.mainScreenId, (0, translations_1.$t)(\"idle_message\"), (0, translations_1.$t)(\"btn_okay\"));\n }, this.cameraTimeLimit);\n (0, components_1.hideFullLoading)(this.cameraId);\n });\n }\n stopVideoStream() {\n if (this.videoElement && this.videoElement.srcObject) {\n const stream = this.videoElement.srcObject;\n const tracks = stream.getTracks();\n tracks.forEach(function (track) {\n track.stop();\n });\n this.videoElement.srcObject = null;\n }\n if (this.timer)\n clearTimeout(this.timer);\n const cameraDiv = document.getElementById(this.cameraId);\n cameraDiv === null || cameraDiv === void 0 ? void 0 : cameraDiv.remove();\n (0, components_1.hideFullLoading)(this.cameraId);\n }\n updateType(cardType) {\n this.cardType = cardType;\n // update title\n const title = document.getElementById(\"pw-camera-title\");\n if (title)\n title.innerHTML = camera_instruction_1.CAMERA_INSTRUCTION[this.cardType].title;\n }\n loadVideoStream(videoElement) {\n const initialConstraints = {\n facingMode: \"environment\",\n width: {\n ideal: 1280, // 1280, 1024, 640\n },\n height: {\n ideal: 960, // 960, 768, 480\n },\n video: true,\n };\n // Mirror video when not on mobile device (desktop/laptop front camera UX)\n if (!(0, deviceDetection_1.isMobileDevice)()) {\n videoElement.style.transform = \"scaleX(-1)\";\n }\n // Load the video stream\n const nav = window.navigator.mediaDevices\n ? window.navigator.mediaDevices\n : window.navigator;\n if (!nav)\n return;\n nav\n .getUserMedia({ video: initialConstraints })\n .then((stream) => {\n videoElement.srcObject = stream;\n })\n .catch((err) => {\n console.error(\"Error accessing the camera:\", err);\n });\n }\n cameraInit() {\n var _a;\n if (!this.videoElement)\n return;\n this.loadVideoStream(this.videoElement);\n // video event listeners\n this.videoElement.addEventListener(\"loadedmetadata\", () => {\n var _a;\n this.cardDetectionSdk.init(this.cardType);\n (_a = this.overlayElement) === null || _a === void 0 ? void 0 : _a.classList.remove(\"pw-hidden\");\n // Set initial video dimensions based on orientation\n this.resizeElement();\n });\n this.videoElement.addEventListener(\"resize\", () => {\n const isFooterExist = document.getElementById(camera_1.ELEMENT_IDS.FOOTER);\n if (!isFooterExist) {\n this.renderCameraBottomUi();\n }\n this.resizeElement();\n });\n window.addEventListener(\"resize\", () => {\n this.resizeElement();\n });\n (_a = screen.orientation) === null || _a === void 0 ? void 0 : _a.addEventListener(\"change\", () => {\n const orientationType = screen.orientation.type;\n if (!orientationType || !this.isMobile)\n return;\n if ([\"landscape-primary\", \"landscape-secondary\"].includes(orientationType)) {\n // TO ADD DIALOG ASK USER TO USE POTRAIT VIEW\n }\n else if ([\"portrait-secondary\", \"portrait-primary\"].includes(orientationType)) {\n // TO BE CONFIRM IF NEED CLOSE DIALOG\n }\n });\n }\n resizeElement() {\n const videoContainer = document.getElementById(camera_1.ELEMENT_IDS.VIDEO_CONTAINER);\n const videoElement = this.videoElement;\n if (videoElement && videoElement.videoWidth && videoElement.videoHeight) {\n const vpW = window.innerWidth;\n const vpH = window.innerHeight;\n const videoAspect = videoElement.videoWidth / videoElement.videoHeight;\n // Fit the container to the camera's native aspect ratio within the viewport\n let containerW;\n let containerH;\n if (vpW / vpH > videoAspect) {\n // Viewport is wider than video — constrain by height\n containerH = vpH;\n containerW = vpH * videoAspect;\n }\n else {\n // Viewport is taller than video — constrain by width\n containerW = vpW;\n containerH = vpW / videoAspect;\n }\n if (videoContainer) {\n videoContainer.style.width = `${containerW}px`;\n videoContainer.style.height = `${containerH}px`;\n }\n videoElement.style.width = \"100%\";\n videoElement.style.height = \"100%\";\n videoElement.style.minWidth = \"\";\n videoElement.style.minHeight = \"\";\n }\n this.cardDetectionSdk.resizeElement();\n }\n}\nexports[\"default\"] = CardCamera;\n\n\n//# sourceURL=webpack://PWUISDK/./src/plugins/card-camera.ts?");
|
|
4004
4004
|
|
|
4005
4005
|
/***/ }),
|
|
4006
4006
|
|
|
@@ -4008,10 +4008,10 @@ eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _argument
|
|
|
4008
4008
|
/*!***************************************!*\
|
|
4009
4009
|
!*** ./src/plugins/card-detection.ts ***!
|
|
4010
4010
|
\***************************************/
|
|
4011
|
-
/***/ (
|
|
4011
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
4012
4012
|
|
|
4013
4013
|
"use strict";
|
|
4014
|
-
eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst id_1 = __webpack_require__(/*! ../constant/id */ \"./src/constant/id.ts\");\nconst camera_1 = __webpack_require__(/*! ../models/camera */ \"./src/models/camera.ts\");\nconst deviceDetection_1 = __webpack_require__(/*! ../helper/deviceDetection */ \"./src/helper/deviceDetection.ts\");\nconst MainPage_1 = __webpack_require__(/*! ../classes/MainPage */ \"./src/classes/MainPage.ts\");\nconst CARD_DETECTION_CONFIG = {\n // Model / inference\n // Fine-tuned YOLO11n, single \"document\" class, INT8. Output is [1, 5, N]:\n // cx, cy, w, h, score per anchor (N comes from the model, we don't hardcode it).\n MODEL_URL: '/card-models/document-detection-int8-480.onnx',\n // onnxruntime-web, served from our own origin (a Blob worker can't importScripts a\n // cross-origin URL). The matching .mjs/.wasm live next to it in public/ort/.\n ORT_URL: '/ort/ort.wasm.min.js',\n INPUT_SIZE: 480,\n MAX_THREADS: 4,\n // so cranking this up doesn't help and just hogs the CPU.\n // Detection rule\n // Two thresholds, not one, so a score wobbling around a single cutoff doesn't flip\n // valid/no-card every frame: needs to get above CONF_ENTER to count as a card, then\n // stays a card until it drops under CONF_EXIT.\n CONF_ENTER: 0.55,\n CONF_EXIT: 0.40,\n // Smooth the score so one bad frame doesn't drop us (the score tanks for a frame or two\n // on a held card when it blurs). ema = alpha*raw + (1-alpha)*ema; smaller alpha = smoother.\n CONF_EMA_ALPHA: 0.5,\n // Framing geometry (the real gate is containment: is the card inside the guide) ──\n MIN_FILL_RATIO: 0.45,\n // How far the card may poke past the guide (x min(guideW,guideH)) before it's \"out of box\".\n // POSITIVE = lenient (card can spill outside the guide). NEGATIVE = strict: the card must stay\n // this far INSIDE the guide, which shrinks the effective detection box so an angled/edging card\n // is flagged \"out-of-box\" early, before it actually crosses the visible guide line.\n CONTAINMENT_SLACK_RATIO: -0.04,\n // Loop / debounce\n // Asymmetric on purpose: slow to go green (don't want a false capture), quick to drop it.\n THROTTLE_FPS: 8,\n STABLE_FRAMES_TO_ENABLE: 2,\n STABLE_FRAMES_TO_DISABLE: 1,\n BORDER_STABLE_FRAMES: 2,\n BORDER_CLEAR_FRAMES: 1,\n INFERENCE_STUCK_MS: 3000, // if a frame's been out this long the worker lost it,\n // so clear the busy flag and carry on instead of hanging\n};\nconst ID_CARD_TYPES = [\n camera_1.CARD_TYPES.ID,\n camera_1.CARD_TYPES.ID_BACK,\n camera_1.CARD_TYPES.LICENSE,\n camera_1.CARD_TYPES.LICENSE_BACK,\n camera_1.CARD_TYPES.CC,\n camera_1.CARD_TYPES.CC_BACK,\n];\n// Inference worker\n// Runs onnxruntime-web off the main thread so WASM inference never blocks UI\n// paint. Receives a transferred ImageBitmap per frame, letterboxes + preprocesses\n// on an OffscreenCanvas, runs the model, and posts back the best box in video px.\n// Kept as a Blob string so it needs no webpack worker-loader config.\nconst WORKER_SOURCE = `\nlet session = null, ortLib = null, ready = false;\nlet INPUT = 320, ctx = null;\n// Input buffer + tensor, allocated once and reused every frame to avoid per-frame GC.\nlet inputBuf = null, inputTensor = null;\n\nself.onmessage = async (e) => {\n const msg = e.data;\n\n if (msg.type === 'init') {\n INPUT = msg.input;\n let stage = 'importScripts';\n try {\n importScripts(msg.ortUrl);\n stage = 'ort-global';\n ortLib = self.ort;\n if (!ortLib) throw new Error('self.ort is undefined after importScripts(' + msg.ortUrl + ')');\n stage = 'config';\n ortLib.env.wasm.wasmPaths = msg.wasmDir;\n ortLib.env.wasm.simd = true;\n // Threads need SharedArrayBuffer, which only exists if the page is cross-origin\n // isolated (COOP/COEP headers). No isolation, no threads - drop to one.\n ortLib.env.wasm.numThreads = self.crossOriginIsolated\n ? Math.min(msg.maxThreads || 4, navigator.hardwareConcurrency || 4)\n : 1;\n stage = 'offscreen-canvas';\n const canvas = new OffscreenCanvas(INPUT, INPUT);\n ctx = canvas.getContext('2d', { willReadFrequently: true });\n stage = 'session-create (' + msg.modelUrl + ')';\n session = await ortLib.InferenceSession.create(msg.modelUrl, {\n executionProviders: ['wasm'],\n graphOptimizationLevel: 'all',\n });\n ready = !!session;\n if (!ready) throw new Error('session create returned no session');\n // Allocate the input buffer/tensor once, then do one throwaway run. That first run\n // eats the graph-optimization + allocation cost so the first real frame isn't slow.\n stage = 'warmup';\n inputBuf = new Float32Array(3 * INPUT * INPUT);\n inputTensor = new ortLib.Tensor('float32', inputBuf, [1, 3, INPUT, INPUT]);\n try {\n await session.run({ [session.inputNames[0]]: inputTensor });\n } catch (_) { /* fine, the first real frame just won't have the warm-up */ }\n self.postMessage({\n type: 'ready', ok: true, ep: 'wasm',\n coi: !!self.crossOriginIsolated,\n threads: ortLib.env.wasm.numThreads,\n });\n return;\n } catch (err) {\n const detail = err && err.message ? err.message : String(err);\n self.postMessage({ type: 'ready', ok: false, error: '[' + stage + '] ' + detail });\n return;\n }\n }\n\n if (msg.type === 'frame') {\n const bitmap = msg.bitmap;\n if (!ready) { if (bitmap && bitmap.close) bitmap.close(); self.postMessage({ type: 'result', ok: false }); return; }\n\n const W = bitmap.width, H = bitmap.height, N = INPUT;\n const scale = Math.min(N / W, N / H);\n const newW = Math.round(W * scale), newH = Math.round(H * scale);\n const padX = (N - newW) / 2, padY = (N - newH) / 2;\n ctx.fillStyle = '#727272';\n ctx.fillRect(0, 0, N, N);\n ctx.drawImage(bitmap, 0, 0, W, H, padX, padY, newW, newH);\n if (bitmap.close) bitmap.close();\n\n const d = ctx.getImageData(0, 0, N, N).data;\n const area = N * N, f = inputBuf; // reused buffer; tensor wraps it by reference\n for (let i = 0; i < area; i++) {\n f[i] = d[i * 4] / 255;\n f[area + i] = d[i * 4 + 1] / 255;\n f[2 * area + i] = d[i * 4 + 2] / 255;\n }\n\n let out, inferMs = 0;\n try {\n const t0 = performance.now();\n out = await session.run({ [session.inputNames[0]]: inputTensor });\n inferMs = performance.now() - t0;\n } catch (err) { self.postMessage({ type: 'result', ok: false }); return; }\n\n const o = out[session.outputNames[0]], od = o.data, nA = o.dims[2];\n let bestScore = 0, bestIdx = -1; const sBase = 4 * nA;\n for (let a = 0; a < nA; a++) { const s = od[sBase + a]; if (s > bestScore) { bestScore = s; bestIdx = a; } }\n\n let box = null;\n if (bestIdx >= 0) {\n const cx = od[bestIdx], cy = od[nA + bestIdx], bw = od[2 * nA + bestIdx], bh = od[3 * nA + bestIdx];\n box = {\n x1: (cx - bw / 2 - padX) / scale, y1: (cy - bh / 2 - padY) / scale,\n x2: (cx + bw / 2 - padX) / scale, y2: (cy + bh / 2 - padY) / scale,\n };\n }\n self.postMessage({ type: 'result', ok: true, score: bestScore, box: box, W: W, H: H, inferMs: inferMs });\n }\n};\n`;\nclass CARDDETECTIONSDK {\n constructor(val) {\n this.type = camera_1.CARD_TYPES.ID;\n this.videoElement = null;\n this.canvasElement = null;\n this.overlayElement = null;\n this.titleElement = null;\n // Worker / model state\n this.worker = null;\n this.workerUrl = null;\n this.modelReady = false;\n this.modelLoadPromise = null;\n // Loop state\n this.rafId = null;\n this.inferenceBusy = false;\n this.lastFrameTime = 0;\n this.consecutiveValidFrames = 0;\n this.consecutiveInvalidFrames = 0;\n this.isDocumentProperlyFramed = false;\n this.candidateBorder = 'none';\n this.candidateBorderCount = 0;\n this.activeBorder = 'none';\n this.stateChangeCallback = null;\n this.lastReason = '';\n this.lastInferMs = 0;\n this.cardPresent = false; // confidence-hysteresis latch (see _evaluateBox)\n this.scoreEma = 0; // smoothed confidence (rejects single-frame dropouts)\n this.inferenceStartedAt = 0; // timestamp of the in-flight frame (watchdog)\n Object.assign(this, val);\n }\n // Returns overlay dimensions in DISPLAY PIXELS — callers cropping from the\n // video stream must scale by videoWidth/clientWidth.\n calculateHeightNWidth(width, height) {\n var _a, _b;\n const videoWidth = ((_a = this.videoElement) === null || _a === void 0 ? void 0 : _a.clientWidth) || width;\n const videoHeight = ((_b = this.videoElement) === null || _b === void 0 ? void 0 : _b.clientHeight) || height;\n const idCardRatio = id_1.ID_CARD_RATIO[this.type] || id_1.ID_CARD_RATIO[\"others\"];\n const isDesktop = window.innerWidth >= id_1.VIEWPORT_SIZE.DESKTOP_BREAKPOINT;\n let newWidth;\n let newHeight;\n if (isDesktop) {\n const isIdCard = ID_CARD_TYPES.includes(this.type);\n const maxWidthRatio = isIdCard\n ? id_1.VIEWPORT_SIZE.DESKTOP_ID_MAX_WIDTH_RATIO\n : id_1.VIEWPORT_SIZE.DESKTOP_PASSPORT_MAX_WIDTH_RATIO;\n const maxHeightRatio = isIdCard\n ? id_1.VIEWPORT_SIZE.DESKTOP_ID_MAX_HEIGHT_RATIO\n : id_1.VIEWPORT_SIZE.DESKTOP_PASSPORT_MAX_HEIGHT_RATIO;\n const maxWidth = videoWidth * maxWidthRatio;\n const maxHeight = videoHeight * maxHeightRatio;\n const widthBasedHeight = maxWidth / idCardRatio;\n const heightBasedWidth = maxHeight * idCardRatio;\n if (widthBasedHeight <= maxHeight) {\n newWidth = maxWidth;\n newHeight = widthBasedHeight;\n }\n else {\n newWidth = heightBasedWidth;\n newHeight = maxHeight;\n }\n // prevent overlay from overlapping host page header\n if (newHeight > id_1.VIEWPORT_SIZE.MAX_OVERLAY_HEIGHT) {\n newHeight = id_1.VIEWPORT_SIZE.MAX_OVERLAY_HEIGHT;\n newWidth = newHeight * idCardRatio;\n }\n }\n else {\n const availableWidth = Math.min(videoWidth, window.innerWidth) -\n id_1.VIEWPORT_SIZE.MOBILE_HORIZONTAL_MARGIN * 2;\n newWidth = Math.max(availableWidth, 200); // min 200px for very small screens\n newHeight = newWidth / idCardRatio;\n const maxHeight = videoHeight - id_1.VIEWPORT_SIZE.MOBILE_HORIZONTAL_MARGIN * 2;\n if (maxHeight > 0 && newHeight > maxHeight) {\n newHeight = Math.max(maxHeight, 100);\n newWidth = newHeight * idCardRatio;\n }\n }\n return { width: newWidth, height: newHeight };\n }\n resizeElement() {\n var _a, _b, _c, _d, _e, _f;\n if (!this.videoElement || !this.canvasElement)\n return;\n const videoWidth = this.videoElement.clientWidth;\n const videoHeight = this.videoElement.clientHeight;\n this.canvasElement.width = videoWidth;\n this.canvasElement.height = videoHeight;\n const { width, height } = this.calculateHeightNWidth(videoWidth, videoHeight);\n (_a = this.overlayElement) === null || _a === void 0 ? void 0 : _a.style.setProperty(\"border-radius\", \"15px\");\n (_b = this.overlayElement) === null || _b === void 0 ? void 0 : _b.style.setProperty(\"border\", \"0px\");\n (_c = this.overlayElement) === null || _c === void 0 ? void 0 : _c.style.setProperty(\"width\", `${width}px`);\n (_d = this.overlayElement) === null || _d === void 0 ? void 0 : _d.style.setProperty(\"height\", `${height}px`);\n const topBorder = (_e = this.overlayElement) === null || _e === void 0 ? void 0 : _e.querySelector(`#${camera_1.ELEMENT_IDS.TOP_BORDER}`);\n topBorder === null || topBorder === void 0 ? void 0 : topBorder.style.setProperty(\"display\", \"inherit\");\n const bottomBorder = (_f = this.overlayElement) === null || _f === void 0 ? void 0 : _f.querySelector(`#${camera_1.ELEMENT_IDS.BOTTOM_BORDER}`);\n bottomBorder === null || bottomBorder === void 0 ? void 0 : bottomBorder.style.setProperty(\"display\", \"inherit\");\n }\n disableDetection() {\n var _a, _b;\n const topBorder = (_a = this.overlayElement) === null || _a === void 0 ? void 0 : _a.querySelector(`#${camera_1.ELEMENT_IDS.TOP_BORDER}`);\n topBorder === null || topBorder === void 0 ? void 0 : topBorder.style.setProperty(\"display\", \"none\");\n const bottomBorder = (_b = this.overlayElement) === null || _b === void 0 ? void 0 : _b.querySelector(`#${camera_1.ELEMENT_IDS.BOTTOM_BORDER}`);\n bottomBorder === null || bottomBorder === void 0 ? void 0 : bottomBorder.style.setProperty(\"display\", \"none\");\n }\n init(type) {\n if (type)\n this.type = type;\n this.resizeElement();\n }\n // Spin up the inference worker and load the model inside it. Resolves even on\n // failure — the caller checks `modelReady` and degrades gracefully.\n loadModel() {\n if (this.modelLoadPromise)\n return this.modelLoadPromise;\n this.modelLoadPromise = new Promise((resolve) => {\n const supported = typeof Worker !== 'undefined' &&\n typeof OffscreenCanvas !== 'undefined' &&\n typeof createImageBitmap !== 'undefined';\n if (!supported) {\n console.warn('[card-detection] Worker/OffscreenCanvas unsupported — detection disabled');\n resolve();\n return;\n }\n try {\n const blob = new Blob([WORKER_SOURCE], { type: 'application/javascript' });\n this.workerUrl = URL.createObjectURL(blob);\n this.worker = new Worker(this.workerUrl);\n }\n catch (e) {\n console.error('[card-detection] failed to start worker', e);\n resolve();\n return;\n }\n this.worker.onmessage = (e) => {\n const m = e.data;\n if ((m === null || m === void 0 ? void 0 : m.type) === 'ready') {\n this.modelReady = !!m.ok;\n if (m.ok) {\n if (MainPage_1.enableImageDebug)\n console.log(`[card-detection] model ready — backend=${m.ep} crossOriginIsolated=${m.coi} threads=${m.threads}`);\n }\n else {\n console.error('[card-detection] model failed to load in worker:', m.error || '(no detail)');\n }\n resolve();\n }\n else if ((m === null || m === void 0 ? void 0 : m.type) === 'result') {\n this._onResult(m);\n }\n };\n this.worker.onerror = (e) => {\n if (MainPage_1.enableImageDebug)\n console.error('[card-detection] worker error', e === null || e === void 0 ? void 0 : e.message);\n if (!this.modelReady)\n resolve();\n };\n // A Blob worker's base is blob:, so resolve every URL to absolute up front.\n const modelUrl = new URL(CARD_DETECTION_CONFIG.MODEL_URL, location.href).href;\n const ortUrl = new URL(CARD_DETECTION_CONFIG.ORT_URL, location.href).href;\n const wasmDir = ortUrl.replace(/[^/]*$/, ''); // dir holding the .mjs + .wasm\n this.worker.postMessage({\n type: 'init',\n input: CARD_DETECTION_CONFIG.INPUT_SIZE,\n maxThreads: CARD_DETECTION_CONFIG.MAX_THREADS,\n modelUrl,\n ortUrl,\n wasmDir,\n });\n });\n return this.modelLoadPromise;\n }\n startDetectionLoop(onStateChange) {\n return __awaiter(this, void 0, void 0, function* () {\n if (this.rafId)\n return;\n this.stateChangeCallback = onStateChange;\n yield this.modelLoadPromise;\n if (!this.modelReady) {\n onStateChange(true); // model/worker failed — let the user capture anyway\n return;\n }\n this.lastFrameTime = 0;\n this.inferenceBusy = false;\n this.cardPresent = false;\n this.scoreEma = 0;\n this.consecutiveValidFrames = 0;\n this.consecutiveInvalidFrames = 0;\n this.isDocumentProperlyFramed = false;\n this.candidateBorder = 'none';\n this.candidateBorderCount = 0;\n this.activeBorder = 'none';\n this.rafId = requestAnimationFrame((now) => this._loopTick(now));\n });\n }\n stopDetectionLoop() {\n if (this.rafId) {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n this.inferenceBusy = false;\n this.cardPresent = false;\n this.scoreEma = 0;\n this.consecutiveValidFrames = 0;\n this.consecutiveInvalidFrames = 0;\n this.isDocumentProperlyFramed = false;\n this.candidateBorder = 'none';\n this.candidateBorderCount = 0;\n this.activeBorder = 'none';\n this.setBorderState('none');\n }\n // Terminal teardown — stops the loop and releases the worker. Call when the\n // camera is closed for good (card-camera `_cleanup`), not on pause.\n dispose() {\n this.stopDetectionLoop();\n if (this.worker) {\n this.worker.terminate();\n this.worker = null;\n }\n if (this.workerUrl) {\n URL.revokeObjectURL(this.workerUrl);\n this.workerUrl = null;\n }\n this.modelReady = false;\n this.modelLoadPromise = null;\n }\n setBorderState(state) {\n if (!this.overlayElement)\n return;\n const borders = [\n this.overlayElement.querySelector(`#${camera_1.ELEMENT_IDS.TOP_BORDER}`),\n this.overlayElement.querySelector(`#${camera_1.ELEMENT_IDS.BOTTOM_BORDER}`),\n ];\n borders.forEach(el => {\n if (!el)\n return;\n el.classList.remove('border-element--valid', 'border-element--invalid');\n if (state !== 'none')\n el.classList.add(`border-element--${state}`);\n });\n }\n _loopTick(now) {\n var _a;\n this.rafId = requestAnimationFrame((n) => this._loopTick(n));\n if (now - this.lastFrameTime < 1000 / CARD_DETECTION_CONFIG.THROTTLE_FPS)\n return;\n // Watchdog: a frame out longer than INFERENCE_STUCK_MS means the worker died or\n // dropped it. Clear the busy flag so we recover - otherwise it stays true forever\n // and detection just quietly stops.\n if (this.inferenceBusy) {\n if (now - this.inferenceStartedAt < CARD_DETECTION_CONFIG.INFERENCE_STUCK_MS)\n return;\n if (MainPage_1.enableImageDebug)\n console.warn('[card-detection] inference watchdog fired, resetting stuck frame');\n this.inferenceBusy = false;\n }\n if (!this.worker || !this.modelReady)\n return;\n if (!((_a = this.videoElement) === null || _a === void 0 ? void 0 : _a.videoWidth))\n return;\n this.lastFrameTime = now;\n this.inferenceBusy = true;\n this.inferenceStartedAt = now;\n // Grab the frame as a transferable ImageBitmap, shrunk during decode to about\n // INPUT_SIZE on the long side. Sending the full 1280x960 every time and resizing\n // in the worker was wasteful. Resolution doesn't matter to detection - the guide is\n // normalised and the worker letterboxes whatever it gets.\n const N = CARD_DETECTION_CONFIG.INPUT_SIZE;\n const vw = this.videoElement.videoWidth, vh = this.videoElement.videoHeight;\n const s = N / Math.max(vw, vh);\n const rw = Math.max(1, Math.round(vw * s)), rh = Math.max(1, Math.round(vh * s));\n createImageBitmap(this.videoElement, { resizeWidth: rw, resizeHeight: rh, resizeQuality: 'low' })\n .then((bitmap) => {\n if (!this.worker) {\n bitmap.close();\n this.inferenceBusy = false;\n return;\n }\n this.worker.postMessage({ type: 'frame', bitmap }, [bitmap]);\n })\n .catch(() => { this.inferenceBusy = false; });\n }\n // Worker posted a detection result — do the (cheap) framing geometry against\n // the current guide on the main thread, then debounce.\n _onResult(m) {\n var _a, _b, _c, _d, _e;\n this.inferenceBusy = false;\n if (!m.ok)\n return;\n this.lastInferMs = (_a = m.inferMs) !== null && _a !== void 0 ? _a : 0;\n const state = this._evaluateBox((_b = m.score) !== null && _b !== void 0 ? _b : 0, (_c = m.box) !== null && _c !== void 0 ? _c : null, (_d = m.W) !== null && _d !== void 0 ? _d : 0, (_e = m.H) !== null && _e !== void 0 ? _e : 0);\n this._updateBorderDebounced(state);\n this._updateDebounce(state);\n }\n // Turns a raw detection into a state: below the confidence gate is 'no-card', a card\n // spilling out of the guide or too small for it is 'invalid', otherwise 'valid'.\n _evaluateBox(score, box, W, H) {\n // Smooth the score first so one dropout frame can't kick us out of the locked\n // state. A frame with no box counts as 0 and pulls the average down.\n const a = CARD_DETECTION_CONFIG.CONF_EMA_ALPHA;\n this.scoreEma = a * (box ? score : 0) + (1 - a) * this.scoreEma;\n const conf = this.scoreEma;\n // Hysteresis: once we've locked onto a card we let the score sag to CONF_EXIT before\n // giving up; until then it has to clear the higher CONF_ENTER. Stops the flicker.\n const gate = this.cardPresent ? CARD_DETECTION_CONFIG.CONF_EXIT : CARD_DETECTION_CONFIG.CONF_ENTER;\n if (!box || conf <= gate) {\n this.cardPresent = false;\n this._trace('no-card', conf, null);\n return 'no-card';\n }\n this.cardPresent = true;\n const guide = this._computeNormalizedGuide();\n if (!guide || !W || !H) {\n this._trace('VALID', conf, null);\n return 'valid';\n } // no guide → conf-only\n const gx1 = guide.left * W, gy1 = guide.top * H;\n const gx2 = (guide.left + guide.width) * W, gy2 = (guide.top + guide.height) * H;\n const gArea = Math.max(1, (gx2 - gx1) * (gy2 - gy1));\n const gMin = Math.min(gx2 - gx1, gy2 - gy1);\n // fill = how much of the guide the card covers (card too far → low fill).\n const inter = Math.max(0, Math.min(box.x2, gx2) - Math.max(box.x1, gx1))\n * Math.max(0, Math.min(box.y2, gy2) - Math.max(box.y1, gy1));\n const fill = inter / gArea;\n // containment = card stays inside the guide (+slack); spilling out → \"out of box\".\n const eps = CARD_DETECTION_CONFIG.CONTAINMENT_SLACK_RATIO * gMin;\n const contained = box.x1 >= gx1 - eps && box.y1 >= gy1 - eps\n && box.x2 <= gx2 + eps && box.y2 <= gy2 + eps;\n let result;\n let reason;\n if (!contained) {\n result = 'invalid';\n reason = 'out-of-box';\n }\n else if (fill < CARD_DETECTION_CONFIG.MIN_FILL_RATIO) {\n result = 'invalid';\n reason = 'too-small';\n }\n else {\n result = 'valid';\n reason = 'VALID';\n }\n this._trace(reason, conf, fill);\n return result;\n }\n // Guide rect as fractions of the raw (un-mirrored) frame - the space the worker's boxes\n // are in. Two gotchas to undo:\n // 1. the <video> is object-fit:cover, so it scales the frame to fill the element and\n // crops the rest. That means a fraction of what you see on screen isn't the same\n // fraction of the real frame. Skip this and a card poking into the cropped-off strip\n // looks \"inside the guide\" to the model. So we map display fractions back through\n // the cover crop.\n // 2. on desktop the video is mirrored (scaleX(-1)), so flip X back.\n _computeNormalizedGuide() {\n if (!this.overlayElement || !this.videoElement)\n return null;\n const oRect = this.overlayElement.getBoundingClientRect();\n const vRect = this.videoElement.getBoundingClientRect();\n if (!vRect.width || !vRect.height)\n return null;\n const VW = this.videoElement.videoWidth, VH = this.videoElement.videoHeight;\n if (!VW || !VH)\n return null;\n // Guide as fractions of the DISPLAYED video box.\n let left = (oRect.left - vRect.left) / vRect.width;\n let top = (oRect.top - vRect.top) / vRect.height;\n let width = oRect.width / vRect.width;\n let height = oRect.height / vRect.height;\n // Walk those display fractions back through the (centred) cover crop.\n const videoAspect = VW / VH, displayAspect = vRect.width / vRect.height;\n if (videoAspect >= displayAspect) {\n // frame is wider than the element, so the sides get cropped, full height shows\n const visW = displayAspect / videoAspect;\n left = (1 - visW) / 2 + left * visW;\n width = width * visW;\n }\n else {\n // frame is taller than the element, so top/bottom get cropped, full width shows\n const visH = videoAspect / displayAspect;\n top = (1 - visH) / 2 + top * visH;\n height = height * visH;\n }\n if (!(0, deviceDetection_1.isMobileDevice)())\n left = 1 - left - width;\n return { left, top, width, height };\n }\n // Diagnostic console trace. Only logs when the state actually changes, so no spam.\n _trace(reason, conf, fill) {\n if (reason === this.lastReason)\n return;\n this.lastReason = reason;\n if (MainPage_1.enableImageDebug)\n console.log(`[detect] ${reason} | conf=${conf.toFixed(3)} fill=${fill == null ? '-' : fill.toFixed(2)} (min ${CARD_DETECTION_CONFIG.MIN_FILL_RATIO}) gate=${CARD_DETECTION_CONFIG.CONF_ENTER}/${CARD_DETECTION_CONFIG.CONF_EXIT} | infer=${this.lastInferMs.toFixed(0)}ms`);\n }\n // Border colour debounce, deliberately lopsided: going green needs BORDER_STABLE_FRAMES\n // good frames in a row so we don't flash green by mistake, but dropping green only needs\n // BORDER_CLEAR_FRAMES, so pulling the card out clears it almost immediately.\n _updateBorderDebounced(rawState) {\n const target = rawState === 'valid' ? 'valid' :\n rawState === 'no-card' ? 'none' :\n 'invalid';\n if (target === this.candidateBorder) {\n this.candidateBorderCount++;\n }\n else {\n this.candidateBorder = target;\n this.candidateBorderCount = 1;\n }\n const needed = target === 'valid'\n ? CARD_DETECTION_CONFIG.BORDER_STABLE_FRAMES\n : CARD_DETECTION_CONFIG.BORDER_CLEAR_FRAMES;\n if (this.candidateBorderCount >= needed && target !== this.activeBorder) {\n this.activeBorder = target;\n this.setBorderState(target);\n }\n }\n _updateDebounce(rawState) {\n var _a;\n const wasFramed = this.isDocumentProperlyFramed;\n if (rawState === 'valid') {\n this.consecutiveInvalidFrames = 0;\n this.consecutiveValidFrames++;\n if (!this.isDocumentProperlyFramed &&\n this.consecutiveValidFrames >= CARD_DETECTION_CONFIG.STABLE_FRAMES_TO_ENABLE) {\n this.isDocumentProperlyFramed = true;\n }\n }\n else {\n this.consecutiveValidFrames = 0;\n this.consecutiveInvalidFrames++;\n if (this.isDocumentProperlyFramed &&\n this.consecutiveInvalidFrames >= CARD_DETECTION_CONFIG.STABLE_FRAMES_TO_DISABLE) {\n this.isDocumentProperlyFramed = false;\n }\n }\n if (this.isDocumentProperlyFramed !== wasFramed) {\n (_a = this.stateChangeCallback) === null || _a === void 0 ? void 0 : _a.call(this, this.isDocumentProperlyFramed);\n }\n }\n}\nexports[\"default\"] = CARDDETECTIONSDK;\n\n\n//# sourceURL=webpack://PWUISDK/./src/plugins/card-detection.ts?");
|
|
4014
|
+
eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst id_1 = __webpack_require__(/*! ../constant/id */ \"./src/constant/id.ts\");\nconst camera_1 = __webpack_require__(/*! ../models/camera */ \"./src/models/camera.ts\");\n/** ID card, license, and credit card use smaller viewport than passport (identity card vs booklet) */\nconst ID_CARD_TYPES = [\n camera_1.CARD_TYPES.ID,\n camera_1.CARD_TYPES.ID_BACK,\n camera_1.CARD_TYPES.LICENSE,\n camera_1.CARD_TYPES.LICENSE_BACK,\n camera_1.CARD_TYPES.CC,\n camera_1.CARD_TYPES.CC_BACK,\n];\nclass CARDDETECTIONSDK {\n constructor(val) {\n this.type = camera_1.CARD_TYPES.ID;\n // html element\n this.videoElement = null;\n this.canvasElement = null;\n this.overlayElement = null;\n this.titleElement = null;\n Object.assign(this, val);\n }\n // use to calculate the cropped image size / ratio\n // ID card/license: smaller viewport (identity card size)\n // Passport/CC: larger viewport\n // All viewports constrained by absolute max-height to prevent header overlap\n // \n // IMPORTANT: This function calculates overlay dimensions in DISPLAY PIXELS\n // based on the video element's displayed size (clientWidth/clientHeight).\n // For image cropping, these dimensions need to be scaled to video stream pixels.\n calculateHeightNWidth(width, height) {\n var _a, _b;\n // Use actual video element display dimensions for overlay sizing\n // (These may differ from video stream dimensions due to CSS scaling)\n const videoWidth = ((_a = this.videoElement) === null || _a === void 0 ? void 0 : _a.clientWidth) || width;\n const videoHeight = ((_b = this.videoElement) === null || _b === void 0 ? void 0 : _b.clientHeight) || height;\n const idCardRatio = id_1.ID_CARD_RATIO[this.type] || id_1.ID_CARD_RATIO[\"others\"];\n const isDesktop = window.innerWidth >= id_1.VIEWPORT_SIZE.DESKTOP_BREAKPOINT;\n let newWidth;\n let newHeight;\n if (isDesktop) {\n // ID card/license/CC: smaller viewport (50% width, 35% height)\n // Passport only: larger viewport (65% width, 45% height)\n const isIdCard = ID_CARD_TYPES.includes(this.type);\n const maxWidthRatio = isIdCard\n ? id_1.VIEWPORT_SIZE.DESKTOP_ID_MAX_WIDTH_RATIO\n : id_1.VIEWPORT_SIZE.DESKTOP_PASSPORT_MAX_WIDTH_RATIO;\n const maxHeightRatio = isIdCard\n ? id_1.VIEWPORT_SIZE.DESKTOP_ID_MAX_HEIGHT_RATIO\n : id_1.VIEWPORT_SIZE.DESKTOP_PASSPORT_MAX_HEIGHT_RATIO;\n const maxWidth = videoWidth * maxWidthRatio;\n const maxHeight = videoHeight * maxHeightRatio;\n // Size by width first, then constrain by height if needed\n const widthBasedHeight = maxWidth / idCardRatio;\n const heightBasedWidth = maxHeight * idCardRatio;\n if (widthBasedHeight <= maxHeight) {\n newWidth = maxWidth;\n newHeight = widthBasedHeight;\n }\n else {\n newWidth = heightBasedWidth;\n newHeight = maxHeight;\n }\n // Apply absolute max-height constraint for all document types\n // This prevents overlay from overlapping with merchant logo/header\n if (newHeight > id_1.VIEWPORT_SIZE.MAX_OVERLAY_HEIGHT) {\n newHeight = id_1.VIEWPORT_SIZE.MAX_OVERLAY_HEIGHT;\n newWidth = newHeight * idCardRatio; // Maintain aspect ratio\n }\n }\n else {\n // Mobile: extend width to fit screen with margins\n const availableWidth = Math.min(videoWidth, window.innerWidth) -\n id_1.VIEWPORT_SIZE.MOBILE_HORIZONTAL_MARGIN * 2;\n newWidth = Math.max(availableWidth, 200); // min 200px for very small screens\n newHeight = newWidth / idCardRatio; // height = width / (width/height ratio)\n // Constrain height to fit within container with vertical padding\n const maxHeight = videoHeight - id_1.VIEWPORT_SIZE.MOBILE_HORIZONTAL_MARGIN * 2;\n if (maxHeight > 0 && newHeight > maxHeight) {\n newHeight = Math.max(maxHeight, 100);\n newWidth = newHeight * idCardRatio;\n }\n }\n return { width: newWidth, height: newHeight };\n }\n resizeElement() {\n var _a, _b, _c, _d, _e, _f;\n if (!this.videoElement || !this.canvasElement)\n return;\n const videoWidth = this.videoElement.clientWidth;\n const videoHeight = this.videoElement.clientHeight;\n // 1. resize canvas to match video size\n this.canvasElement.width = videoWidth;\n this.canvasElement.height = videoHeight;\n // 2. resize square overlay to match video size\n const { width, height } = this.calculateHeightNWidth(videoWidth, videoHeight);\n // All viewports now use corner borders with rounded corners\n (_a = this.overlayElement) === null || _a === void 0 ? void 0 : _a.style.setProperty(\"border-radius\", \"15px\");\n (_b = this.overlayElement) === null || _b === void 0 ? void 0 : _b.style.setProperty(\"border\", \"0px\");\n (_c = this.overlayElement) === null || _c === void 0 ? void 0 : _c.style.setProperty(\"width\", `${width}px`);\n (_d = this.overlayElement) === null || _d === void 0 ? void 0 : _d.style.setProperty(\"height\", `${height}px`);\n // 3. show border corner\n const topBorder = (_e = this.overlayElement) === null || _e === void 0 ? void 0 : _e.querySelector(`#${camera_1.ELEMENT_IDS.TOP_BORDER}`);\n topBorder === null || topBorder === void 0 ? void 0 : topBorder.style.setProperty(\"display\", \"inherit\");\n const bottomBorder = (_f = this.overlayElement) === null || _f === void 0 ? void 0 : _f.querySelector(`#${camera_1.ELEMENT_IDS.BOTTOM_BORDER}`);\n bottomBorder === null || bottomBorder === void 0 ? void 0 : bottomBorder.style.setProperty(\"display\", \"inherit\");\n }\n disableDetection() {\n var _a, _b;\n const topBorder = (_a = this.overlayElement) === null || _a === void 0 ? void 0 : _a.querySelector(`#${camera_1.ELEMENT_IDS.TOP_BORDER}`);\n topBorder === null || topBorder === void 0 ? void 0 : topBorder.style.setProperty(\"display\", \"none\");\n const bottomBorder = (_b = this.overlayElement) === null || _b === void 0 ? void 0 : _b.querySelector(`#${camera_1.ELEMENT_IDS.BOTTOM_BORDER}`);\n bottomBorder === null || bottomBorder === void 0 ? void 0 : bottomBorder.style.setProperty(\"display\", \"none\");\n }\n init(type) {\n if (type)\n this.type = type;\n this.resizeElement();\n }\n}\nexports[\"default\"] = CARDDETECTIONSDK;\n\n\n//# sourceURL=webpack://PWUISDK/./src/plugins/card-detection.ts?");
|
|
4015
4015
|
|
|
4016
4016
|
/***/ }),
|
|
4017
4017
|
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pipwave-ekyc-uikit",
|
|
3
|
-
"version": "3.0.5
|
|
3
|
+
"version": "3.0.5",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/pw-bundle.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
8
|
-
"dev": "
|
|
9
|
-
"build": "
|
|
8
|
+
"dev": "build_env=development webpack serve --mode=development --open",
|
|
9
|
+
"build": "build_env=production webpack"
|
|
10
10
|
},
|
|
11
11
|
"author": "",
|
|
12
12
|
"license": "ISC",
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
"@types/jquery": "^3.5.16",
|
|
15
15
|
"@types/pikaday": "^1.7.6",
|
|
16
16
|
"copy-webpack-plugin": "^11.0.0",
|
|
17
|
-
"cross-env": "^10.1.0",
|
|
18
17
|
"css-loader": "^6.8.1",
|
|
19
18
|
"html-webpack-plugin": "^5.5.3",
|
|
20
19
|
"postcss": "^8.4.26",
|
|
@@ -31,7 +30,7 @@
|
|
|
31
30
|
"webpack-dev-server": "^4.15.1"
|
|
32
31
|
},
|
|
33
32
|
"dependencies": {
|
|
34
|
-
|
|
33
|
+
"@types/pdfjs-dist": "^2.10.378",
|
|
35
34
|
"@types/w3c-image-capture": "^1.0.7",
|
|
36
35
|
"dotenv": "^16.3.1",
|
|
37
36
|
"dotenv-webpack": "^8.0.1",
|