accuraidscanplugin 1.0.25 → 1.0.26

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/accuraface2.js ADDED
@@ -0,0 +1,267 @@
1
+ function Utils(errorOutputId) {
2
+ // eslint-disable-line no-unused-vars
3
+ let self = this;
4
+ this.errorOutput = document.getElementById(errorOutputId);
5
+ this.apiKey = "168508101488d7JV8yvF32yRGRti0hyatBHFwev0KInaUAgtGv";
6
+
7
+ const OPENCV_URL = "opencv.js";
8
+ this.loadOpenCv = function (onloadCallback) {
9
+ let script = document.createElement("script");
10
+ script.setAttribute("async", "");
11
+ script.setAttribute("type", "text/javascript");
12
+ script.addEventListener("load", () => {
13
+ if (cv.getBuildInformation) {
14
+ console.log(cv.getBuildInformation());
15
+ onloadCallback();
16
+ } else {
17
+ // WASM
18
+ cv["onRuntimeInitialized"] = () => {
19
+ console.log(cv.getBuildInformation());
20
+ onloadCallback();
21
+ };
22
+ }
23
+ });
24
+ script.addEventListener("error", () => {
25
+ self.printError("Failed to load " + OPENCV_URL);
26
+ });
27
+ script.src = OPENCV_URL;
28
+ let node = document.getElementsByTagName("script")[0];
29
+ node.parentNode.insertBefore(script, node);
30
+ };
31
+
32
+ this.createFileFromUrl = function (path, url, callback) {
33
+ let request = new XMLHttpRequest();
34
+ request.open("GET", url, true);
35
+ request.responseType = "arraybuffer";
36
+ request.onload = function (ev) {
37
+ if (request.readyState === 4) {
38
+ if (request.status === 200) {
39
+ let data = new Uint8Array(request.response);
40
+ cv.FS_createDataFile("/", path, data, true, false, false);
41
+ callback();
42
+ } else {
43
+ self.printError(
44
+ "Failed to load " + url + " status: " + request.status
45
+ );
46
+ }
47
+ }
48
+ };
49
+ request.send();
50
+ };
51
+
52
+ this.loadImageToCanvas = function (url, cavansId) {
53
+ let canvas = document.getElementById(cavansId);
54
+ let ctx = canvas.getContext("2d");
55
+ let img = new Image();
56
+ img.crossOrigin = "anonymous";
57
+ img.onload = function () {
58
+ canvas.width = img.width;
59
+ canvas.height = img.height;
60
+ ctx.drawImage(img, 0, 0, img.width, img.height);
61
+ };
62
+ img.src = url;
63
+ };
64
+
65
+ this.executeCode = function (textAreaId) {
66
+ try {
67
+ this.clearError();
68
+ let code = document.getElementById(textAreaId).value;
69
+ eval(code);
70
+ } catch (err) {
71
+ this.printError(err);
72
+ }
73
+ };
74
+
75
+ this.clearError = function () {
76
+ this.errorOutput.innerHTML = "";
77
+ };
78
+
79
+ this.printError = function (err) {
80
+ if (typeof err === "undefined") {
81
+ err = "";
82
+ } else if (typeof err === "number") {
83
+ if (!isNaN(err)) {
84
+ if (typeof cv !== "undefined") {
85
+ err = "Exception: " + cv.exceptionFromPtr(err).msg;
86
+ }
87
+ }
88
+ } else if (typeof err === "string") {
89
+ let ptr = Number(err.split(" ")[0]);
90
+ if (!isNaN(ptr)) {
91
+ if (typeof cv !== "undefined") {
92
+ err = "Exception: " + cv.exceptionFromPtr(ptr).msg;
93
+ }
94
+ }
95
+ } else if (err instanceof Error) {
96
+ err = err.stack.replace(/\n/g, "<br>");
97
+ }
98
+ this.errorOutput.innerHTML = err;
99
+ };
100
+
101
+ this.loadCode = function (scriptId, textAreaId) {
102
+ let scriptNode = document.getElementById(scriptId);
103
+ let textArea = document.getElementById(textAreaId);
104
+ if (scriptNode.type !== "text/code-snippet") {
105
+ throw Error("Unknown code snippet type");
106
+ }
107
+ textArea.value = scriptNode.text.replace(/^\n/, "");
108
+ };
109
+
110
+ this.addFileInputHandler = function (fileInputId, canvasId) {
111
+ let inputElement = document.getElementById(fileInputId);
112
+ inputElement.addEventListener(
113
+ "change",
114
+ (e) => {
115
+ let files = e.target.files;
116
+ if (files.length > 0) {
117
+ let imgUrl = URL.createObjectURL(files[0]);
118
+ self.loadImageToCanvas(imgUrl, canvasId);
119
+ }
120
+ },
121
+ false
122
+ );
123
+ };
124
+
125
+ function onVideoCanPlay() {
126
+ if (self.onCameraStartedCallback) {
127
+ self.onCameraStartedCallback(self.stream, self.video);
128
+ }
129
+ }
130
+
131
+ this.startCamera = function (resolution, callback, videoId) {
132
+ const constraints = {
133
+ qvga: { width: { exact: 320 }, height: { exact: 240 } },
134
+ vga: { width: { exact: 640 }, height: { exact: 480 } },
135
+ };
136
+ let video = document.getElementById(videoId);
137
+ if (!video) {
138
+ video = document.createElement("video");
139
+ }
140
+
141
+ let videoConstraint = constraints[resolution];
142
+ if (!videoConstraint) {
143
+ videoConstraint = true;
144
+ }
145
+
146
+ navigator.mediaDevices
147
+ .getUserMedia({ video: videoConstraint, audio: false })
148
+ .then(function (stream) {
149
+ video.srcObject = stream;
150
+ video.play();
151
+ self.video = video;
152
+ self.stream = stream;
153
+ self.onCameraStartedCallback = callback;
154
+ video.addEventListener("canplay", onVideoCanPlay, false);
155
+ })
156
+ .catch(function (err) {
157
+ self.printError("Camera Error: " + err.name + " " + err.message);
158
+ });
159
+ };
160
+
161
+ this.stopCamera = function () {
162
+ if (this.video) {
163
+ this.video.pause();
164
+ this.video.srcObject = null;
165
+ this.video.removeEventListener("canplay", onVideoCanPlay);
166
+ }
167
+ if (this.stream) {
168
+ this.stream.getVideoTracks()[0].stop();
169
+ }
170
+ };
171
+
172
+ this.captureImage = function (canvasId) {
173
+ let canvas = document.getElementById(canvasId);
174
+ let dataUrl = canvas.toDataURL("image/jpeg");
175
+ return dataUrl;
176
+ };
177
+
178
+ this.stringFunction = function (dynamicString) {
179
+ console.log("Dynamic string:", dynamicString);
180
+
181
+ document.getElementById("status-text").innerText = dynamicString;
182
+ };
183
+
184
+ this.captureAndSend = function () {
185
+ let video = document.getElementById("cam_input");
186
+ let canvas = document.getElementById("canvas_output");
187
+
188
+ // Hide the video and show the canvas after capturing the photo
189
+ video.style.display = "none";
190
+ canvas.style.display = "block";
191
+ isCanvasVisible = true;
192
+
193
+ // Create a canvas element to temporarily hold the image data
194
+ let tempCanvas = document.createElement("canvas");
195
+ tempCanvas.width = video.videoWidth;
196
+ tempCanvas.height = video.videoHeight;
197
+ let ctx = tempCanvas.getContext("2d");
198
+ ctx.drawImage(video, 0, 0, tempCanvas.width, tempCanvas.height);
199
+
200
+ // Draw the oval shape on the temporary canvas
201
+ ctx.save();
202
+ ctx.beginPath();
203
+ ctx.moveTo(tempCanvas.width / 2, 0);
204
+ ctx.bezierCurveTo(
205
+ tempCanvas.width,
206
+ 0,
207
+ tempCanvas.width,
208
+ tempCanvas.height,
209
+ tempCanvas.width / 2,
210
+ tempCanvas.height
211
+ );
212
+ ctx.bezierCurveTo(0, tempCanvas.height, 0, 0, tempCanvas.width / 2, 0);
213
+ ctx.clip();
214
+ ctx.drawImage(tempCanvas, 0, 0);
215
+ ctx.restore();
216
+
217
+ let imageDataUrl = tempCanvas.toDataURL("image/jpeg");
218
+
219
+ // // Check if imageDataUrl is valid
220
+ // if (!imageDataUrl) {
221
+ // console.error("Invalid imageDataUrl");
222
+ // return;
223
+ // }
224
+
225
+ // // Send the captured image to the API
226
+ // fetch("https://accurascan.com/v2/api/liveness", {
227
+ // method: "POST",
228
+ // headers: {
229
+ // "Api-Key": self.apiKey,
230
+ // "Content-Type": "application/json",
231
+ // },
232
+ // body: JSON.stringify({
233
+ // liveness_image: imageDataUrl,
234
+ // }),
235
+ // })
236
+ // .then((response) => {
237
+ // // Check if the response is successful (status code 2xx)
238
+ // if (!response.ok) {
239
+ // throw new Error(
240
+ // `Network response was not ok, status: ${response.status}`
241
+ // );
242
+ // }
243
+ // return response.json(); // Parse response body as JSON
244
+ // })
245
+ // .then(function (data) {
246
+ // console.log("API response:", data);
247
+
248
+ // // Check the "status" property in the data object and display appropriate messages
249
+ // if (data.status === true) {
250
+ // self.stringFunction(
251
+ // "Face detected! Quality: " +
252
+ // data.data.quality +
253
+ // ", Score: " +
254
+ // data.data.score
255
+ // );
256
+ // //When face is detected
257
+ // } else {
258
+ // self.stringFunction("No face detected or other status");
259
+ // // When no face is detected or handle other status scenarios if needed
260
+ // }
261
+ // })
262
+ // .catch((error) => {
263
+ // console.error("Error sending image to API:", error);
264
+ // self.stringFunction("Error sending image to API");
265
+ // });
266
+ };
267
+ }
@@ -1 +1 @@
1
- export default class IDCardPlugin{constructor(t,{countryCode:e,cardCode:i,topTextSize:n,topTextColor:s,topTextWeight:a,bottomTextSize:o,bottomTextColor:r,bottomTextWeight:c,bottomTextText:d}){this.callback=t,this.country_code=e,this.card_code=i,this.countriesData=[],this.frontStream=null,this.backStream=null,this.uaParserLoaded="undefined"!=typeof UAParser,this.frontCapture=null,this.backCapture=null,this.result={front:null,back:null},this.topInstructSize=n,this.topInstructColor=s,this.topInstructWeight=a,this.InstructSize=o,this.InstructWeight=c,this.InstructColor=r,this.InstructText=d;const l=document.createElement("script");l.src="./node_modules/accuraidscanplugin/public/libs/piexif.js",document.head.appendChild(l),this.ding=new Audio("./node_modules/accuraidscanplugin/public/audio/ding.mp3"),this.ding.preload="auto",this.audioUnlocked=!1,this.ding.muted=!0;const h=()=>{this.audioUnlocked||(this.ding.play().then((()=>{this.ding.pause(),this.ding.currentTime=0,this.ding.muted=!1,this.audioUnlocked=!0})).catch((()=>{})),document.removeEventListener("click",h))};document.addEventListener("click",h,{once:!0}),this.selectedCard=null,this.init()}async init(){try{const t=await fetch("./node_modules/accuraidscanplugin/src/js.json");if(!t.ok)throw new Error("Failed to load data");this.countriesData=await t.json(),this.loadStyles(),await this.setSelectedCard(),this.startCamera()}catch(t){console.error("Error loading countries data:",t)}}async setSelectedCard(){const t=this.countriesData.find((t=>t.country_code===this.country_code));if(!t)return void console.error(`Country with code ${this.country_code} not found`);let e=null,i=null,n=null;for(const s of t.cards||[])if(s.allcard&&Array.isArray(s.allcard)&&(e=s.allcard.find((t=>t.card_code===this.card_code)),e)){n=s,i=2===s.allcard.length?s.allcard.find((t=>t.card_code!==this.card_code)):null;break}e?this.selectedCard={country_code:t.country_code,card_code:e.card_code,country:t,frontCard:e,backCard:i,requiresBack:!!i}:console.error(`Card with code ${this.card_code} not found for country ${this.country_code}`)}loadStyles(){if(!document.querySelector('link[href*="all.min.css"]')){const t=document.createElement("link");t.rel="stylesheet",t.href="./node_modules/accuraidscanplugin/public/fontawesome-free/css/all.min.css",document.head.appendChild(t)}}startCamera(){if(this.selectedCard)if(this.createCameraUI(),"undefined"!=typeof cv&&cv.getBuildInformation)this.startCameraProcessing();else{const t=document.createElement("script");t.src="./node_modules/accuraidscanplugin/accuraface1.js",t.onload=()=>{cv.onRuntimeInitialized=()=>this.startCameraProcessing()},document.body.appendChild(t)}else console.error("No card selected. Cannot start camera.")}createCameraUI(){this.cameraContainer=document.createElement("div"),this.cameraContainer.className="camera-container",this.cameraContainer.style.position="fixed",this.cameraContainer.style.top="0",this.cameraContainer.style.left="0",this.cameraContainer.style.width="100%",this.cameraContainer.style.height="100%",this.cameraContainer.style.display="flex",this.cameraContainer.style.justifyContent="center",this.cameraContainer.style.alignItems="center",this.cameraContainer.style.background="rgba(0,0,0,0.8)",this.cameraContainer.style.zIndex="2000",document.body.appendChild(this.cameraContainer),this.video=document.createElement("video"),this.video.id="video",this.video.autoplay=!0,this.video.playsInline=!0,this.video.style.width="auto",this.video.style.height="100%",this.video.style.objectFit="cover",this.video.style.position="absolute",this.video.style.top="0",this.video.style.left="50%",this.video.style.transform="translateX(-50%)",this.cameraContainer.appendChild(this.video),this.canvas=document.createElement("canvas"),this.canvas.id="canvas",this.canvas.style.display="none",this.canvas.style.transform="scaleX(-1)",this.cameraContainer.appendChild(this.canvas),this.scanFrame=document.createElement("div"),this.scanFrame.className="scan-frame",this.scanFrame.style.position="absolute",this.scanFrame.style.top="50%",this.scanFrame.style.left="50%",this.scanFrame.style.transform="translate(-50%, -50%)",this.scanFrame.style.border="2px solid red",this.scanFrame.style.boxSizing="border-box",this.scanFrame.style.boxShadow="0 0 0 9999px rgba(0, 0, 0, 0.6)",window.innerWidth<=767?(this.scanFrame.style.width="90vw",this.scanFrame.style.height="50vw",this.scanFrame.style.maxWidth="350px",this.scanFrame.style.maxHeight="200px"):window.innerWidth<=1024?(this.scanFrame.style.width="60vw",this.scanFrame.style.height="40vw",this.scanFrame.style.maxWidth="600px",this.scanFrame.style.maxHeight="400px"):(this.scanFrame.style.width="50vw",this.scanFrame.style.height="30vw",this.scanFrame.style.maxWidth="800px",this.scanFrame.style.maxHeight="500px"),this.cameraContainer.appendChild(this.scanFrame),this.instructionText=document.createElement("div"),this.instructionText.className="instruction-text",this.instructionText.id="instructionText",this.instructionText.textContent=this.InstructText||"Keep Document in Frame",this.instructionText.style.position="absolute",this.instructionText.style.left="50%",this.instructionText.style.transform="translateX(-50%)",this.instructionText.style.padding="8px 12px",this.instructionText.style.borderRadius="6px",this.instructionText.style.pointerEvents="none",this.instructionText.style.textAlign="center",this.instructionText.style.fontSize=this.InstructSize||"0.8rem",this.instructionText.style.fontWeight=this.InstructWeight||"450",this.instructionText.style.width="100%",this.instructionText.style.maxWidth="100%",this.instructionText.style.zIndex="8000",this.instructionText.style.color=this.InstructColor||"#fff",this.instructionText.style.bottom="10%",this.cameraContainer.appendChild(this.instructionText),this.topInstructionText=document.createElement("div"),this.topInstructionText.className="top-instruction-text",this.topInstructionText.id="topInstructionText",this.topInstructionText.style.position="absolute",this.topInstructionText.style.left="50%",this.topInstructionText.style.transform="translateX(-50%)",this.topInstructionText.style.padding="8px 12px",this.topInstructionText.style.borderRadius="6px",this.topInstructionText.style.pointerEvents="none",this.topInstructionText.style.textAlign="center",this.topInstructionText.style.fontSize=this.topInstructSize||"0.8rem",this.topInstructionText.style.fontWeight=this.topInstructWeight||"450",this.topInstructionText.style.width="100%",this.topInstructionText.style.maxWidth="100%",this.topInstructionText.style.zIndex="8000",this.topInstructionText.style.color=this.topInstructColor||"#fff",this.topInstructionText.style.top="10%",this.cameraContainer.appendChild(this.topInstructionText)}startCameraProcessing(){const{country:t,REWARDS:e,frontCard:i,backCard:n,requiresBack:s}=this.selectedCard;let a=i.card_code,o=.12,r=.12;"CLMIDN"===a&&(o=.09,r=.1),"CLMID"===a&&(o=.1,r=.1),"COLPAF"===a&&(o=.09,r=.1),"CLMDL"===a&&(o=.11,r=.1),"COLCIF"===a&&(o=.08,r=.09),"UGNIDF"===a&&(o=.1,r=.12);let c="CLMIDN"===a?`Scan Front Side of ${t.country_name} National ID Card New`:"CLMID"===a?`Scan Front Side of ${t.country_name} National ID Card`:"COLPAF"===a?`Scan Front Side of ${t.country_name}'s Passport`:"CLMDL"===a?`Scan Front Side of ${t.country_name}'s Driving License`:"COLCIF"===a?`Scan Front Side of ${t.country_name}'s Citizen Card`:"UGNIDF"===a?`Scan Front Side of ${t.country_name}'s National ID Card`:"Scanning front side...";this.topInstructionText.textContent=c,this.instructionText.textContent="Keep Document in Frame";const d=new Image;d.src="data:image/jpeg;base64,"+i.card_img;let l=!1,h=0,m=0,u=!1;d.onload=()=>{const e=cv.imread(d);let a=Math.round(.15*e.rows),c=e.roi(new cv.Rect(0,0,e.cols,a));navigator.mediaDevices.getUserMedia({video:{width:{ideal:1920},height:{ideal:1080},facingMode:{ideal:"environment"},frameRate:{ideal:60,max:60}}}).then((a=>{this.frontStream=a,this.video.srcObject=this.frontStream,this.video.addEventListener("loadedmetadata",(()=>{this.canvas.width=this.video.videoWidth,this.canvas.height=this.video.videoHeight}));const d=a=>{if(!this.frontStream||!this.frontStream.active||l)return void requestAnimationFrame(d);const p=this.video.getBoundingClientRect(),y=this.scanFrame.getBoundingClientRect();this.instructionText.style.top=y.bottom+10+"px",this.topInstructionText.style.top=y.top-35+"px";const x=this.video.videoWidth/p.width,C=this.video.videoHeight/p.height,f=(y.left-p.left)*x,g=(y.top-p.top)*C,v=y.width*x,T=y.height*C;if(v>0&&T>0){const a=document.createElement("canvas");a.width=v,a.height=T;a.getContext("2d").drawImage(this.video,f,g,v,T,0,0,v,T);const d=cv.imread(a),p=this.multiScaleTemplateMatch(d,e);if(p.maxVal>=o){const e=this.multiScaleTemplateMatch(d,c);e.maxVal>=r&&(h++,3===h&&(l=!0,this.frontStream.getTracks().forEach((t=>t.stop())),this.processCapturedFrame(a,t,i,p,e,"front").then((()=>{if(s&&n){this.audioUnlocked&&(this.ding.currentTime=0,this.ding.play().catch((()=>{})));const e=document.createElement("div");e.id="flipAnimation",e.innerHTML='<i class="fas fa-id-card"></i>',e.style.animation="flipAnimation 1s linear forwards",e.style.position="absolute",e.style.top="50%",e.style.left="50%",e.style.width="50px",e.style.height="50px",e.style.transform="translate(-50%, -50%)",e.style.fontSize="48px",e.style.color="#e53935",this.cameraContainer.appendChild(e),setTimeout((()=>{e.parentNode===this.cameraContainer&&this.cameraContainer.removeChild(e),this.startBackCameraProcessing(t,n)}),1e3)}}))))}m++,m%20!=0||u||(u=!0,this.instructionText.textContent="Keep Document Near to Camera",setTimeout((()=>{l||(this.instructionText.textContent="Keep Document in Frame"),u=!1}),1200)),d.delete()}requestAnimationFrame(d)};requestAnimationFrame(d)})).catch((t=>{console.error("Front camera error:",t)}))}}startBackCameraProcessing(t,e){let i=.1,n=.12;"UGNIDB"===e.card_code&&(i=.12,n=.12);let s="COLIDB"===e.card_code?`Scan Back Side of ${t.country_name} National ID Card New`:"COLMIDB"===e.card_code?`Scan Back Side of ${t.country_name} National ID Card`:"COLCIB"===e.card_code?`Scan Back Side of ${t.country_name} Citizen Card`:"UGNIDB"===e.card_code?`Scan Back Side of ${t.country_name}'s National ID Card`:"Scanning back side...";this.topInstructionText.textContent=s,this.instructionText.textContent="Keep Document in Frame";const a=new Image;a.src="data:image/jpeg;base64,"+e.card_img;let o=!1,r=0,c=0,d=!1;a.onload=()=>{const s=cv.imread(a);let l=Math.round(.35*s.rows),h=s.roi(new cv.Rect(0,0,s.cols,l));navigator.mediaDevices.getUserMedia({video:{width:{ideal:1920},height:{ideal:1080},facingMode:{ideal:"environment"},frameRate:{ideal:60,max:60}}}).then((a=>{this.backStream=a,this.video.srcObject=this.backStream,this.video.addEventListener("loadedmetadata",(()=>{this.canvas.width=this.video.videoWidth,this.canvas.height=this.video.videoHeight}));const l=a=>{if(!this.backStream||!this.backStream.active||o)return void requestAnimationFrame(l);const m=this.video.getBoundingClientRect(),u=this.scanFrame.getBoundingClientRect();this.instructionText.style.top=u.bottom+10+"px",this.topInstructionText.style.top=u.top-35+"px";const p=this.video.videoWidth/m.width,y=this.video.videoHeight/m.height,x=(u.left-m.left)*p,C=(u.top-m.top)*y,f=u.width*p,g=u.height*y;if(f>0&&g>0){const a=document.createElement("canvas");a.width=f,a.height=g;a.getContext("2d").drawImage(this.video,x,C,f,g,0,0,f,g);const l=cv.imread(a),m=this.multiScaleTemplateMatch(l,s);if(m.maxVal>=i){const i=this.multiScaleTemplateMatch(l,h);i.maxVal>=n&&(r++,3===r&&(o=!0,this.backStream.getTracks().forEach((t=>t.stop())),this.processCapturedFrame(a,t,e,m,i,"back")))}c++,c%20!=0||d||(d=!0,this.instructionText.textContent="Keep Document Near to Camera",setTimeout((()=>{o||(this.instructionText.textContent="Keep Document in Frame"),d=!1}),1200)),l.delete()}requestAnimationFrame(l)};requestAnimationFrame(l)})).catch((t=>{console.error("Back camera error:",t)}))}}multiScaleTemplateMatch(t,e){let i=null,n=1,s=0;const a=new cv.Mat,o=new cv.Mat;cv.resize(e,o,new cv.Size(e.cols,e.rows));const r=new cv.Mat;cv.cvtColor(o,r,cv.COLOR_RGBA2GRAY),cv.Canny(r,r,60,255);for(let e=1;e<=2;e+=.1){const o=new cv.Mat,c=Math.round(t.cols/e),d=Math.round(t.rows/e);cv.resize(t,o,new cv.Size(c,d));let l=o.cols<r.cols||o.rows<r.rows?new cv.Mat:r;if(o.cols<r.cols||o.rows<r.rows){let t=Math.min(o.cols/r.cols,o.rows/r.rows);cv.resize(r,l,new cv.Size(Math.round(r.cols*t),Math.round(r.rows*t)))}const h=new cv.Mat;cv.cvtColor(o,h,cv.COLOR_RGBA2GRAY),cv.Canny(h,h,60,255);try{cv.matchTemplate(h,l,a,cv.TM_CCOEFF_NORMED)}catch(t){console.error("Error in matchTemplate at scale",e,t)}const m=cv.minMaxLoc(a);m.maxVal>s&&(s=m.maxVal,i=m,n=e),h.delete(),(o.cols<r.cols||o.rows<r.rows)&&l.delete(),o.delete()}return o.delete(),r.delete(),a.delete(),{bestMatch:i,bestScale:n,maxVal:s}}async processCapturedFrame(canvas,t,e,i,n,s){this.showLoadingAnimation(),this.instructionText.textContent="Processing...";try{const t=await new Promise((t=>canvas.toBlob(t,"image/jpeg",.9))),e={"0th":{[piexif.ImageIFD.Make]:"AutoID",[piexif.ImageIFD.Model]:"IDDetectionCamera"}},i=piexif.dump(e),n=piexif.insert(i,canvas.toDataURL("image/jpeg",.92));await new Promise((e=>{const i=new FileReader;i.onload=()=>e(i.result),i.readAsDataURL(t)}));"front"===s?this.result.front=n:"back"===s&&(this.result.back=n),!this.selectedCard.requiresBack||this.result.back?(this.callback(this.result),this.hideLoadingAnimation(),setTimeout((()=>{this.stopAllStreams(),this.cameraContainer.remove()}),1e3)):this.hideLoadingAnimation()}catch(t){console.error("Error processing captured frame:",t),this.hideLoadingAnimation(),this.instructionText.textContent="Error processing image. Please try again."}}showLoadingAnimation(){const t=document.createElement("div");t.className="loading-spinner",t.innerHTML='<i class="fas fa-spinner"></i>',t.style.position="absolute",t.style.top="50%",t.style.left="50%",t.style.transform="translate(-50%, -50%)",t.style.zIndex="3500";const e=t.querySelector("i");e.style.fontSize="48px",e.style.animation="spin 1s linear infinite",e.style.color="#e53935",this.cameraContainer.appendChild(t),this.loadingSpinner=t}hideLoadingAnimation(){this.loadingSpinner&&this.loadingSpinner.parentNode===this.cameraContainer&&this.cameraContainer.removeChild(this.loadingSpinner)}stopAllStreams(){this.frontStream&&(this.frontStream.getTracks().forEach((t=>t.stop())),this.frontStream=null),this.backStream&&(this.backStream.getTracks().forEach((t=>t.stop())),this.backStream=null)}}const style=document.createElement("style");style.textContent="\n@keyframes spin { \n from { transform: rotate(0deg); } \n to { transform: rotate(360deg); } \n}\n@keyframes flipAnimation { \n from { transform: translate(-50%, -50%) rotateY(0deg); } \n to { transform: translate(-50%, -50%) rotateY(360deg); } \n}\n",document.head.appendChild(style);
1
+ export default class IDCardPlugin{constructor(t,{countryCode:e,cardCode:i,topTextSize:n,topTextColor:s,topTextWeight:a,bottomTextSize:o,bottomTextColor:r,bottomTextWeight:c,bottomTextText:d}){this.callback=t,this.country_code=e,this.card_code=i,this.countriesData=[],this.frontStream=null,this.backStream=null,this.uaParserLoaded="undefined"!=typeof UAParser,this.frontCapture=null,this.backCapture=null,this.result={front:null,back:null},this.topInstructSize=n,this.topInstructColor=s,this.topInstructWeight=a,this.InstructSize=o,this.InstructWeight=c,this.InstructColor=r,this.InstructText=d;const l=document.createElement("script");l.src="/libs/piexif.js",document.head.appendChild(l),this.ding=new Audio("/audio/ding.mp3"),this.ding.preload="auto",this.audioUnlocked=!1,this.ding.muted=!0;const h=()=>{this.audioUnlocked||(this.ding.play().then((()=>{this.ding.pause(),this.ding.currentTime=0,this.ding.muted=!1,this.audioUnlocked=!0})).catch((()=>{})),document.removeEventListener("click",h))};document.addEventListener("click",h,{once:!0}),this.selectedCard=null,this.init()}async init(){try{const t=await fetch("/accura/js.json");if(!t.ok)throw new Error("Failed to load data");this.countriesData=await t.json(),this.loadStyles(),await this.setSelectedCard(),this.startCamera()}catch(t){console.error("Error loading countries data:",t)}}async setSelectedCard(){const t=this.countriesData.find((t=>t.country_code===this.country_code));if(!t)return void console.error(`Country with code ${this.country_code} not found`);let e=null,i=null,n=null;for(const s of t.cards||[])if(s.allcard&&Array.isArray(s.allcard)&&(e=s.allcard.find((t=>t.card_code===this.card_code)),e)){n=s,i=2===s.allcard.length?s.allcard.find((t=>t.card_code!==this.card_code)):null;break}e?this.selectedCard={country_code:t.country_code,card_code:e.card_code,country:t,frontCard:e,backCard:i,requiresBack:!!i}:console.error(`Card with code ${this.card_code} not found for country ${this.country_code}`)}loadStyles(){if(!document.querySelector('link[href*="all.min.css"]')){const t=document.createElement("link");t.rel="stylesheet",t.href="/fontawesome-free/css/all.min.css",document.head.appendChild(t)}}startCamera(){if(this.selectedCard)if(this.createCameraUI(),"undefined"!=typeof cv&&cv.getBuildInformation)this.startCameraProcessing();else{const t=document.createElement("script");t.src="/accuraface1.js",t.onload=()=>{cv.onRuntimeInitialized=()=>this.startCameraProcessing()},document.body.appendChild(t)}else console.error("No card selected. Cannot start camera.")}createCameraUI(){this.cameraContainer=document.createElement("div"),this.cameraContainer.className="camera-container",this.cameraContainer.style.position="fixed",this.cameraContainer.style.top="0",this.cameraContainer.style.left="0",this.cameraContainer.style.width="100%",this.cameraContainer.style.height="100%",this.cameraContainer.style.display="flex",this.cameraContainer.style.justifyContent="center",this.cameraContainer.style.alignItems="center",this.cameraContainer.style.background="rgba(0,0,0,0.8)",this.cameraContainer.style.zIndex="2000",document.body.appendChild(this.cameraContainer),this.video=document.createElement("video"),this.video.id="video",this.video.autoplay=!0,this.video.playsInline=!0,this.video.style.width="auto",this.video.style.height="100%",this.video.style.objectFit="cover",this.video.style.position="absolute",this.video.style.top="0",this.video.style.left="50%",this.video.style.transform="translateX(-50%)",this.cameraContainer.appendChild(this.video),this.canvas=document.createElement("canvas"),this.canvas.id="canvas",this.canvas.style.display="none",this.canvas.style.transform="scaleX(-1)",this.cameraContainer.appendChild(this.canvas),this.scanFrame=document.createElement("div"),this.scanFrame.className="scan-frame",this.scanFrame.style.position="absolute",this.scanFrame.style.top="50%",this.scanFrame.style.left="50%",this.scanFrame.style.transform="translate(-50%, -50%)",this.scanFrame.style.border="2px solid red",this.scanFrame.style.boxSizing="border-box",this.scanFrame.style.boxShadow="0 0 0 9999px rgba(0, 0, 0, 0.6)",window.innerWidth<=767?(this.scanFrame.style.width="90vw",this.scanFrame.style.height="50vw",this.scanFrame.style.maxWidth="350px",this.scanFrame.style.maxHeight="200px"):window.innerWidth<=1024?(this.scanFrame.style.width="60vw",this.scanFrame.style.height="40vw",this.scanFrame.style.maxWidth="600px",this.scanFrame.style.maxHeight="400px"):(this.scanFrame.style.width="50vw",this.scanFrame.style.height="30vw",this.scanFrame.style.maxWidth="800px",this.scanFrame.style.maxHeight="500px"),this.cameraContainer.appendChild(this.scanFrame),this.instructionText=document.createElement("div"),this.instructionText.className="instruction-text",this.instructionText.id="instructionText",this.instructionText.textContent=this.InstructText||"Keep Document in Frame",this.instructionText.style.position="absolute",this.instructionText.style.left="50%",this.instructionText.style.transform="translateX(-50%)",this.instructionText.style.padding="8px 12px",this.instructionText.style.borderRadius="6px",this.instructionText.style.pointerEvents="none",this.instructionText.style.textAlign="center",this.instructionText.style.fontSize=this.InstructSize||"0.8rem",this.instructionText.style.fontWeight=this.InstructWeight||"450",this.instructionText.style.width="100%",this.instructionText.style.maxWidth="100%",this.instructionText.style.zIndex="8000",this.instructionText.style.color=this.InstructColor||"#fff",this.instructionText.style.bottom="10%",this.cameraContainer.appendChild(this.instructionText),this.topInstructionText=document.createElement("div"),this.topInstructionText.className="top-instruction-text",this.topInstructionText.id="topInstructionText",this.topInstructionText.style.position="absolute",this.topInstructionText.style.left="50%",this.topInstructionText.style.transform="translateX(-50%)",this.topInstructionText.style.padding="8px 12px",this.topInstructionText.style.borderRadius="6px",this.topInstructionText.style.pointerEvents="none",this.topInstructionText.style.textAlign="center",this.topInstructionText.style.fontSize=this.topInstructSize||"0.8rem",this.topInstructionText.style.fontWeight=this.topInstructWeight||"450",this.topInstructionText.style.width="100%",this.topInstructionText.style.maxWidth="100%",this.topInstructionText.style.zIndex="8000",this.topInstructionText.style.color=this.topInstructColor||"#fff",this.topInstructionText.style.top="10%",this.cameraContainer.appendChild(this.topInstructionText)}startCameraProcessing(){const{country:t,REWARDS:e,frontCard:i,backCard:n,requiresBack:s}=this.selectedCard;let a=i.card_code,o=.12,r=.12;"CLMIDN"===a&&(o=.09,r=.1),"CLMID"===a&&(o=.1,r=.1),"COLPAF"===a&&(o=.09,r=.1),"CLMDL"===a&&(o=.11,r=.1),"COLCIF"===a&&(o=.08,r=.09),"UGNIDF"===a&&(o=.1,r=.12);let c="CLMIDN"===a?`Scan Front Side of ${t.country_name} National ID Card New`:"CLMID"===a?`Scan Front Side of ${t.country_name} National ID Card`:"COLPAF"===a?`Scan Front Side of ${t.country_name}'s Passport`:"CLMDL"===a?`Scan Front Side of ${t.country_name}'s Driving License`:"COLCIF"===a?`Scan Front Side of ${t.country_name}'s Citizen Card`:"UGNIDF"===a?`Scan Front Side of ${t.country_name}'s National ID Card`:"Scanning front side...";this.topInstructionText.textContent=c,this.instructionText.textContent="Keep Document in Frame";const d=new Image;d.src="data:image/jpeg;base64,"+i.card_img;let l=!1,h=0,m=0,u=!1;d.onload=()=>{const e=cv.imread(d);let a=Math.round(.15*e.rows),c=e.roi(new cv.Rect(0,0,e.cols,a));navigator.mediaDevices.getUserMedia({video:{width:{ideal:1920},height:{ideal:1080},facingMode:{ideal:"environment"},frameRate:{ideal:60,max:60}}}).then((a=>{this.frontStream=a,this.video.srcObject=this.frontStream,this.video.addEventListener("loadedmetadata",(()=>{this.canvas.width=this.video.videoWidth,this.canvas.height=this.video.videoHeight}));const d=a=>{if(!this.frontStream||!this.frontStream.active||l)return void requestAnimationFrame(d);const p=this.video.getBoundingClientRect(),y=this.scanFrame.getBoundingClientRect();this.instructionText.style.top=y.bottom+10+"px",this.topInstructionText.style.top=y.top-35+"px";const x=this.video.videoWidth/p.width,C=this.video.videoHeight/p.height,f=(y.left-p.left)*x,v=(y.top-p.top)*C,g=y.width*x,T=y.height*C;if(g>0&&T>0){const a=document.createElement("canvas");a.width=g,a.height=T;a.getContext("2d").drawImage(this.video,f,v,g,T,0,0,g,T);const d=cv.imread(a),p=this.multiScaleTemplateMatch(d,e);if(p.maxVal>=o){const e=this.multiScaleTemplateMatch(d,c);e.maxVal>=r&&(h++,3===h&&(l=!0,this.frontStream.getTracks().forEach((t=>t.stop())),this.processCapturedFrame(a,t,i,p,e,"front").then((()=>{if(s&&n){this.audioUnlocked&&(this.ding.currentTime=0,this.ding.play().catch((()=>{})));const e=document.createElement("div");e.id="flipAnimation",e.innerHTML='<i class="fas fa-id-card"></i>',e.style.animation="flipAnimation 1s linear forwards",e.style.position="absolute",e.style.top="50%",e.style.left="50%",e.style.width="50px",e.style.height="50px",e.style.transform="translate(-50%, -50%)",e.style.fontSize="48px",e.style.color="#e53935",this.cameraContainer.appendChild(e),setTimeout((()=>{e.parentNode===this.cameraContainer&&this.cameraContainer.removeChild(e),this.startBackCameraProcessing(t,n)}),1e3)}}))))}m++,m%20!=0||u||(u=!0,this.instructionText.textContent="Keep Document Near to Camera",setTimeout((()=>{l||(this.instructionText.textContent="Keep Document in Frame"),u=!1}),1200)),d.delete()}requestAnimationFrame(d)};requestAnimationFrame(d)})).catch((t=>{console.error("Front camera error:",t)}))}}startBackCameraProcessing(t,e){let i=.1,n=.12;"UGNIDB"===e.card_code&&(i=.12,n=.12);let s="COLIDB"===e.card_code?`Scan Back Side of ${t.country_name} National ID Card New`:"COLMIDB"===e.card_code?`Scan Back Side of ${t.country_name} National ID Card`:"COLCIB"===e.card_code?`Scan Back Side of ${t.country_name} Citizen Card`:"UGNIDB"===e.card_code?`Scan Back Side of ${t.country_name}'s National ID Card`:"Scanning back side...";this.topInstructionText.textContent=s,this.instructionText.textContent="Keep Document in Frame";const a=new Image;a.src="data:image/jpeg;base64,"+e.card_img;let o=!1,r=0,c=0,d=!1;a.onload=()=>{const s=cv.imread(a);let l=Math.round(.35*s.rows),h=s.roi(new cv.Rect(0,0,s.cols,l));navigator.mediaDevices.getUserMedia({video:{width:{ideal:1920},height:{ideal:1080},facingMode:{ideal:"environment"},frameRate:{ideal:60,max:60}}}).then((a=>{this.backStream=a,this.video.srcObject=this.backStream,this.video.addEventListener("loadedmetadata",(()=>{this.canvas.width=this.video.videoWidth,this.canvas.height=this.video.videoHeight}));const l=a=>{if(!this.backStream||!this.backStream.active||o)return void requestAnimationFrame(l);const m=this.video.getBoundingClientRect(),u=this.scanFrame.getBoundingClientRect();this.instructionText.style.top=u.bottom+10+"px",this.topInstructionText.style.top=u.top-35+"px";const p=this.video.videoWidth/m.width,y=this.video.videoHeight/m.height,x=(u.left-m.left)*p,C=(u.top-m.top)*y,f=u.width*p,v=u.height*y;if(f>0&&v>0){const a=document.createElement("canvas");a.width=f,a.height=v;a.getContext("2d").drawImage(this.video,x,C,f,v,0,0,f,v);const l=cv.imread(a),m=this.multiScaleTemplateMatch(l,s);if(m.maxVal>=i){const i=this.multiScaleTemplateMatch(l,h);i.maxVal>=n&&(r++,3===r&&(o=!0,this.backStream.getTracks().forEach((t=>t.stop())),this.processCapturedFrame(a,t,e,m,i,"back")))}c++,c%20!=0||d||(d=!0,this.instructionText.textContent="Keep Document Near to Camera",setTimeout((()=>{o||(this.instructionText.textContent="Keep Document in Frame"),d=!1}),1200)),l.delete()}requestAnimationFrame(l)};requestAnimationFrame(l)})).catch((t=>{console.error("Back camera error:",t)}))}}multiScaleTemplateMatch(t,e){let i=null,n=1,s=0;const a=new cv.Mat,o=new cv.Mat;cv.resize(e,o,new cv.Size(e.cols,e.rows));const r=new cv.Mat;cv.cvtColor(o,r,cv.COLOR_RGBA2GRAY),cv.Canny(r,r,60,255);for(let e=1;e<=2;e+=.1){const o=new cv.Mat,c=Math.round(t.cols/e),d=Math.round(t.rows/e);cv.resize(t,o,new cv.Size(c,d));let l=o.cols<r.cols||o.rows<r.rows?new cv.Mat:r;if(o.cols<r.cols||o.rows<r.rows){let t=Math.min(o.cols/r.cols,o.rows/r.rows);cv.resize(r,l,new cv.Size(Math.round(r.cols*t),Math.round(r.rows*t)))}const h=new cv.Mat;cv.cvtColor(o,h,cv.COLOR_RGBA2GRAY),cv.Canny(h,h,60,255);try{cv.matchTemplate(h,l,a,cv.TM_CCOEFF_NORMED)}catch(t){console.error("Error in matchTemplate at scale",e,t)}const m=cv.minMaxLoc(a);m.maxVal>s&&(s=m.maxVal,i=m,n=e),h.delete(),(o.cols<r.cols||o.rows<r.rows)&&l.delete(),o.delete()}return o.delete(),r.delete(),a.delete(),{bestMatch:i,bestScale:n,maxVal:s}}async processCapturedFrame(canvas,t,e,i,n,s){this.showLoadingAnimation(),this.instructionText.textContent="Processing...";try{const t=await new Promise((t=>canvas.toBlob(t,"image/jpeg",.9))),e={"0th":{[piexif.ImageIFD.Make]:"AutoID",[piexif.ImageIFD.Model]:"IDDetectionCamera"}},i=piexif.dump(e),n=piexif.insert(i,canvas.toDataURL("image/jpeg",.92));await new Promise((e=>{const i=new FileReader;i.onload=()=>e(i.result),i.readAsDataURL(t)}));"front"===s?this.result.front=n:"back"===s&&(this.result.back=n),!this.selectedCard.requiresBack||this.result.back?(this.callback(this.result),this.hideLoadingAnimation(),setTimeout((()=>{this.stopAllStreams(),this.cameraContainer.remove()}),1e3)):this.hideLoadingAnimation()}catch(t){console.error("Error processing captured frame:",t),this.hideLoadingAnimation(),this.instructionText.textContent="Error processing image. Please try again."}}showLoadingAnimation(){const t=document.createElement("div");t.className="loading-spinner",t.innerHTML='<i class="fas fa-spinner"></i>',t.style.position="absolute",t.style.top="50%",t.style.left="50%",t.style.transform="translate(-50%, -50%)",t.style.zIndex="3500";const e=t.querySelector("i");e.style.fontSize="48px",e.style.animation="spin 1s linear infinite",e.style.color="#e53935",this.cameraContainer.appendChild(t),this.loadingSpinner=t}hideLoadingAnimation(){this.loadingSpinner&&this.loadingSpinner.parentNode===this.cameraContainer&&this.cameraContainer.removeChild(this.loadingSpinner)}stopAllStreams(){this.frontStream&&(this.frontStream.getTracks().forEach((t=>t.stop())),this.frontStream=null),this.backStream&&(this.backStream.getTracks().forEach((t=>t.stop())),this.backStream=null)}}const style=document.createElement("style");style.textContent="\n@keyframes spin { \n from { transform: rotate(0deg); } \n to { transform: rotate(360deg); } \n}\n@keyframes flipAnimation { \n from { transform: translate(-50%, -50%) rotateY(0deg); } \n to { transform: translate(-50%, -50%) rotateY(360deg); } \n}\n",document.head.appendChild(style);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "accuraidscanplugin",
3
- "version": "1.0.25",
3
+ "version": "1.0.26",
4
4
  "description": "",
5
5
  "main": "./src/accuraautoocruganda.js",
6
6
  "scripts": {
@@ -9,8 +9,9 @@
9
9
  "files": [
10
10
  "build/accuramain.js",
11
11
  "./accuraface1.js",
12
- "./src/js.json",
13
- "./public"
12
+ "./accuraface2.js",
13
+ "./public",
14
+ "./accura.xml"
14
15
  ],
15
16
  "keywords": [],
16
17
  "author": "",
@@ -28,4 +29,4 @@
28
29
  "dependencies": {
29
30
 
30
31
  }
31
- }
32
+ }