@codeuctivity/qr-scanner 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +277 -0
- package/package.json +67 -0
- package/qr-scanner-worker.min.js +98 -0
- package/qr-scanner-worker.min.js.map +1 -0
- package/qr-scanner.legacy.min.js +57 -0
- package/qr-scanner.legacy.min.js.map +1 -0
- package/qr-scanner.min.js +32 -0
- package/qr-scanner.min.js.map +1 -0
- package/qr-scanner.umd.min.js +32 -0
- package/qr-scanner.umd.min.js.map +1 -0
- package/types/qr-scanner.d.ts +140 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
'use strict';var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.SIMPLE_FROUND_POLYFILL=!1;$jscomp.ISOLATE_POLYFILLS=!1;$jscomp.FORCE_POLYFILL_PROMISE=!1;$jscomp.FORCE_POLYFILL_PROMISE_WHEN_NO_UNHANDLED_REJECTION=!1;$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(c,e,a){if(c==Array.prototype||c==Object.prototype)return c;c[e]=a.value;return c};
|
|
2
|
+
$jscomp.getGlobal=function(c){c=["object"==typeof globalThis&&globalThis,c,"object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global];for(var e=0;e<c.length;++e){var a=c[e];if(a&&a.Math==Math)return a}throw Error("Cannot find global object");};$jscomp.global=$jscomp.getGlobal(this);$jscomp.IS_SYMBOL_NATIVE="function"===typeof Symbol&&"symbol"===typeof Symbol("x");$jscomp.TRUST_ES6_POLYFILLS=!$jscomp.ISOLATE_POLYFILLS||$jscomp.IS_SYMBOL_NATIVE;$jscomp.polyfills={};
|
|
3
|
+
$jscomp.propertyToPolyfillSymbol={};$jscomp.POLYFILL_PREFIX="$jscp$";var $jscomp$lookupPolyfilledValue=function(c,e){var a=$jscomp.propertyToPolyfillSymbol[e];if(null==a)return c[e];a=c[a];return void 0!==a?a:c[e]};$jscomp.polyfill=function(c,e,a,b){e&&($jscomp.ISOLATE_POLYFILLS?$jscomp.polyfillIsolated(c,e,a,b):$jscomp.polyfillUnisolated(c,e,a,b))};
|
|
4
|
+
$jscomp.polyfillUnisolated=function(c,e,a,b){a=$jscomp.global;c=c.split(".");for(b=0;b<c.length-1;b++){var d=c[b];if(!(d in a))return;a=a[d]}c=c[c.length-1];b=a[c];e=e(b);e!=b&&null!=e&&$jscomp.defineProperty(a,c,{configurable:!0,writable:!0,value:e})};
|
|
5
|
+
$jscomp.polyfillIsolated=function(c,e,a,b){var d=c.split(".");c=1===d.length;b=d[0];b=!c&&b in $jscomp.polyfills?$jscomp.polyfills:$jscomp.global;for(var f=0;f<d.length-1;f++){var g=d[f];if(!(g in b))return;b=b[g]}d=d[d.length-1];a=$jscomp.IS_SYMBOL_NATIVE&&"es6"===a?b[d]:null;e=e(a);null!=e&&(c?$jscomp.defineProperty($jscomp.polyfills,d,{configurable:!0,writable:!0,value:e}):e!==a&&(void 0===$jscomp.propertyToPolyfillSymbol[d]&&(a=1E9*Math.random()>>>0,$jscomp.propertyToPolyfillSymbol[d]=$jscomp.IS_SYMBOL_NATIVE?
|
|
6
|
+
$jscomp.global.Symbol(d):$jscomp.POLYFILL_PREFIX+a+"$"+d),$jscomp.defineProperty(b,$jscomp.propertyToPolyfillSymbol[d],{configurable:!0,writable:!0,value:e})))};$jscomp.underscoreProtoCanBeSet=function(){var c={a:!0},e={};try{return e.__proto__=c,e.a}catch(a){}return!1};
|
|
7
|
+
$jscomp.setPrototypeOf=$jscomp.TRUST_ES6_POLYFILLS&&"function"==typeof Object.setPrototypeOf?Object.setPrototypeOf:$jscomp.underscoreProtoCanBeSet()?function(c,e){c.__proto__=e;if(c.__proto__!==e)throw new TypeError(c+" is not extensible");return c}:null;$jscomp.arrayIteratorImpl=function(c){var e=0;return function(){return e<c.length?{done:!1,value:c[e++]}:{done:!0}}};$jscomp.arrayIterator=function(c){return{next:$jscomp.arrayIteratorImpl(c)}};
|
|
8
|
+
$jscomp.makeIterator=function(c){var e="undefined"!=typeof Symbol&&Symbol.iterator&&c[Symbol.iterator];return e?e.call(c):$jscomp.arrayIterator(c)};$jscomp.generator={};$jscomp.generator.ensureIteratorResultIsObject_=function(c){if(!(c instanceof Object))throw new TypeError("Iterator result "+c+" is not an object");};
|
|
9
|
+
$jscomp.generator.Context=function(){this.isRunning_=!1;this.yieldAllIterator_=null;this.yieldResult=void 0;this.nextAddress=1;this.finallyAddress_=this.catchAddress_=0;this.finallyContexts_=this.abruptCompletion_=null};$jscomp.generator.Context.prototype.start_=function(){if(this.isRunning_)throw new TypeError("Generator is already running");this.isRunning_=!0};$jscomp.generator.Context.prototype.stop_=function(){this.isRunning_=!1};
|
|
10
|
+
$jscomp.generator.Context.prototype.jumpToErrorHandler_=function(){this.nextAddress=this.catchAddress_||this.finallyAddress_};$jscomp.generator.Context.prototype.next_=function(c){this.yieldResult=c};$jscomp.generator.Context.prototype.throw_=function(c){this.abruptCompletion_={exception:c,isException:!0};this.jumpToErrorHandler_()};$jscomp.generator.Context.prototype.return=function(c){this.abruptCompletion_={return:c};this.nextAddress=this.finallyAddress_};
|
|
11
|
+
$jscomp.generator.Context.prototype.jumpThroughFinallyBlocks=function(c){this.abruptCompletion_={jumpTo:c};this.nextAddress=this.finallyAddress_};$jscomp.generator.Context.prototype.yield=function(c,e){this.nextAddress=e;return{value:c}};$jscomp.generator.Context.prototype.yieldAll=function(c,e){c=$jscomp.makeIterator(c);var a=c.next();$jscomp.generator.ensureIteratorResultIsObject_(a);if(a.done)this.yieldResult=a.value,this.nextAddress=e;else return this.yieldAllIterator_=c,this.yield(a.value,e)};
|
|
12
|
+
$jscomp.generator.Context.prototype.jumpTo=function(c){this.nextAddress=c};$jscomp.generator.Context.prototype.jumpToEnd=function(){this.nextAddress=0};$jscomp.generator.Context.prototype.setCatchFinallyBlocks=function(c,e){this.catchAddress_=c;void 0!=e&&(this.finallyAddress_=e)};$jscomp.generator.Context.prototype.setFinallyBlock=function(c){this.catchAddress_=0;this.finallyAddress_=c||0};$jscomp.generator.Context.prototype.leaveTryBlock=function(c,e){this.nextAddress=c;this.catchAddress_=e||0};
|
|
13
|
+
$jscomp.generator.Context.prototype.enterCatchBlock=function(c){this.catchAddress_=c||0;c=this.abruptCompletion_.exception;this.abruptCompletion_=null;return c};$jscomp.generator.Context.prototype.enterFinallyBlock=function(c,e,a){a?this.finallyContexts_[a]=this.abruptCompletion_:this.finallyContexts_=[this.abruptCompletion_];this.catchAddress_=c||0;this.finallyAddress_=e||0};
|
|
14
|
+
$jscomp.generator.Context.prototype.leaveFinallyBlock=function(c,e){e=this.finallyContexts_.splice(e||0)[0];if(e=this.abruptCompletion_=this.abruptCompletion_||e){if(e.isException)return this.jumpToErrorHandler_();void 0!=e.jumpTo&&this.finallyAddress_<e.jumpTo?(this.nextAddress=e.jumpTo,this.abruptCompletion_=null):this.nextAddress=this.finallyAddress_}else this.nextAddress=c};$jscomp.generator.Context.prototype.forIn=function(c){return new $jscomp.generator.Context.PropertyIterator(c)};
|
|
15
|
+
$jscomp.generator.Context.PropertyIterator=function(c){this.object_=c;this.properties_=[];for(var e in c)this.properties_.push(e);this.properties_.reverse()};$jscomp.generator.Context.PropertyIterator.prototype.getNext=function(){for(;0<this.properties_.length;){var c=this.properties_.pop();if(c in this.object_)return c}return null};$jscomp.generator.Engine_=function(c){this.context_=new $jscomp.generator.Context;this.program_=c};
|
|
16
|
+
$jscomp.generator.Engine_.prototype.next_=function(c){this.context_.start_();if(this.context_.yieldAllIterator_)return this.yieldAllStep_(this.context_.yieldAllIterator_.next,c,this.context_.next_);this.context_.next_(c);return this.nextStep_()};
|
|
17
|
+
$jscomp.generator.Engine_.prototype.return_=function(c){this.context_.start_();var e=this.context_.yieldAllIterator_;if(e)return this.yieldAllStep_("return"in e?e["return"]:function(a){return{value:a,done:!0}},c,this.context_.return);this.context_.return(c);return this.nextStep_()};
|
|
18
|
+
$jscomp.generator.Engine_.prototype.throw_=function(c){this.context_.start_();if(this.context_.yieldAllIterator_)return this.yieldAllStep_(this.context_.yieldAllIterator_["throw"],c,this.context_.next_);this.context_.throw_(c);return this.nextStep_()};
|
|
19
|
+
$jscomp.generator.Engine_.prototype.yieldAllStep_=function(c,e,a){try{var b=c.call(this.context_.yieldAllIterator_,e);$jscomp.generator.ensureIteratorResultIsObject_(b);if(!b.done)return this.context_.stop_(),b;var d=b.value}catch(f){return this.context_.yieldAllIterator_=null,this.context_.throw_(f),this.nextStep_()}this.context_.yieldAllIterator_=null;a.call(this.context_,d);return this.nextStep_()};
|
|
20
|
+
$jscomp.generator.Engine_.prototype.nextStep_=function(){for(;this.context_.nextAddress;)try{var c=this.program_(this.context_);if(c)return this.context_.stop_(),{value:c.value,done:!1}}catch(e){this.context_.yieldResult=void 0,this.context_.throw_(e)}this.context_.stop_();if(this.context_.abruptCompletion_){c=this.context_.abruptCompletion_;this.context_.abruptCompletion_=null;if(c.isException)throw c.exception;return{value:c.return,done:!0}}return{value:void 0,done:!0}};
|
|
21
|
+
$jscomp.generator.Generator_=function(c){this.next=function(e){return c.next_(e)};this.throw=function(e){return c.throw_(e)};this.return=function(e){return c.return_(e)};this[Symbol.iterator]=function(){return this}};$jscomp.generator.createGenerator=function(c,e){e=new $jscomp.generator.Generator_(new $jscomp.generator.Engine_(e));$jscomp.setPrototypeOf&&c.prototype&&$jscomp.setPrototypeOf(e,c.prototype);return e};
|
|
22
|
+
$jscomp.asyncExecutePromiseGenerator=function(c){function e(b){return c.next(b)}function a(b){return c.throw(b)}return new Promise(function(b,d){function f(g){g.done?b(g.value):Promise.resolve(g.value).then(e,a).then(f,d)}f(c.next())})};$jscomp.asyncExecutePromiseGeneratorFunction=function(c){return $jscomp.asyncExecutePromiseGenerator(c())};$jscomp.asyncExecutePromiseGeneratorProgram=function(c){return $jscomp.asyncExecutePromiseGenerator(new $jscomp.generator.Generator_(new $jscomp.generator.Engine_(c)))};
|
|
23
|
+
(function(c,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"===typeof define&&define.amd?define(e):(c="undefined"!==typeof globalThis?globalThis:c||self,c.QrScanner=e())})(this,function(){class c{static set WORKER_PATH(a){console.warn("Setting QrScanner.WORKER_PATH is not required and not supported anymore. Have a look at the README for new setup instructions.")}static hasCamera(){return $jscomp.asyncExecutePromiseGeneratorFunction(function*(){try{return!!(yield c.listCameras(!1)).length}catch(a){return!1}})}static listCameras(a=
|
|
24
|
+
!1){return $jscomp.asyncExecutePromiseGeneratorFunction(function*(){if(!navigator.mediaDevices)return[];let b=()=>$jscomp.asyncExecutePromiseGeneratorFunction(function*(){return(yield navigator.mediaDevices.enumerateDevices()).filter(f=>"videoinput"===f.kind)}),d;try{a&&(yield b()).every(f=>!f.label)&&(d=yield navigator.mediaDevices.getUserMedia({audio:!1,video:!0}))}catch(f){}try{return(yield b()).map((f,g)=>({id:f.deviceId,label:f.label||(0===g?"Default Camera":`Camera ${g+1}`)}))}finally{d&&(console.warn("Call listCameras after successfully starting a QR scanner to avoid creating a temporary video stream"),
|
|
25
|
+
c._stopVideoStream(d))}})}constructor(a,b,d,f,g){this._legacyCanvasSize=c.DEFAULT_CANVAS_SIZE;this._preferredCamera="environment";this._maxScansPerSecond=25;this._lastScanTimestamp=-1;this._destroyed=this._flashOn=this._paused=this._active=!1;this.$video=a;this.$canvas=document.createElement("canvas");d&&"object"===typeof d?this._onDecode=b:(d||f||g?console.warn("You're using a deprecated version of the QrScanner constructor which will be removed in the future"):console.warn("Note that the type of the scan result passed to onDecode will change in the future. To already switch to the new api today, you can pass returnDetailedScanResult: true."),
|
|
26
|
+
this._legacyOnDecode=b);b="object"===typeof d?d:{};this._onDecodeError=b.onDecodeError||("function"===typeof d?d:this._onDecodeError);this._calculateScanRegion=b.calculateScanRegion||("function"===typeof f?f:this._calculateScanRegion);this._preferredCamera=b.preferredCamera||g||this._preferredCamera;this._legacyCanvasSize="number"===typeof d?d:"number"===typeof f?f:this._legacyCanvasSize;this._maxScansPerSecond=b.maxScansPerSecond||this._maxScansPerSecond;this._onPlay=this._onPlay.bind(this);this._onLoadedMetaData=
|
|
27
|
+
this._onLoadedMetaData.bind(this);this._onVisibilityChange=this._onVisibilityChange.bind(this);this._updateOverlay=this._updateOverlay.bind(this);a.disablePictureInPicture=!0;a.playsInline=!0;a.muted=!0;let k=!1;a.hidden&&(a.hidden=!1,k=!0);document.body.contains(a)||(document.body.appendChild(a),k=!0);d=a.parentElement;if(b.highlightScanRegion||b.highlightCodeOutline){f=!!b.overlay;this.$overlay=b.overlay||document.createElement("div");g=this.$overlay.style;g.position="absolute";g.display="none";
|
|
28
|
+
g.pointerEvents="none";this.$overlay.classList.add("scan-region-highlight");if(!f&&b.highlightScanRegion){this.$overlay.innerHTML='<svg class="scan-region-highlight-svg" viewBox="0 0 238 238" preserveAspectRatio="none" style="position:absolute;width:100%;height:100%;left:0;top:0;fill:none;stroke:#e9b213;stroke-width:4;stroke-linecap:round;stroke-linejoin:round"><path d="M31 2H10a8 8 0 0 0-8 8v21M207 2h21a8 8 0 0 1 8 8v21m0 176v21a8 8 0 0 1-8 8h-21m-176 0H10a8 8 0 0 1-8-8v-21"/></svg>';try{this.$overlay.firstElementChild.animate({transform:["scale(.98)",
|
|
29
|
+
"scale(1.01)"]},{duration:400,iterations:Infinity,direction:"alternate",easing:"ease-in-out"})}catch(l){}d.insertBefore(this.$overlay,this.$video.nextSibling)}b.highlightCodeOutline&&(this.$overlay.insertAdjacentHTML("beforeend",'<svg class="code-outline-highlight" preserveAspectRatio="none" style="display:none;width:100%;height:100%;fill:none;stroke:#e9b213;stroke-width:5;stroke-dasharray:25;stroke-linecap:round;stroke-linejoin:round"><polygon/></svg>'),this.$codeOutlineHighlight=this.$overlay.lastElementChild)}this._scanRegion=
|
|
30
|
+
this._calculateScanRegion(a);requestAnimationFrame(()=>{let l=window.getComputedStyle(a);"none"===l.display&&(a.style.setProperty("display","block","important"),k=!0);"visible"!==l.visibility&&(a.style.setProperty("visibility","visible","important"),k=!0);k&&(console.warn("QrScanner has overwritten the video hiding style to avoid Safari stopping the playback."),a.style.opacity="0",a.style.width="0",a.style.height="0",this.$overlay&&this.$overlay.parentElement&&this.$overlay.parentElement.removeChild(this.$overlay),
|
|
31
|
+
delete this.$overlay,delete this.$codeOutlineHighlight);this.$overlay&&this._updateOverlay()});a.addEventListener("play",this._onPlay);a.addEventListener("loadedmetadata",this._onLoadedMetaData);document.addEventListener("visibilitychange",this._onVisibilityChange);window.addEventListener("resize",this._updateOverlay);this._qrEnginePromise=c.createQrEngine()}hasFlash(){const a=this;return $jscomp.asyncExecutePromiseGeneratorFunction(function*(){let b;try{if(a.$video.srcObject){if(!(a.$video.srcObject instanceof
|
|
32
|
+
MediaStream))return!1;b=a.$video.srcObject}else b=(yield a._getCameraStream()).stream;return"torch"in b.getVideoTracks()[0].getSettings()}catch(d){return!1}finally{b&&b!==a.$video.srcObject&&(console.warn("Call hasFlash after successfully starting the scanner to avoid creating a temporary video stream"),c._stopVideoStream(b))}})}isFlashOn(){return this._flashOn}toggleFlash(){const a=this;return $jscomp.asyncExecutePromiseGeneratorFunction(function*(){a._flashOn?yield a.turnFlashOff():yield a.turnFlashOn()})}turnFlashOn(){const a=
|
|
33
|
+
this;return $jscomp.asyncExecutePromiseGeneratorFunction(function*(){if(!a._flashOn&&!a._destroyed&&(a._flashOn=!0,a._active&&!a._paused))try{if(!(yield a.hasFlash()))throw"No flash available";yield a.$video.srcObject.getVideoTracks()[0].applyConstraints({advanced:[{torch:!0}]})}catch(b){throw a._flashOn=!1,b;}})}turnFlashOff(){const a=this;return $jscomp.asyncExecutePromiseGeneratorFunction(function*(){a._flashOn&&(a._flashOn=!1,yield a._restartVideoStream())})}destroy(){this.$video.removeEventListener("loadedmetadata",
|
|
34
|
+
this._onLoadedMetaData);this.$video.removeEventListener("play",this._onPlay);document.removeEventListener("visibilitychange",this._onVisibilityChange);window.removeEventListener("resize",this._updateOverlay);this._destroyed=!0;this._flashOn=!1;this.stop();c._postWorkerMessage(this._qrEnginePromise,"close")}start(){const a=this;return $jscomp.asyncExecutePromiseGeneratorFunction(function*(){if(a._destroyed)throw Error("The QR scanner can not be started as it had been destroyed.");if(!a._active||a._paused)if("https:"!==
|
|
35
|
+
window.location.protocol&&console.warn("The camera stream is only accessible if the page is transferred via https."),a._active=!0,!document.hidden)if(a._paused=!1,a.$video.srcObject)yield a.$video.play();else try{let {stream:b,facingMode:d}=yield a._getCameraStream();!a._active||a._paused?c._stopVideoStream(b):(a._setVideoMirror(d),a.$video.srcObject=b,yield a.$video.play(),a._flashOn&&(a._flashOn=!1,a.turnFlashOn().catch(()=>{})))}catch(b){if(!a._paused)throw a._active=!1,b;}})}stop(){this.pause();
|
|
36
|
+
this._active=!1}pause(a=!1){const b=this;return $jscomp.asyncExecutePromiseGeneratorFunction(function*(){b._paused=!0;if(!b._active)return!0;b.$video.pause();b.$overlay&&(b.$overlay.style.display="none");let d=()=>{b.$video.srcObject instanceof MediaStream&&(c._stopVideoStream(b.$video.srcObject),b.$video.srcObject=null)};if(a)return d(),!0;yield new Promise(f=>setTimeout(f,300));if(!b._paused)return!1;d();return!0})}setCamera(a){const b=this;return $jscomp.asyncExecutePromiseGeneratorFunction(function*(){a!==
|
|
37
|
+
b._preferredCamera&&(b._preferredCamera=a,yield b._restartVideoStream())})}static scanImage(a,b,d,f,g=!1,k=!1){return $jscomp.asyncExecutePromiseGeneratorFunction(function*(){let l,p=!1;b&&("scanRegion"in b||"qrEngine"in b||"canvas"in b||"disallowCanvasResizing"in b||"alsoTryWithoutScanRegion"in b||"returnDetailedScanResult"in b)?(l=b.scanRegion,d=b.qrEngine,f=b.canvas,g=b.disallowCanvasResizing||!1,k=b.alsoTryWithoutScanRegion||!1,p=!0):b||d||f||g||k?console.warn("You're using a deprecated api for scanImage which will be removed in the future."):
|
|
38
|
+
console.warn("Note that the return type of scanImage will change in the future. To already switch to the new api today, you can pass returnDetailedScanResult: true.");let t=!!d;try{let m,r;[d,m]=yield Promise.all([d||c.createQrEngine(),c._loadImage(a)]);[f,r]=c._drawToCanvas(m,l,f,g);let n;if(d instanceof Worker){let h=d;t||c._postWorkerMessageSync(h,"inversionMode","both");n=yield new Promise((q,z)=>{let x,v,w,y=-1;v=u=>{u.data.id===y&&(h.removeEventListener("message",v),h.removeEventListener("error",
|
|
39
|
+
w),clearTimeout(x),null!==u.data.data?q({data:u.data.data,cornerPoints:c._convertPoints(u.data.cornerPoints,l),bytes:u.data.bytes}):z(c.NO_QR_CODE_FOUND))};w=u=>{h.removeEventListener("message",v);h.removeEventListener("error",w);clearTimeout(x);z("Scanner error: "+(u?u.message||u:"Unknown Error"))};h.addEventListener("message",v);h.addEventListener("error",w);x=setTimeout(()=>w("timeout"),1E4);let A=r.getImageData(0,0,f.width,f.height);y=c._postWorkerMessageSync(h,"decode",A,[A.data.buffer])})}else n=
|
|
40
|
+
yield Promise.race([new Promise((h,q)=>window.setTimeout(()=>q("Scanner error: timeout"),1E4)),(()=>$jscomp.asyncExecutePromiseGeneratorFunction(function*(){try{var [h]=yield d.detect(f);if(!h)throw c.NO_QR_CODE_FOUND;return{data:h.rawValue,cornerPoints:c._convertPoints(h.cornerPoints,l),bytes:h.rawValue.split("").map(q=>q.charCodeAt(0))}}catch(q){h=q.message||q;if(/not implemented|service unavailable/.test(h))return c._disableBarcodeDetector=!0,c.scanImage(a,{scanRegion:l,canvas:f,disallowCanvasResizing:g,
|
|
41
|
+
alsoTryWithoutScanRegion:k});throw`Scanner error: ${h}`;}}))()]);return p?n:n.data}catch(m){if(!l||!k)throw m;let r=yield c.scanImage(a,{qrEngine:d,canvas:f,disallowCanvasResizing:g});return p?r:r.data}finally{t||c._postWorkerMessage(d,"close")}})}setGrayscaleWeights(a,b,d,f=!0){c._postWorkerMessage(this._qrEnginePromise,"grayscaleWeights",{red:a,green:b,blue:d,useIntegerApproximation:f})}setInversionMode(a){c._postWorkerMessage(this._qrEnginePromise,"inversionMode",a)}static createQrEngine(a){return $jscomp.asyncExecutePromiseGeneratorFunction(function*(){a&&
|
|
42
|
+
console.warn("Specifying a worker path is not required and not supported anymore.");let b=()=>Promise.resolve().then(function(){return e}).then(f=>f.createWorker());if(!(!c._disableBarcodeDetector&&"BarcodeDetector"in window&&BarcodeDetector.getSupportedFormats&&(yield BarcodeDetector.getSupportedFormats()).includes("qr_code")))return b();let d=navigator.userAgentData;return d&&d.brands.some(({brand:f})=>/Chromium/i.test(f))&&/mac ?OS/i.test(d.platform)&&(yield d.getHighEntropyValues(["architecture",
|
|
43
|
+
"platformVersion"]).then(({architecture:f,platformVersion:g})=>/arm/i.test(f||"arm")&&13<=parseInt(g||"13")).catch(()=>!0))?b():new BarcodeDetector({formats:["qr_code"]})})}_onPlay(){this._scanRegion=this._calculateScanRegion(this.$video);this._updateOverlay();this.$overlay&&(this.$overlay.style.display="");this._scanFrame()}_onLoadedMetaData(){this._scanRegion=this._calculateScanRegion(this.$video);this._updateOverlay()}_onVisibilityChange(){document.hidden?this.pause():this._active&&this.start()}_calculateScanRegion(a){let b=
|
|
44
|
+
Math.round(2/3*Math.min(a.videoWidth,a.videoHeight));return{x:Math.round((a.videoWidth-b)/2),y:Math.round((a.videoHeight-b)/2),width:b,height:b,downScaledWidth:this._legacyCanvasSize,downScaledHeight:this._legacyCanvasSize}}_updateOverlay(){requestAnimationFrame(()=>{if(this.$overlay){var a=this.$video,b=a.videoWidth,d=a.videoHeight,f=a.offsetWidth,g=a.offsetHeight,k=a.offsetLeft,l=a.offsetTop,p=window.getComputedStyle(a),t=p.objectFit,m=b/d,r=f/g;switch(t){case "none":var n=b;var h=d;break;case "fill":n=
|
|
45
|
+
f;h=g;break;default:("cover"===t?m>r:m<r)?(h=g,n=h*m):(n=f,h=n/m),"scale-down"===t&&(n=Math.min(n,b),h=Math.min(h,d))}var [q,z]=p.objectPosition.split(" ").map((v,w)=>{const y=parseFloat(v);return v.endsWith("%")?(w?g-h:f-n)*y/100:y});p=this._scanRegion.width||b;r=this._scanRegion.height||d;t=this._scanRegion.x||0;var x=this._scanRegion.y||0;m=this.$overlay.style;m.width=`${p/b*n}px`;m.height=`${r/d*h}px`;m.top=`${l+z+x/d*h}px`;d=/scaleX\(-1\)/.test(a.style.transform);m.left=`${k+(d?f-q-n:q)+(d?b-
|
|
46
|
+
t-p:t)/b*n}px`;m.transform=a.style.transform}})}static _convertPoints(a,b){if(!b)return a;let d=b.x||0,f=b.y||0,g=b.width&&b.downScaledWidth?b.width/b.downScaledWidth:1;b=b.height&&b.downScaledHeight?b.height/b.downScaledHeight:1;for(let k of a)k.x=k.x*g+d,k.y=k.y*b+f;return a}_scanFrame(){!this._active||this.$video.paused||this.$video.ended||("requestVideoFrameCallback"in this.$video?this.$video.requestVideoFrameCallback.bind(this.$video):requestAnimationFrame)(()=>{const a=this;return $jscomp.asyncExecutePromiseGeneratorFunction(function*(){if(!(1>=
|
|
47
|
+
a.$video.readyState)){var b=Date.now()-a._lastScanTimestamp,d=1E3/a._maxScansPerSecond;b<d&&(yield new Promise(g=>setTimeout(g,d-b)));a._lastScanTimestamp=Date.now();try{var f=yield c.scanImage(a.$video,{scanRegion:a._scanRegion,qrEngine:a._qrEnginePromise,canvas:a.$canvas})}catch(g){if(!a._active)return;a._onDecodeError(g)}!c._disableBarcodeDetector||(yield a._qrEnginePromise)instanceof Worker||(a._qrEnginePromise=c.createQrEngine());f?(a._onDecode?a._onDecode(f):a._legacyOnDecode&&a._legacyOnDecode(f.data),
|
|
48
|
+
a.$codeOutlineHighlight&&(clearTimeout(a._codeOutlineHighlightRemovalTimeout),a._codeOutlineHighlightRemovalTimeout=void 0,a.$codeOutlineHighlight.setAttribute("viewBox",`${a._scanRegion.x||0} `+`${a._scanRegion.y||0} `+`${a._scanRegion.width||a.$video.videoWidth} `+`${a._scanRegion.height||a.$video.videoHeight}`),a.$codeOutlineHighlight.firstElementChild.setAttribute("points",f.cornerPoints.map(({x:g,y:k})=>`${g},${k}`).join(" ")),a.$codeOutlineHighlight.style.display="")):a.$codeOutlineHighlight&&
|
|
49
|
+
!a._codeOutlineHighlightRemovalTimeout&&(a._codeOutlineHighlightRemovalTimeout=setTimeout(()=>a.$codeOutlineHighlight.style.display="none",100))}a._scanFrame()})})}_onDecodeError(a){a!==c.NO_QR_CODE_FOUND&&console.log(a)}_getCameraStream(){const a=this;return $jscomp.asyncExecutePromiseGeneratorFunction(function*(){if(!navigator.mediaDevices)throw"Camera not found.";let b=/^(environment|user)$/.test(a._preferredCamera)?"facingMode":"deviceId",d=[{width:{min:1024}},{width:{min:768}},{}],f=d.map(g=>
|
|
50
|
+
Object.assign({},g,{[b]:{exact:a._preferredCamera}}));for(let g of[...f,...d])try{let k=yield navigator.mediaDevices.getUserMedia({video:g,audio:!1}),l=a._getFacingMode(k)||(g.facingMode?a._preferredCamera:"environment"===a._preferredCamera?"user":"environment");return{stream:k,facingMode:l}}catch(k){}throw"Camera not found.";})}_restartVideoStream(){const a=this;return $jscomp.asyncExecutePromiseGeneratorFunction(function*(){let b=a._paused;(yield a.pause(!0))&&!b&&a._active&&(yield a.start())})}static _stopVideoStream(a){for(let b of a.getTracks())b.stop(),
|
|
51
|
+
a.removeTrack(b)}_setVideoMirror(a){this.$video.style.transform="scaleX("+("user"===a?-1:1)+")"}_getFacingMode(a){return(a=a.getVideoTracks()[0])?/rear|back|environment/i.test(a.label)?"environment":/front|user|face/i.test(a.label)?"user":null:null}static _drawToCanvas(a,b,d,f=!1){d=d||document.createElement("canvas");let g=b&&b.x?b.x:0,k=b&&b.y?b.y:0,l=b&&b.width?b.width:a.videoWidth||a.width,p=b&&b.height?b.height:a.videoHeight||a.height;f||(f=b&&b.downScaledWidth?b.downScaledWidth:l,b=b&&b.downScaledHeight?
|
|
52
|
+
b.downScaledHeight:p,d.width!==f&&(d.width=f),d.height!==b&&(d.height=b));b=d.getContext("2d",{alpha:!1});b.imageSmoothingEnabled=!1;b.drawImage(a,g,k,l,p,0,0,d.width,d.height);return[d,b]}static _loadImage(a){return $jscomp.asyncExecutePromiseGeneratorFunction(function*(){if(a instanceof Image)return yield c._awaitImageLoad(a),a;if(a instanceof HTMLVideoElement||a instanceof HTMLCanvasElement||a instanceof SVGImageElement||"OffscreenCanvas"in window&&a instanceof OffscreenCanvas||"ImageBitmap"in
|
|
53
|
+
window&&a instanceof ImageBitmap)return a;if(a instanceof File||a instanceof Blob||a instanceof URL||"string"===typeof a){let b=new Image;b.src=a instanceof File||a instanceof Blob?URL.createObjectURL(a):a.toString();try{return yield c._awaitImageLoad(b),b}finally{(a instanceof File||a instanceof Blob)&&URL.revokeObjectURL(b.src)}}else throw"Unsupported image type.";})}static _awaitImageLoad(a){return $jscomp.asyncExecutePromiseGeneratorFunction(function*(){a.complete&&0!==a.naturalWidth||(yield new Promise((b,
|
|
54
|
+
d)=>{let f=g=>{a.removeEventListener("load",f);a.removeEventListener("error",f);g instanceof ErrorEvent?d("Image load error"):b()};a.addEventListener("load",f);a.addEventListener("error",f)}))})}static _postWorkerMessage(a,b,d,f){return $jscomp.asyncExecutePromiseGeneratorFunction(function*(){return c._postWorkerMessageSync(yield a,b,d,f)})}static _postWorkerMessageSync(a,b,d,f){if(!(a instanceof Worker))return-1;let g=c._workerMessageId++;a.postMessage({id:g,type:b,data:d},f);return g}}c.DEFAULT_CANVAS_SIZE=
|
|
55
|
+
400;c.NO_QR_CODE_FOUND="No QR code found";c._disableBarcodeDetector=!1;c._workerMessageId=0;var e=Object.freeze({__proto__:null,createWorker:()=>new Worker(URL.createObjectURL(new Blob(['class x{constructor(a,b){this.width=b;this.height=a.length/b;this.data=a}static createEmpty(a,b){return new x(new Uint8ClampedArray(a*b),a)}get(a,b){return 0>a||a>=this.width||0>b||b>=this.height?!1:!!this.data[b*this.width+a]}set(a,b,c){this.data[b*this.width+a]=c?1:0}setRegion(a,b,c,d,e){for(let f=b;f<b+d;f++)for(let g=a;g<a+c;g++)this.set(g,f,!!e)}}\nclass A{constructor(a,b,c){this.width=a;a*=b;if(c&&c.length!==a)throw Error("Wrong buffer size");this.data=c||new Uint8ClampedArray(a)}get(a,b){return this.data[b*this.width+a]}set(a,b,c){this.data[b*this.width+a]=c}}\nclass ba{constructor(a){this.bitOffset=this.byteOffset=0;this.bytes=a}readBits(a){if(1>a||32<a||a>this.available())throw Error("Cannot read "+a.toString()+" bits");var b=0;if(0<this.bitOffset){b=8-this.bitOffset;var c=a<b?a:b;b-=c;b=(this.bytes[this.byteOffset]&255>>8-c<<b)>>b;a-=c;this.bitOffset+=c;8===this.bitOffset&&(this.bitOffset=0,this.byteOffset++)}if(0<a){for(;8<=a;)b=b<<8|this.bytes[this.byteOffset]&255,this.byteOffset++,a-=8;0<a&&(c=8-a,b=b<<a|(this.bytes[this.byteOffset]&255>>c<<c)>>c,\nthis.bitOffset+=a)}return b}available(){return 8*(this.bytes.length-this.byteOffset)-this.bitOffset}}var B,C=B||(B={});C.Numeric="numeric";C.Alphanumeric="alphanumeric";C.Byte="byte";C.Kanji="kanji";C.ECI="eci";C.StructuredAppend="structuredappend";var D,E=D||(D={});E[E.Terminator=0]="Terminator";E[E.Numeric=1]="Numeric";E[E.Alphanumeric=2]="Alphanumeric";E[E.Byte=4]="Byte";E[E.Kanji=8]="Kanji";E[E.ECI=7]="ECI";E[E.StructuredAppend=3]="StructuredAppend";let F="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:".split("");\nfunction ca(a,b){let c=[],d="";b=a.readBits([8,16,16][b]);for(let e=0;e<b;e++){let f=a.readBits(8);c.push(f)}try{d+=decodeURIComponent(c.map(e=>`%${("0"+e.toString(16)).substr(-2)}`).join(""))}catch(e){}return{bytes:c,text:d}}\nfunction da(a,b){a=new ba(a);let c=9>=b?0:26>=b?1:2;for(b={text:"",bytes:[],chunks:[],version:b};4<=a.available();){var d=a.readBits(4);if(d===D.Terminator)return b;if(d===D.ECI)0===a.readBits(1)?b.chunks.push({type:B.ECI,assignmentNumber:a.readBits(7)}):0===a.readBits(1)?b.chunks.push({type:B.ECI,assignmentNumber:a.readBits(14)}):0===a.readBits(1)?b.chunks.push({type:B.ECI,assignmentNumber:a.readBits(21)}):b.chunks.push({type:B.ECI,assignmentNumber:-1});else if(d===D.Numeric){var e=a,f=[];d="";for(var g=\ne.readBits([10,12,14][c]);3<=g;){var h=e.readBits(10);if(1E3<=h)throw Error("Invalid numeric value above 999");var k=Math.floor(h/100),m=Math.floor(h/10)%10;h%=10;f.push(48+k,48+m,48+h);d+=k.toString()+m.toString()+h.toString();g-=3}if(2===g){g=e.readBits(7);if(100<=g)throw Error("Invalid numeric value above 99");e=Math.floor(g/10);g%=10;f.push(48+e,48+g);d+=e.toString()+g.toString()}else if(1===g){e=e.readBits(4);if(10<=e)throw Error("Invalid numeric value above 9");f.push(48+e);d+=e.toString()}b.text+=\nd;b.bytes.push(...f);b.chunks.push({type:B.Numeric,text:d})}else if(d===D.Alphanumeric){e=a;f=[];d="";for(g=e.readBits([9,11,13][c]);2<=g;)m=e.readBits(11),k=Math.floor(m/45),m%=45,f.push(F[k].charCodeAt(0),F[m].charCodeAt(0)),d+=F[k]+F[m],g-=2;1===g&&(e=e.readBits(6),f.push(F[e].charCodeAt(0)),d+=F[e]);b.text+=d;b.bytes.push(...f);b.chunks.push({type:B.Alphanumeric,text:d})}else if(d===D.Byte)d=ca(a,c),b.text+=d.text,b.bytes.push(...d.bytes),b.chunks.push({type:B.Byte,bytes:d.bytes,text:d.text});\nelse if(d===D.Kanji){f=a;d=[];e=f.readBits([8,10,12][c]);for(g=0;g<e;g++)k=f.readBits(13),k=Math.floor(k/192)<<8|k%192,k=7936>k?k+33088:k+49472,d.push(k>>8,k&255);f=(new TextDecoder("shift-jis")).decode(Uint8Array.from(d));b.text+=f;b.bytes.push(...d);b.chunks.push({type:B.Kanji,bytes:d,text:f})}else d===D.StructuredAppend&&b.chunks.push({type:B.StructuredAppend,currentSequence:a.readBits(4),totalSequence:a.readBits(4),parity:a.readBits(8)})}if(0===a.available()||0===a.readBits(a.available()))return b}\nclass G{constructor(a,b){if(0===b.length)throw Error("No coefficients.");this.field=a;let c=b.length;if(1<c&&0===b[0]){let d=1;for(;d<c&&0===b[d];)d++;if(d===c)this.coefficients=a.zero.coefficients;else for(this.coefficients=new Uint8ClampedArray(c-d),a=0;a<this.coefficients.length;a++)this.coefficients[a]=b[d+a]}else this.coefficients=b}degree(){return this.coefficients.length-1}isZero(){return 0===this.coefficients[0]}getCoefficient(a){return this.coefficients[this.coefficients.length-1-a]}addOrSubtract(a){if(this.isZero())return a;\nif(a.isZero())return this;let b=this.coefficients;a=a.coefficients;b.length>a.length&&([b,a]=[a,b]);let c=new Uint8ClampedArray(a.length),d=a.length-b.length;for(var e=0;e<d;e++)c[e]=a[e];for(e=d;e<a.length;e++)c[e]=b[e-d]^a[e];return new G(this.field,c)}multiply(a){if(0===a)return this.field.zero;if(1===a)return this;let b=this.coefficients.length,c=new Uint8ClampedArray(b);for(let d=0;d<b;d++)c[d]=this.field.multiply(this.coefficients[d],a);return new G(this.field,c)}multiplyPoly(a){if(this.isZero()||\na.isZero())return this.field.zero;let b=this.coefficients,c=b.length;a=a.coefficients;let d=a.length,e=new Uint8ClampedArray(c+d-1);for(let f=0;f<c;f++){let g=b[f];for(let h=0;h<d;h++)e[f+h]=H(e[f+h],this.field.multiply(g,a[h]))}return new G(this.field,e)}multiplyByMonomial(a,b){if(0>a)throw Error("Invalid degree less than 0");if(0===b)return this.field.zero;let c=this.coefficients.length;a=new Uint8ClampedArray(c+a);for(let d=0;d<c;d++)a[d]=this.field.multiply(this.coefficients[d],b);return new G(this.field,\na)}evaluateAt(a){let b=0;if(0===a)return this.getCoefficient(0);let c=this.coefficients.length;if(1===a)return this.coefficients.forEach(d=>{b^=d}),b;b=this.coefficients[0];for(let d=1;d<c;d++)b=H(this.field.multiply(a,b),this.coefficients[d]);return b}}function H(a,b){return a^b}\nclass ea{constructor(a,b,c){this.primitive=a;this.size=b;this.generatorBase=c;this.expTable=Array(this.size);this.logTable=Array(this.size);a=1;for(b=0;b<this.size;b++)this.expTable[b]=a,a*=2,a>=this.size&&(a=(a^this.primitive)&this.size-1);for(a=0;a<this.size-1;a++)this.logTable[this.expTable[a]]=a;this.zero=new G(this,Uint8ClampedArray.from([0]));this.one=new G(this,Uint8ClampedArray.from([1]))}multiply(a,b){return 0===a||0===b?0:this.expTable[(this.logTable[a]+this.logTable[b])%(this.size-1)]}inverse(a){if(0===\na)throw Error("Can\'t invert 0");return this.expTable[this.size-this.logTable[a]-1]}buildMonomial(a,b){if(0>a)throw Error("Invalid monomial degree less than 0");if(0===b)return this.zero;a=new Uint8ClampedArray(a+1);a[0]=b;return new G(this,a)}log(a){if(0===a)throw Error("Can\'t take log(0)");return this.logTable[a]}exp(a){return this.expTable[a]}}\nfunction fa(a,b,c,d){b.degree()<c.degree()&&([b,c]=[c,b]);let e=a.zero;for(var f=a.one;c.degree()>=d/2;){var g=b;let h=e;b=c;e=f;if(b.isZero())return null;c=g;f=a.zero;g=b.getCoefficient(b.degree());for(g=a.inverse(g);c.degree()>=b.degree()&&!c.isZero();){let k=c.degree()-b.degree(),m=a.multiply(c.getCoefficient(c.degree()),g);f=f.addOrSubtract(a.buildMonomial(k,m));c=c.addOrSubtract(b.multiplyByMonomial(k,m))}f=f.multiplyPoly(e).addOrSubtract(h);if(c.degree()>=b.degree())return null}d=f.getCoefficient(0);\nif(0===d)return null;a=a.inverse(d);return[f.multiply(a),c.multiply(a)]}\nfunction ha(a,b){let c=new Uint8ClampedArray(a.length);c.set(a);a=new ea(285,256,0);var d=new G(a,c),e=new Uint8ClampedArray(b),f=!1;for(var g=0;g<b;g++){var h=d.evaluateAt(a.exp(g+a.generatorBase));e[e.length-1-g]=h;0!==h&&(f=!0)}if(!f)return c;d=new G(a,e);d=fa(a,a.buildMonomial(b,1),d,b);if(null===d)return null;b=d[0];g=b.degree();if(1===g)b=[b.getCoefficient(1)];else{e=Array(g);f=0;for(h=1;h<a.size&&f<g;h++)0===b.evaluateAt(h)&&(e[f]=a.inverse(h),f++);b=f!==g?null:e}if(null==b)return null;e=d[1];\nf=b.length;d=Array(f);for(g=0;g<f;g++){h=a.inverse(b[g]);let k=1;for(let m=0;m<f;m++)g!==m&&(k=a.multiply(k,H(1,a.multiply(b[m],h))));d[g]=a.multiply(e.evaluateAt(h),a.inverse(k));0!==a.generatorBase&&(d[g]=a.multiply(d[g],h))}for(e=0;e<b.length;e++){f=c.length-1-a.log(b[e]);if(0>f)return null;c[f]^=d[e]}return c}\nlet I=[{infoBits:null,versionNumber:1,alignmentPatternCenters:[],errorCorrectionLevels:[{ecCodewordsPerBlock:7,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:19}]},{ecCodewordsPerBlock:10,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:16}]},{ecCodewordsPerBlock:13,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:13}]},{ecCodewordsPerBlock:17,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:9}]}]},{infoBits:null,versionNumber:2,alignmentPatternCenters:[6,18],errorCorrectionLevels:[{ecCodewordsPerBlock:10,ecBlocks:[{numBlocks:1,\ndataCodewordsPerBlock:34}]},{ecCodewordsPerBlock:16,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:28}]},{ecCodewordsPerBlock:22,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:22}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:16}]}]},{infoBits:null,versionNumber:3,alignmentPatternCenters:[6,22],errorCorrectionLevels:[{ecCodewordsPerBlock:15,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:55}]},{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:44}]},{ecCodewordsPerBlock:18,\necBlocks:[{numBlocks:2,dataCodewordsPerBlock:17}]},{ecCodewordsPerBlock:22,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:13}]}]},{infoBits:null,versionNumber:4,alignmentPatternCenters:[6,26],errorCorrectionLevels:[{ecCodewordsPerBlock:20,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:80}]},{ecCodewordsPerBlock:18,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:32}]},{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:24}]},{ecCodewordsPerBlock:16,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:9}]}]},\n{infoBits:null,versionNumber:5,alignmentPatternCenters:[6,30],errorCorrectionLevels:[{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:108}]},{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:43}]},{ecCodewordsPerBlock:18,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:15},{numBlocks:2,dataCodewordsPerBlock:16}]},{ecCodewordsPerBlock:22,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:11},{numBlocks:2,dataCodewordsPerBlock:12}]}]},{infoBits:null,versionNumber:6,alignmentPatternCenters:[6,\n34],errorCorrectionLevels:[{ecCodewordsPerBlock:18,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:68}]},{ecCodewordsPerBlock:16,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:27}]},{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:19}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:15}]}]},{infoBits:31892,versionNumber:7,alignmentPatternCenters:[6,22,38],errorCorrectionLevels:[{ecCodewordsPerBlock:20,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:78}]},{ecCodewordsPerBlock:18,\necBlocks:[{numBlocks:4,dataCodewordsPerBlock:31}]},{ecCodewordsPerBlock:18,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:14},{numBlocks:4,dataCodewordsPerBlock:15}]},{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:13},{numBlocks:1,dataCodewordsPerBlock:14}]}]},{infoBits:34236,versionNumber:8,alignmentPatternCenters:[6,24,42],errorCorrectionLevels:[{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:97}]},{ecCodewordsPerBlock:22,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:38},\n{numBlocks:2,dataCodewordsPerBlock:39}]},{ecCodewordsPerBlock:22,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:18},{numBlocks:2,dataCodewordsPerBlock:19}]},{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:14},{numBlocks:2,dataCodewordsPerBlock:15}]}]},{infoBits:39577,versionNumber:9,alignmentPatternCenters:[6,26,46],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:116}]},{ecCodewordsPerBlock:22,ecBlocks:[{numBlocks:3,dataCodewordsPerBlock:36},\n{numBlocks:2,dataCodewordsPerBlock:37}]},{ecCodewordsPerBlock:20,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:16},{numBlocks:4,dataCodewordsPerBlock:17}]},{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:12},{numBlocks:4,dataCodewordsPerBlock:13}]}]},{infoBits:42195,versionNumber:10,alignmentPatternCenters:[6,28,50],errorCorrectionLevels:[{ecCodewordsPerBlock:18,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:68},{numBlocks:2,dataCodewordsPerBlock:69}]},{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:4,\ndataCodewordsPerBlock:43},{numBlocks:1,dataCodewordsPerBlock:44}]},{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:6,dataCodewordsPerBlock:19},{numBlocks:2,dataCodewordsPerBlock:20}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:6,dataCodewordsPerBlock:15},{numBlocks:2,dataCodewordsPerBlock:16}]}]},{infoBits:48118,versionNumber:11,alignmentPatternCenters:[6,30,54],errorCorrectionLevels:[{ecCodewordsPerBlock:20,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:81}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:1,\ndataCodewordsPerBlock:50},{numBlocks:4,dataCodewordsPerBlock:51}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:22},{numBlocks:4,dataCodewordsPerBlock:23}]},{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:3,dataCodewordsPerBlock:12},{numBlocks:8,dataCodewordsPerBlock:13}]}]},{infoBits:51042,versionNumber:12,alignmentPatternCenters:[6,32,58],errorCorrectionLevels:[{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:92},{numBlocks:2,dataCodewordsPerBlock:93}]},\n{ecCodewordsPerBlock:22,ecBlocks:[{numBlocks:6,dataCodewordsPerBlock:36},{numBlocks:2,dataCodewordsPerBlock:37}]},{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:20},{numBlocks:6,dataCodewordsPerBlock:21}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:7,dataCodewordsPerBlock:14},{numBlocks:4,dataCodewordsPerBlock:15}]}]},{infoBits:55367,versionNumber:13,alignmentPatternCenters:[6,34,62],errorCorrectionLevels:[{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:107}]},\n{ecCodewordsPerBlock:22,ecBlocks:[{numBlocks:8,dataCodewordsPerBlock:37},{numBlocks:1,dataCodewordsPerBlock:38}]},{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:8,dataCodewordsPerBlock:20},{numBlocks:4,dataCodewordsPerBlock:21}]},{ecCodewordsPerBlock:22,ecBlocks:[{numBlocks:12,dataCodewordsPerBlock:11},{numBlocks:4,dataCodewordsPerBlock:12}]}]},{infoBits:58893,versionNumber:14,alignmentPatternCenters:[6,26,46,66],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:3,dataCodewordsPerBlock:115},\n{numBlocks:1,dataCodewordsPerBlock:116}]},{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:40},{numBlocks:5,dataCodewordsPerBlock:41}]},{ecCodewordsPerBlock:20,ecBlocks:[{numBlocks:11,dataCodewordsPerBlock:16},{numBlocks:5,dataCodewordsPerBlock:17}]},{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:11,dataCodewordsPerBlock:12},{numBlocks:5,dataCodewordsPerBlock:13}]}]},{infoBits:63784,versionNumber:15,alignmentPatternCenters:[6,26,48,70],errorCorrectionLevels:[{ecCodewordsPerBlock:22,\necBlocks:[{numBlocks:5,dataCodewordsPerBlock:87},{numBlocks:1,dataCodewordsPerBlock:88}]},{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:5,dataCodewordsPerBlock:41},{numBlocks:5,dataCodewordsPerBlock:42}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:5,dataCodewordsPerBlock:24},{numBlocks:7,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:11,dataCodewordsPerBlock:12},{numBlocks:7,dataCodewordsPerBlock:13}]}]},{infoBits:68472,versionNumber:16,alignmentPatternCenters:[6,26,50,\n74],errorCorrectionLevels:[{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:5,dataCodewordsPerBlock:98},{numBlocks:1,dataCodewordsPerBlock:99}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:7,dataCodewordsPerBlock:45},{numBlocks:3,dataCodewordsPerBlock:46}]},{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:15,dataCodewordsPerBlock:19},{numBlocks:2,dataCodewordsPerBlock:20}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:3,dataCodewordsPerBlock:15},{numBlocks:13,dataCodewordsPerBlock:16}]}]},{infoBits:70749,\nversionNumber:17,alignmentPatternCenters:[6,30,54,78],errorCorrectionLevels:[{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:107},{numBlocks:5,dataCodewordsPerBlock:108}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:10,dataCodewordsPerBlock:46},{numBlocks:1,dataCodewordsPerBlock:47}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:22},{numBlocks:15,dataCodewordsPerBlock:23}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:14},{numBlocks:17,\ndataCodewordsPerBlock:15}]}]},{infoBits:76311,versionNumber:18,alignmentPatternCenters:[6,30,56,82],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:5,dataCodewordsPerBlock:120},{numBlocks:1,dataCodewordsPerBlock:121}]},{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:9,dataCodewordsPerBlock:43},{numBlocks:4,dataCodewordsPerBlock:44}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:17,dataCodewordsPerBlock:22},{numBlocks:1,dataCodewordsPerBlock:23}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:2,\ndataCodewordsPerBlock:14},{numBlocks:19,dataCodewordsPerBlock:15}]}]},{infoBits:79154,versionNumber:19,alignmentPatternCenters:[6,30,58,86],errorCorrectionLevels:[{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:3,dataCodewordsPerBlock:113},{numBlocks:4,dataCodewordsPerBlock:114}]},{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:3,dataCodewordsPerBlock:44},{numBlocks:11,dataCodewordsPerBlock:45}]},{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:17,dataCodewordsPerBlock:21},{numBlocks:4,dataCodewordsPerBlock:22}]},\n{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:9,dataCodewordsPerBlock:13},{numBlocks:16,dataCodewordsPerBlock:14}]}]},{infoBits:84390,versionNumber:20,alignmentPatternCenters:[6,34,62,90],errorCorrectionLevels:[{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:3,dataCodewordsPerBlock:107},{numBlocks:5,dataCodewordsPerBlock:108}]},{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:3,dataCodewordsPerBlock:41},{numBlocks:13,dataCodewordsPerBlock:42}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:15,dataCodewordsPerBlock:24},\n{numBlocks:5,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:15,dataCodewordsPerBlock:15},{numBlocks:10,dataCodewordsPerBlock:16}]}]},{infoBits:87683,versionNumber:21,alignmentPatternCenters:[6,28,50,72,94],errorCorrectionLevels:[{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:116},{numBlocks:4,dataCodewordsPerBlock:117}]},{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:17,dataCodewordsPerBlock:42}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:17,dataCodewordsPerBlock:22},\n{numBlocks:6,dataCodewordsPerBlock:23}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:19,dataCodewordsPerBlock:16},{numBlocks:6,dataCodewordsPerBlock:17}]}]},{infoBits:92361,versionNumber:22,alignmentPatternCenters:[6,26,50,74,98],errorCorrectionLevels:[{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:111},{numBlocks:7,dataCodewordsPerBlock:112}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:17,dataCodewordsPerBlock:46}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:7,dataCodewordsPerBlock:24},\n{numBlocks:16,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:34,dataCodewordsPerBlock:13}]}]},{infoBits:96236,versionNumber:23,alignmentPatternCenters:[6,30,54,74,102],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:121},{numBlocks:5,dataCodewordsPerBlock:122}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:47},{numBlocks:14,dataCodewordsPerBlock:48}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:11,dataCodewordsPerBlock:24},\n{numBlocks:14,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:16,dataCodewordsPerBlock:15},{numBlocks:14,dataCodewordsPerBlock:16}]}]},{infoBits:102084,versionNumber:24,alignmentPatternCenters:[6,28,54,80,106],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:6,dataCodewordsPerBlock:117},{numBlocks:4,dataCodewordsPerBlock:118}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:6,dataCodewordsPerBlock:45},{numBlocks:14,dataCodewordsPerBlock:46}]},{ecCodewordsPerBlock:30,\necBlocks:[{numBlocks:11,dataCodewordsPerBlock:24},{numBlocks:16,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:30,dataCodewordsPerBlock:16},{numBlocks:2,dataCodewordsPerBlock:17}]}]},{infoBits:102881,versionNumber:25,alignmentPatternCenters:[6,32,58,84,110],errorCorrectionLevels:[{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:8,dataCodewordsPerBlock:106},{numBlocks:4,dataCodewordsPerBlock:107}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:8,dataCodewordsPerBlock:47},{numBlocks:13,\ndataCodewordsPerBlock:48}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:7,dataCodewordsPerBlock:24},{numBlocks:22,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:22,dataCodewordsPerBlock:15},{numBlocks:13,dataCodewordsPerBlock:16}]}]},{infoBits:110507,versionNumber:26,alignmentPatternCenters:[6,30,58,86,114],errorCorrectionLevels:[{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:10,dataCodewordsPerBlock:114},{numBlocks:2,dataCodewordsPerBlock:115}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:19,\ndataCodewordsPerBlock:46},{numBlocks:4,dataCodewordsPerBlock:47}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:28,dataCodewordsPerBlock:22},{numBlocks:6,dataCodewordsPerBlock:23}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:33,dataCodewordsPerBlock:16},{numBlocks:4,dataCodewordsPerBlock:17}]}]},{infoBits:110734,versionNumber:27,alignmentPatternCenters:[6,34,62,90,118],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:8,dataCodewordsPerBlock:122},{numBlocks:4,dataCodewordsPerBlock:123}]},\n{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:22,dataCodewordsPerBlock:45},{numBlocks:3,dataCodewordsPerBlock:46}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:8,dataCodewordsPerBlock:23},{numBlocks:26,dataCodewordsPerBlock:24}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:12,dataCodewordsPerBlock:15},{numBlocks:28,dataCodewordsPerBlock:16}]}]},{infoBits:117786,versionNumber:28,alignmentPatternCenters:[6,26,50,74,98,122],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:3,dataCodewordsPerBlock:117},\n{numBlocks:10,dataCodewordsPerBlock:118}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:3,dataCodewordsPerBlock:45},{numBlocks:23,dataCodewordsPerBlock:46}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:24},{numBlocks:31,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:11,dataCodewordsPerBlock:15},{numBlocks:31,dataCodewordsPerBlock:16}]}]},{infoBits:119615,versionNumber:29,alignmentPatternCenters:[6,30,54,78,102,126],errorCorrectionLevels:[{ecCodewordsPerBlock:30,\necBlocks:[{numBlocks:7,dataCodewordsPerBlock:116},{numBlocks:7,dataCodewordsPerBlock:117}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:21,dataCodewordsPerBlock:45},{numBlocks:7,dataCodewordsPerBlock:46}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:23},{numBlocks:37,dataCodewordsPerBlock:24}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:19,dataCodewordsPerBlock:15},{numBlocks:26,dataCodewordsPerBlock:16}]}]},{infoBits:126325,versionNumber:30,alignmentPatternCenters:[6,\n26,52,78,104,130],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:5,dataCodewordsPerBlock:115},{numBlocks:10,dataCodewordsPerBlock:116}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:19,dataCodewordsPerBlock:47},{numBlocks:10,dataCodewordsPerBlock:48}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:15,dataCodewordsPerBlock:24},{numBlocks:25,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:23,dataCodewordsPerBlock:15},{numBlocks:25,dataCodewordsPerBlock:16}]}]},\n{infoBits:127568,versionNumber:31,alignmentPatternCenters:[6,30,56,82,108,134],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:13,dataCodewordsPerBlock:115},{numBlocks:3,dataCodewordsPerBlock:116}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:46},{numBlocks:29,dataCodewordsPerBlock:47}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:42,dataCodewordsPerBlock:24},{numBlocks:1,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:23,dataCodewordsPerBlock:15},\n{numBlocks:28,dataCodewordsPerBlock:16}]}]},{infoBits:133589,versionNumber:32,alignmentPatternCenters:[6,34,60,86,112,138],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:17,dataCodewordsPerBlock:115}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:10,dataCodewordsPerBlock:46},{numBlocks:23,dataCodewordsPerBlock:47}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:10,dataCodewordsPerBlock:24},{numBlocks:35,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:19,\ndataCodewordsPerBlock:15},{numBlocks:35,dataCodewordsPerBlock:16}]}]},{infoBits:136944,versionNumber:33,alignmentPatternCenters:[6,30,58,86,114,142],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:17,dataCodewordsPerBlock:115},{numBlocks:1,dataCodewordsPerBlock:116}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:14,dataCodewordsPerBlock:46},{numBlocks:21,dataCodewordsPerBlock:47}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:29,dataCodewordsPerBlock:24},{numBlocks:19,dataCodewordsPerBlock:25}]},\n{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:11,dataCodewordsPerBlock:15},{numBlocks:46,dataCodewordsPerBlock:16}]}]},{infoBits:141498,versionNumber:34,alignmentPatternCenters:[6,34,62,90,118,146],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:13,dataCodewordsPerBlock:115},{numBlocks:6,dataCodewordsPerBlock:116}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:14,dataCodewordsPerBlock:46},{numBlocks:23,dataCodewordsPerBlock:47}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:44,\ndataCodewordsPerBlock:24},{numBlocks:7,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:59,dataCodewordsPerBlock:16},{numBlocks:1,dataCodewordsPerBlock:17}]}]},{infoBits:145311,versionNumber:35,alignmentPatternCenters:[6,30,54,78,102,126,150],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:12,dataCodewordsPerBlock:121},{numBlocks:7,dataCodewordsPerBlock:122}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:12,dataCodewordsPerBlock:47},{numBlocks:26,dataCodewordsPerBlock:48}]},\n{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:39,dataCodewordsPerBlock:24},{numBlocks:14,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:22,dataCodewordsPerBlock:15},{numBlocks:41,dataCodewordsPerBlock:16}]}]},{infoBits:150283,versionNumber:36,alignmentPatternCenters:[6,24,50,76,102,128,154],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:6,dataCodewordsPerBlock:121},{numBlocks:14,dataCodewordsPerBlock:122}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:6,\ndataCodewordsPerBlock:47},{numBlocks:34,dataCodewordsPerBlock:48}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:46,dataCodewordsPerBlock:24},{numBlocks:10,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:15},{numBlocks:64,dataCodewordsPerBlock:16}]}]},{infoBits:152622,versionNumber:37,alignmentPatternCenters:[6,28,54,80,106,132,158],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:17,dataCodewordsPerBlock:122},{numBlocks:4,dataCodewordsPerBlock:123}]},\n{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:29,dataCodewordsPerBlock:46},{numBlocks:14,dataCodewordsPerBlock:47}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:49,dataCodewordsPerBlock:24},{numBlocks:10,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:24,dataCodewordsPerBlock:15},{numBlocks:46,dataCodewordsPerBlock:16}]}]},{infoBits:158308,versionNumber:38,alignmentPatternCenters:[6,32,58,84,110,136,162],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:4,\ndataCodewordsPerBlock:122},{numBlocks:18,dataCodewordsPerBlock:123}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:13,dataCodewordsPerBlock:46},{numBlocks:32,dataCodewordsPerBlock:47}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:48,dataCodewordsPerBlock:24},{numBlocks:14,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:42,dataCodewordsPerBlock:15},{numBlocks:32,dataCodewordsPerBlock:16}]}]},{infoBits:161089,versionNumber:39,alignmentPatternCenters:[6,26,54,82,110,138,166],\nerrorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:20,dataCodewordsPerBlock:117},{numBlocks:4,dataCodewordsPerBlock:118}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:40,dataCodewordsPerBlock:47},{numBlocks:7,dataCodewordsPerBlock:48}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:43,dataCodewordsPerBlock:24},{numBlocks:22,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:10,dataCodewordsPerBlock:15},{numBlocks:67,dataCodewordsPerBlock:16}]}]},{infoBits:167017,\nversionNumber:40,alignmentPatternCenters:[6,30,58,86,114,142,170],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:19,dataCodewordsPerBlock:118},{numBlocks:6,dataCodewordsPerBlock:119}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:18,dataCodewordsPerBlock:47},{numBlocks:31,dataCodewordsPerBlock:48}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:34,dataCodewordsPerBlock:24},{numBlocks:34,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:20,dataCodewordsPerBlock:15},\n{numBlocks:61,dataCodewordsPerBlock:16}]}]}];function J(a,b){a^=b;for(b=0;a;)b++,a&=a-1;return b}function K(a,b){return b<<1|a}\nlet ia=[{bits:21522,formatInfo:{errorCorrectionLevel:1,dataMask:0}},{bits:20773,formatInfo:{errorCorrectionLevel:1,dataMask:1}},{bits:24188,formatInfo:{errorCorrectionLevel:1,dataMask:2}},{bits:23371,formatInfo:{errorCorrectionLevel:1,dataMask:3}},{bits:17913,formatInfo:{errorCorrectionLevel:1,dataMask:4}},{bits:16590,formatInfo:{errorCorrectionLevel:1,dataMask:5}},{bits:20375,formatInfo:{errorCorrectionLevel:1,dataMask:6}},{bits:19104,formatInfo:{errorCorrectionLevel:1,dataMask:7}},{bits:30660,formatInfo:{errorCorrectionLevel:0,\ndataMask:0}},{bits:29427,formatInfo:{errorCorrectionLevel:0,dataMask:1}},{bits:32170,formatInfo:{errorCorrectionLevel:0,dataMask:2}},{bits:30877,formatInfo:{errorCorrectionLevel:0,dataMask:3}},{bits:26159,formatInfo:{errorCorrectionLevel:0,dataMask:4}},{bits:25368,formatInfo:{errorCorrectionLevel:0,dataMask:5}},{bits:27713,formatInfo:{errorCorrectionLevel:0,dataMask:6}},{bits:26998,formatInfo:{errorCorrectionLevel:0,dataMask:7}},{bits:5769,formatInfo:{errorCorrectionLevel:3,dataMask:0}},{bits:5054,\nformatInfo:{errorCorrectionLevel:3,dataMask:1}},{bits:7399,formatInfo:{errorCorrectionLevel:3,dataMask:2}},{bits:6608,formatInfo:{errorCorrectionLevel:3,dataMask:3}},{bits:1890,formatInfo:{errorCorrectionLevel:3,dataMask:4}},{bits:597,formatInfo:{errorCorrectionLevel:3,dataMask:5}},{bits:3340,formatInfo:{errorCorrectionLevel:3,dataMask:6}},{bits:2107,formatInfo:{errorCorrectionLevel:3,dataMask:7}},{bits:13663,formatInfo:{errorCorrectionLevel:2,dataMask:0}},{bits:12392,formatInfo:{errorCorrectionLevel:2,\ndataMask:1}},{bits:16177,formatInfo:{errorCorrectionLevel:2,dataMask:2}},{bits:14854,formatInfo:{errorCorrectionLevel:2,dataMask:3}},{bits:9396,formatInfo:{errorCorrectionLevel:2,dataMask:4}},{bits:8579,formatInfo:{errorCorrectionLevel:2,dataMask:5}},{bits:11994,formatInfo:{errorCorrectionLevel:2,dataMask:6}},{bits:11245,formatInfo:{errorCorrectionLevel:2,dataMask:7}}],ja=[a=>0===(a.y+a.x)%2,a=>0===a.y%2,a=>0===a.x%3,a=>0===(a.y+a.x)%3,a=>0===(Math.floor(a.y/2)+Math.floor(a.x/3))%2,a=>0===a.x*a.y%\n2+a.x*a.y%3,a=>0===(a.y*a.x%2+a.y*a.x%3)%2,a=>0===((a.y+a.x)%2+a.y*a.x%3)%2];\nfunction ka(a,b,c){c=ja[c.dataMask];let d=a.height;var e=17+4*b.versionNumber;let f=x.createEmpty(e,e);f.setRegion(0,0,9,9,!0);f.setRegion(e-8,0,8,9,!0);f.setRegion(0,e-8,9,8,!0);for(var g of b.alignmentPatternCenters)for(var h of b.alignmentPatternCenters)6===g&&6===h||6===g&&h===e-7||g===e-7&&6===h||f.setRegion(g-2,h-2,5,5,!0);f.setRegion(6,9,1,e-17,!0);f.setRegion(9,6,e-17,1,!0);6<b.versionNumber&&(f.setRegion(e-11,0,3,6,!0),f.setRegion(0,e-11,6,3,!0));b=[];h=g=0;e=!0;for(let k=d-1;0<k;k-=2){6===\nk&&k--;for(let m=0;m<d;m++){let l=e?d-1-m:m;for(let n=0;2>n;n++){let q=k-n;if(!f.get(q,l)){h++;let r=a.get(q,l);c({y:l,x:q})&&(r=!r);g=g<<1|r;8===h&&(b.push(g),g=h=0)}}}e=!e}return b}\nfunction la(a){var b=a.height,c=Math.floor((b-17)/4);if(6>=c)return I[c-1];c=0;for(var d=5;0<=d;d--)for(var e=b-9;e>=b-11;e--)c=K(a.get(e,d),c);d=0;for(e=5;0<=e;e--)for(let g=b-9;g>=b-11;g--)d=K(a.get(e,g),d);a=Infinity;let f;for(let g of I){if(g.infoBits===c||g.infoBits===d)return g;b=J(c,g.infoBits);b<a&&(f=g,a=b);b=J(d,g.infoBits);b<a&&(f=g,a=b)}if(3>=a)return f}\nfunction ma(a){let b=0;for(var c=0;8>=c;c++)6!==c&&(b=K(a.get(c,8),b));for(c=7;0<=c;c--)6!==c&&(b=K(a.get(8,c),b));var d=a.height;c=0;for(var e=d-1;e>=d-7;e--)c=K(a.get(8,e),c);for(e=d-8;e<d;e++)c=K(a.get(e,8),c);a=Infinity;d=null;for(let {bits:f,formatInfo:g}of ia){if(f===b||f===c)return g;e=J(b,f);e<a&&(d=g,a=e);b!==c&&(e=J(c,f),e<a&&(d=g,a=e))}return 3>=a?d:null}\nfunction na(a,b,c){let d=b.errorCorrectionLevels[c],e=[],f=0;d.ecBlocks.forEach(h=>{for(let k=0;k<h.numBlocks;k++)e.push({numDataCodewords:h.dataCodewordsPerBlock,codewords:[]}),f+=h.dataCodewordsPerBlock+d.ecCodewordsPerBlock});if(a.length<f)return null;a=a.slice(0,f);b=d.ecBlocks[0].dataCodewordsPerBlock;for(c=0;c<b;c++)for(var g of e)g.codewords.push(a.shift());if(1<d.ecBlocks.length)for(g=d.ecBlocks[0].numBlocks,b=d.ecBlocks[1].numBlocks,c=0;c<b;c++)e[g+c].codewords.push(a.shift());for(;0<a.length;)for(let h of e)h.codewords.push(a.shift());\nreturn e}function L(a){let b=la(a);if(!b)return null;var c=ma(a);if(!c)return null;a=ka(a,b,c);var d=na(a,b,c.errorCorrectionLevel);if(!d)return null;c=d.reduce((e,f)=>e+f.numDataCodewords,0);c=new Uint8ClampedArray(c);a=0;for(let e of d){d=ha(e.codewords,e.codewords.length-e.numDataCodewords);if(!d)return null;for(let f=0;f<e.numDataCodewords;f++)c[a++]=d[f]}try{return da(c,b.versionNumber)}catch(e){return null}}\nfunction M(a,b,c,d){var e=a.x-b.x+c.x-d.x;let f=a.y-b.y+c.y-d.y;if(0===e&&0===f)return{a11:b.x-a.x,a12:b.y-a.y,a13:0,a21:c.x-b.x,a22:c.y-b.y,a23:0,a31:a.x,a32:a.y,a33:1};let g=b.x-c.x;var h=d.x-c.x;let k=b.y-c.y,m=d.y-c.y;c=g*m-h*k;h=(e*m-h*f)/c;e=(g*f-e*k)/c;return{a11:b.x-a.x+h*b.x,a12:b.y-a.y+h*b.y,a13:h,a21:d.x-a.x+e*d.x,a22:d.y-a.y+e*d.y,a23:e,a31:a.x,a32:a.y,a33:1}}\nfunction oa(a,b,c,d){a=M(a,b,c,d);return{a11:a.a22*a.a33-a.a23*a.a32,a12:a.a13*a.a32-a.a12*a.a33,a13:a.a12*a.a23-a.a13*a.a22,a21:a.a23*a.a31-a.a21*a.a33,a22:a.a11*a.a33-a.a13*a.a31,a23:a.a13*a.a21-a.a11*a.a23,a31:a.a21*a.a32-a.a22*a.a31,a32:a.a12*a.a31-a.a11*a.a32,a33:a.a11*a.a22-a.a12*a.a21}}\nfunction pa(a,b){var c=oa({x:3.5,y:3.5},{x:b.dimension-3.5,y:3.5},{x:b.dimension-6.5,y:b.dimension-6.5},{x:3.5,y:b.dimension-3.5}),d=M(b.topLeft,b.topRight,b.alignmentPattern,b.bottomLeft),e=d.a11*c.a11+d.a21*c.a12+d.a31*c.a13,f=d.a12*c.a11+d.a22*c.a12+d.a32*c.a13,g=d.a13*c.a11+d.a23*c.a12+d.a33*c.a13,h=d.a11*c.a21+d.a21*c.a22+d.a31*c.a23,k=d.a12*c.a21+d.a22*c.a22+d.a32*c.a23,m=d.a13*c.a21+d.a23*c.a22+d.a33*c.a23,l=d.a11*c.a31+d.a21*c.a32+d.a31*c.a33,n=d.a12*c.a31+d.a22*c.a32+d.a32*c.a33,q=d.a13*\nc.a31+d.a23*c.a32+d.a33*c.a33;c=x.createEmpty(b.dimension,b.dimension);d=(r,u)=>{const p=g*r+m*u+q;return{x:(e*r+h*u+l)/p,y:(f*r+k*u+n)/p}};for(let r=0;r<b.dimension;r++)for(let u=0;u<b.dimension;u++){let p=d(u+.5,r+.5);c.set(u,r,a.get(Math.floor(p.x),Math.floor(p.y)))}return{matrix:c,mappingFunction:d}}let N=(a,b)=>Math.sqrt(Math.pow(b.x-a.x,2)+Math.pow(b.y-a.y,2));function O(a){return a.reduce((b,c)=>b+c)}\nfunction qa(a,b,c){let d=N(a,b),e=N(b,c),f=N(a,c),g,h,k;e>=d&&e>=f?[g,h,k]=[b,a,c]:f>=e&&f>=d?[g,h,k]=[a,b,c]:[g,h,k]=[a,c,b];0>(k.x-h.x)*(g.y-h.y)-(k.y-h.y)*(g.x-h.x)&&([g,k]=[k,g]);return{bottomLeft:g,topLeft:h,topRight:k}}\nfunction ra(a,b,c,d){d=(O(P(a,c,d,5))/7+O(P(a,b,d,5))/7+O(P(c,a,d,5))/7+O(P(b,a,d,5))/7)/4;if(1>d)throw Error("Invalid module size");b=Math.round(N(a,b)/d);a=Math.round(N(a,c)/d);a=Math.floor((b+a)/2)+7;switch(a%4){case 0:a++;break;case 2:a--}return{dimension:a,moduleSize:d}}\nfunction Q(a,b,c,d){let e=[{x:Math.floor(a.x),y:Math.floor(a.y)}];var f=Math.abs(b.y-a.y)>Math.abs(b.x-a.x);if(f){var g=Math.floor(a.y);var h=Math.floor(a.x);a=Math.floor(b.y);b=Math.floor(b.x)}else g=Math.floor(a.x),h=Math.floor(a.y),a=Math.floor(b.x),b=Math.floor(b.y);let k=Math.abs(a-g),m=Math.abs(b-h),l=Math.floor(-k/2),n=g<a?1:-1,q=h<b?1:-1,r=!0;for(let u=g,p=h;u!==a+n;u+=n){g=f?p:u;h=f?u:p;if(c.get(g,h)!==r&&(r=!r,e.push({x:g,y:h}),e.length===d+1))break;l+=m;if(0<l){if(p===b)break;p+=q;l-=k}}c=\n[];for(f=0;f<d;f++)e[f]&&e[f+1]?c.push(N(e[f],e[f+1])):c.push(0);return c}function P(a,b,c,d){let e=b.y-a.y,f=b.x-a.x;b=Q(a,b,c,Math.ceil(d/2));a=Q(a,{x:a.x-f,y:a.y-e},c,Math.ceil(d/2));c=b.shift()+a.shift()-1;return a.concat(c).concat(...b)}function R(a,b){let c=O(a)/O(b),d=0;b.forEach((e,f)=>{d+=Math.pow(a[f]-e*c,2)});return{averageSize:c,error:d}}\nfunction S(a,b,c){try{let d=P(a,{x:-1,y:a.y},c,b.length),e=P(a,{x:a.x,y:-1},c,b.length),f=P(a,{x:Math.max(0,a.x-a.y)-1,y:Math.max(0,a.y-a.x)-1},c,b.length),g=P(a,{x:Math.min(c.width,a.x+a.y)+1,y:Math.min(c.height,a.y+a.x)+1},c,b.length),h=R(d,b),k=R(e,b),m=R(f,b),l=R(g,b),n=(h.averageSize+k.averageSize+m.averageSize+l.averageSize)/4;return Math.sqrt(h.error*h.error+k.error*k.error+m.error*m.error+l.error*l.error)+(Math.pow(h.averageSize-n,2)+Math.pow(k.averageSize-n,2)+Math.pow(m.averageSize-n,2)+\nMath.pow(l.averageSize-n,2))/n}catch(d){return Infinity}}function T(a,b){for(var c=Math.round(b.x);a.get(c,Math.round(b.y));)c--;for(var d=Math.round(b.x);a.get(d,Math.round(b.y));)d++;c=(c+d)/2;for(d=Math.round(b.y);a.get(Math.round(c),d);)d--;for(b=Math.round(b.y);a.get(Math.round(c),b);)b++;return{x:c,y:(d+b)/2}}\nfunction sa(a){var b=[],c=[];let d=[];var e=[];for(let p=0;p<=a.height;p++){var f=0,g=!1;let t=[0,0,0,0,0];for(let v=-1;v<=a.width;v++){var h=a.get(v,p);if(h===g)f++;else{t=[t[1],t[2],t[3],t[4],f];f=1;g=h;var k=O(t)/7;k=Math.abs(t[0]-k)<k&&Math.abs(t[1]-k)<k&&Math.abs(t[2]-3*k)<3*k&&Math.abs(t[3]-k)<k&&Math.abs(t[4]-k)<k&&!h;var m=O(t.slice(-3))/3;h=Math.abs(t[2]-m)<m&&Math.abs(t[3]-m)<m&&Math.abs(t[4]-m)<m&&h;if(k){let z=v-t[3]-t[4],y=z-t[2];k={startX:y,endX:z,y:p};m=c.filter(w=>y>=w.bottom.startX&&\ny<=w.bottom.endX||z>=w.bottom.startX&&y<=w.bottom.endX||y<=w.bottom.startX&&z>=w.bottom.endX&&1.5>t[2]/(w.bottom.endX-w.bottom.startX)&&.5<t[2]/(w.bottom.endX-w.bottom.startX));0<m.length?m[0].bottom=k:c.push({top:k,bottom:k})}if(h){let z=v-t[4],y=z-t[3];h={startX:y,y:p,endX:z};k=e.filter(w=>y>=w.bottom.startX&&y<=w.bottom.endX||z>=w.bottom.startX&&y<=w.bottom.endX||y<=w.bottom.startX&&z>=w.bottom.endX&&1.5>t[2]/(w.bottom.endX-w.bottom.startX)&&.5<t[2]/(w.bottom.endX-w.bottom.startX));0<k.length?\nk[0].bottom=h:e.push({top:h,bottom:h})}}}b.push(...c.filter(v=>v.bottom.y!==p&&2<=v.bottom.y-v.top.y));c=c.filter(v=>v.bottom.y===p);d.push(...e.filter(v=>v.bottom.y!==p));e=e.filter(v=>v.bottom.y===p)}b.push(...c.filter(p=>2<=p.bottom.y-p.top.y));d.push(...e);c=[];for(var l of b)2>l.bottom.y-l.top.y||(b=(l.top.startX+l.top.endX+l.bottom.startX+l.bottom.endX)/4,e=(l.top.y+l.bottom.y+1)/2,a.get(Math.round(b),Math.round(e))&&(f=[l.top.endX-l.top.startX,l.bottom.endX-l.bottom.startX,l.bottom.y-l.top.y+\n1],f=O(f)/f.length,g=S({x:Math.round(b),y:Math.round(e)},[1,1,3,1,1],a),c.push({score:g,x:b,y:e,size:f})));if(3>c.length)return null;c.sort((p,t)=>p.score-t.score);l=[];for(b=0;b<Math.min(c.length,5);++b){e=c[b];f=[];for(var n of c)n!==e&&f.push(Object.assign(Object.assign({},n),{score:n.score+Math.pow(n.size-e.size,2)/e.size}));f.sort((p,t)=>p.score-t.score);l.push({points:[e,f[0],f[1]],score:e.score+f[0].score+f[1].score})}l.sort((p,t)=>p.score-t.score);let {topRight:q,topLeft:r,bottomLeft:u}=qa(...l[0].points);\nl=U(a,d,q,r,u);n=[];l&&n.push({alignmentPattern:{x:l.alignmentPattern.x,y:l.alignmentPattern.y},bottomLeft:{x:u.x,y:u.y},dimension:l.dimension,topLeft:{x:r.x,y:r.y},topRight:{x:q.x,y:q.y}});l=T(a,q);b=T(a,r);c=T(a,u);(a=U(a,d,l,b,c))&&n.push({alignmentPattern:{x:a.alignmentPattern.x,y:a.alignmentPattern.y},bottomLeft:{x:c.x,y:c.y},topLeft:{x:b.x,y:b.y},topRight:{x:l.x,y:l.y},dimension:a.dimension});return 0===n.length?null:n}\nfunction U(a,b,c,d,e){let f,g;try{({dimension:f,moduleSize:g}=ra(d,c,e,a))}catch(l){return null}var h=c.x-d.x+e.x,k=c.y-d.y+e.y;c=(N(d,e)+N(d,c))/2/g;e=1-3/c;let m={x:d.x+e*(h-d.x),y:d.y+e*(k-d.y)};b=b.map(l=>{const n=(l.top.startX+l.top.endX+l.bottom.startX+l.bottom.endX)/4;l=(l.top.y+l.bottom.y+1)/2;if(a.get(Math.floor(n),Math.floor(l))){var q=S({x:Math.floor(n),y:Math.floor(l)},[1,1,1],a)+N({x:n,y:l},m);return{x:n,y:l,score:q}}}).filter(l=>!!l).sort((l,n)=>l.score-n.score);return{alignmentPattern:15<=\nc&&b.length?b[0]:m,dimension:f}}\nfunction V(a){var b=sa(a);if(!b)return null;for(let e of b){b=pa(a,e);var c=b.matrix;if(null==c)c=null;else{var d=L(c);if(d)c=d;else{for(d=0;d<c.width;d++)for(let f=d+1;f<c.height;f++)c.get(d,f)!==c.get(f,d)&&(c.set(d,f,!c.get(d,f)),c.set(f,d,!c.get(f,d)));c=L(c)}}if(c)return{binaryData:c.bytes,data:c.text,chunks:c.chunks,version:c.version,location:{topRightCorner:b.mappingFunction(e.dimension,0),topLeftCorner:b.mappingFunction(0,0),bottomRightCorner:b.mappingFunction(e.dimension,e.dimension),bottomLeftCorner:b.mappingFunction(0,\ne.dimension),topRightFinderPattern:e.topRight,topLeftFinderPattern:e.topLeft,bottomLeftFinderPattern:e.bottomLeft,bottomRightAlignmentPattern:e.alignmentPattern},matrix:b.matrix}}return null}let ta={inversionAttempts:"attemptBoth",greyScaleWeights:{red:.2126,green:.7152,blue:.0722,useIntegerApproximation:!1},canOverwriteImage:!0};function W(a,b){Object.keys(b).forEach(c=>{a[c]=b[c]})}\nfunction X(a,b,c,d={}){let e=Object.create(null);W(e,ta);W(e,d);d="onlyInvert"===e.inversionAttempts||"invertFirst"===e.inversionAttempts;var f="attemptBoth"===e.inversionAttempts||d;var g=e.greyScaleWeights,h=e.canOverwriteImage,k=b*c;if(a.length!==4*k)throw Error("Malformed data passed to binarizer.");var m=0;if(h){var l=new Uint8ClampedArray(a.buffer,m,k);m+=k}l=new A(b,c,l);if(g.useIntegerApproximation)for(var n=0;n<c;n++)for(var q=0;q<b;q++){var r=4*(n*b+q);l.set(q,n,g.red*a[r]+g.green*a[r+1]+\ng.blue*a[r+2]+128>>8)}else for(n=0;n<c;n++)for(q=0;q<b;q++)r=4*(n*b+q),l.set(q,n,g.red*a[r]+g.green*a[r+1]+g.blue*a[r+2]);g=Math.ceil(b/8);n=Math.ceil(c/8);q=g*n;if(h){var u=new Uint8ClampedArray(a.buffer,m,q);m+=q}u=new A(g,n,u);for(q=0;q<n;q++)for(r=0;r<g;r++){var p=Infinity,t=0;for(var v=0;8>v;v++)for(let w=0;8>w;w++){let aa=l.get(8*r+w,8*q+v);p=Math.min(p,aa);t=Math.max(t,aa)}v=(p+t)/2;v=Math.min(255,1.11*v);24>=t-p&&(v=p/2,0<q&&0<r&&(t=(u.get(r,q-1)+2*u.get(r-1,q)+u.get(r-1,q-1))/4,p<t&&(v=t)));\nu.set(r,q,v)}h?(q=new Uint8ClampedArray(a.buffer,m,k),m+=k,q=new x(q,b)):q=x.createEmpty(b,c);r=null;f&&(h?(a=new Uint8ClampedArray(a.buffer,m,k),r=new x(a,b)):r=x.createEmpty(b,c));for(b=0;b<n;b++)for(a=0;a<g;a++){c=g-3;c=2>a?2:a>c?c:a;h=n-3;h=2>b?2:b>h?h:b;k=0;for(m=-2;2>=m;m++)for(p=-2;2>=p;p++)k+=u.get(c+m,h+p);c=k/25;for(h=0;8>h;h++)for(k=0;8>k;k++)m=8*a+h,p=8*b+k,t=l.get(m,p),q.set(m,p,t<=c),f&&r.set(m,p,!(t<=c))}f=f?{binarized:q,inverted:r}:{binarized:q};let {binarized:z,inverted:y}=f;(f=V(d?\ny:z))||"attemptBoth"!==e.inversionAttempts&&"invertFirst"!==e.inversionAttempts||(f=V(d?z:y));return f}X.default=X;let Y="dontInvert",Z={red:77,green:150,blue:29,useIntegerApproximation:!0};\nself.onmessage=a=>{let b=a.data.id,c=a.data.data;switch(a.data.type){case "decode":(a=X(c.data,c.width,c.height,{inversionAttempts:Y,greyScaleWeights:Z}))?self.postMessage({id:b,type:"qrResult",data:a.data,bytes:a.binaryData,cornerPoints:[a.location.topLeftCorner,a.location.topRightCorner,a.location.bottomRightCorner,a.location.bottomLeftCorner]}):self.postMessage({id:b,type:"qrResult",data:null});break;case "grayscaleWeights":Z.red=c.red;Z.green=c.green;Z.blue=c.blue;Z.useIntegerApproximation=c.useIntegerApproximation;\nbreak;case "inversionMode":switch(c){case "original":Y="dontInvert";break;case "invert":Y="onlyInvert";break;case "both":Y="attemptBoth";break;default:throw Error("Invalid inversion mode");}break;case "close":self.close()}}\n']),
|
|
56
|
+
{type:"application/javascript"}))});return c})
|
|
57
|
+
//# sourceMappingURL=qr-scanner.legacy.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qr-scanner.legacy.min.js","sources":["src/qr-scanner.ts"],"sourcesContent":["class QrScanner {\r\n static readonly DEFAULT_CANVAS_SIZE = 400;\r\n static readonly NO_QR_CODE_FOUND = 'No QR code found';\r\n private static _disableBarcodeDetector = false;\r\n private static _workerMessageId = 0;\r\n\r\n /** @deprecated */\r\n static set WORKER_PATH(workerPath: string) {\r\n console.warn('Setting QrScanner.WORKER_PATH is not required and not supported anymore. '\r\n + 'Have a look at the README for new setup instructions.');\r\n }\r\n\r\n static async hasCamera(): Promise<boolean> {\r\n try {\r\n return !!(await QrScanner.listCameras(false)).length;\r\n } catch (e) {\r\n return false;\r\n }\r\n }\r\n\r\n static async listCameras(requestLabels = false): Promise<Array<QrScanner.Camera>> {\r\n if (!navigator.mediaDevices) return [];\r\n\r\n const enumerateCameras = async (): Promise<Array<MediaDeviceInfo>> =>\r\n (await navigator.mediaDevices.enumerateDevices()).filter((device) => device.kind === 'videoinput');\r\n\r\n // Note that enumerateDevices can always be called and does not prompt the user for permission.\r\n // However, enumerateDevices only includes device labels if served via https and an active media stream exists\r\n // or permission to access the camera was given. Therefore, if we're not getting labels but labels are requested\r\n // ask for camera permission by opening a stream.\r\n let openedStream: MediaStream | undefined;\r\n try {\r\n if (requestLabels && (await enumerateCameras()).every((camera) => !camera.label)) {\r\n openedStream = await navigator.mediaDevices.getUserMedia({ audio: false, video: true });\r\n }\r\n } catch (e) {\r\n // Fail gracefully, especially if the device has no camera or on mobile when the camera is already in use\r\n // and some browsers disallow a second stream.\r\n }\r\n\r\n try {\r\n return (await enumerateCameras()).map((camera, i) => ({\r\n id: camera.deviceId,\r\n label: camera.label || (i === 0 ? 'Default Camera' : `Camera ${i + 1}`),\r\n }));\r\n } finally {\r\n // close the stream we just opened for getting camera access for listing the device labels\r\n if (openedStream) {\r\n console.warn('Call listCameras after successfully starting a QR scanner to avoid creating '\r\n + 'a temporary video stream');\r\n QrScanner._stopVideoStream(openedStream);\r\n }\r\n }\r\n }\r\n\r\n readonly $video: HTMLVideoElement;\r\n readonly $canvas: HTMLCanvasElement;\r\n readonly $overlay?: HTMLDivElement;\r\n private readonly $codeOutlineHighlight?: SVGSVGElement;\r\n private readonly _onDecode?: (result: QrScanner.ScanResult) => void;\r\n private readonly _legacyOnDecode?: (result: string) => void;\r\n private readonly _legacyCanvasSize: number = QrScanner.DEFAULT_CANVAS_SIZE;\r\n private _preferredCamera: QrScanner.FacingMode | QrScanner.DeviceId = 'environment';\r\n private readonly _maxScansPerSecond: number = 25;\r\n private _lastScanTimestamp: number = -1;\r\n private _scanRegion: QrScanner.ScanRegion;\r\n private _codeOutlineHighlightRemovalTimeout?: number;\r\n private _qrEnginePromise: Promise<Worker | BarcodeDetector>\r\n private _active: boolean = false;\r\n private _paused: boolean = false;\r\n private _flashOn: boolean = false;\r\n private _destroyed: boolean = false;\r\n\r\n constructor(\r\n video: HTMLVideoElement,\r\n onDecode: (result: QrScanner.ScanResult) => void,\r\n options: {\r\n onDecodeError?: (error: Error | string) => void,\r\n calculateScanRegion?: (video: HTMLVideoElement) => QrScanner.ScanRegion,\r\n preferredCamera?: QrScanner.FacingMode | QrScanner.DeviceId,\r\n maxScansPerSecond?: number;\r\n highlightScanRegion?: boolean,\r\n highlightCodeOutline?: boolean,\r\n overlay?: HTMLDivElement,\r\n /** just a temporary flag until we switch entirely to the new api */\r\n returnDetailedScanResult?: true,\r\n },\r\n );\r\n /** @deprecated */\r\n constructor(\r\n video: HTMLVideoElement,\r\n onDecode: (result: string) => void,\r\n onDecodeError?: (error: Error | string) => void,\r\n calculateScanRegion?: (video: HTMLVideoElement) => QrScanner.ScanRegion,\r\n preferredCamera?: QrScanner.FacingMode | QrScanner.DeviceId,\r\n );\r\n /** @deprecated */\r\n constructor(\r\n video: HTMLVideoElement,\r\n onDecode: (result: string) => void,\r\n onDecodeError?: (error: Error | string) => void,\r\n canvasSize?: number,\r\n preferredCamera?: QrScanner.FacingMode | QrScanner.DeviceId,\r\n );\r\n /** @deprecated */\r\n constructor(video: HTMLVideoElement, onDecode: (result: string) => void, canvasSize?: number);\r\n constructor(\r\n video: HTMLVideoElement,\r\n onDecode: ((result: QrScanner.ScanResult) => void) | ((result: string) => void),\r\n canvasSizeOrOnDecodeErrorOrOptions?: number | ((error: Error | string) => void) | {\r\n onDecodeError?: (error: Error | string) => void,\r\n calculateScanRegion?: (video: HTMLVideoElement) => QrScanner.ScanRegion,\r\n preferredCamera?: QrScanner.FacingMode | QrScanner.DeviceId,\r\n maxScansPerSecond?: number;\r\n highlightScanRegion?: boolean,\r\n highlightCodeOutline?: boolean,\r\n overlay?: HTMLDivElement,\r\n /** just a temporary flag until we switch entirely to the new api */\r\n returnDetailedScanResult?: true,\r\n },\r\n canvasSizeOrCalculateScanRegion?: number | ((video: HTMLVideoElement) => QrScanner.ScanRegion),\r\n preferredCamera?: QrScanner.FacingMode | QrScanner.DeviceId,\r\n ) {\r\n this.$video = video;\r\n this.$canvas = document.createElement('canvas');\r\n\r\n if (canvasSizeOrOnDecodeErrorOrOptions && typeof canvasSizeOrOnDecodeErrorOrOptions === 'object') {\r\n // we got an options object using the new api\r\n this._onDecode = onDecode as QrScanner['_onDecode'];\r\n } else {\r\n if (canvasSizeOrOnDecodeErrorOrOptions || canvasSizeOrCalculateScanRegion || preferredCamera) {\r\n console.warn('You\\'re using a deprecated version of the QrScanner constructor which will be removed in '\r\n + 'the future');\r\n } else {\r\n // Only video and onDecode were specified and we can't distinguish between new or old api usage. For\r\n // backwards compatibility we have to assume the old api for now. The options object is marked as non-\r\n // optional in the parameter list above to make clear that ScanResult instead of string is only passed\r\n // if an options object was provided. However, in the future once legacy support is removed, the options\r\n // object should become optional.\r\n console.warn('Note that the type of the scan result passed to onDecode will change in the future. '\r\n + 'To already switch to the new api today, you can pass returnDetailedScanResult: true.');\r\n }\r\n this._legacyOnDecode = onDecode as QrScanner['_legacyOnDecode'];\r\n }\r\n\r\n const options = typeof canvasSizeOrOnDecodeErrorOrOptions === 'object'\r\n ? canvasSizeOrOnDecodeErrorOrOptions\r\n : {};\r\n this._onDecodeError = options.onDecodeError || (typeof canvasSizeOrOnDecodeErrorOrOptions === 'function'\r\n ? canvasSizeOrOnDecodeErrorOrOptions\r\n : this._onDecodeError);\r\n this._calculateScanRegion = options.calculateScanRegion || (typeof canvasSizeOrCalculateScanRegion==='function'\r\n ? canvasSizeOrCalculateScanRegion\r\n : this._calculateScanRegion);\r\n this._preferredCamera = options.preferredCamera || preferredCamera || this._preferredCamera;\r\n this._legacyCanvasSize = typeof canvasSizeOrOnDecodeErrorOrOptions === 'number'\r\n ? canvasSizeOrOnDecodeErrorOrOptions\r\n : typeof canvasSizeOrCalculateScanRegion === 'number'\r\n ? canvasSizeOrCalculateScanRegion\r\n : this._legacyCanvasSize;\r\n this._maxScansPerSecond = options.maxScansPerSecond || this._maxScansPerSecond;\r\n\r\n this._onPlay = this._onPlay.bind(this);\r\n this._onLoadedMetaData = this._onLoadedMetaData.bind(this);\r\n this._onVisibilityChange = this._onVisibilityChange.bind(this);\r\n this._updateOverlay = this._updateOverlay.bind(this);\r\n\r\n // @ts-ignore\r\n video.disablePictureInPicture = true;\r\n // Allow inline playback on iPhone instead of requiring full screen playback,\r\n // see https://webkit.org/blog/6784/new-video-policies-for-ios/\r\n // @ts-ignore\r\n video.playsInline = true;\r\n // Allow play() on iPhone without requiring a user gesture. Should not really be needed as camera stream\r\n // includes no audio, but just to be safe.\r\n video.muted = true;\r\n\r\n // Avoid Safari stopping the video stream on a hidden video.\r\n // See https://github.com/cozmo/jsQR/issues/185\r\n let shouldHideVideo = false;\r\n if (video.hidden) {\r\n video.hidden = false;\r\n shouldHideVideo = true;\r\n }\r\n if (!document.body.contains(video)) {\r\n document.body.appendChild(video);\r\n shouldHideVideo = true;\r\n }\r\n const videoContainer = video.parentElement!;\r\n\r\n if (options.highlightScanRegion || options.highlightCodeOutline) {\r\n const gotExternalOverlay = !!options.overlay;\r\n this.$overlay = options.overlay || document.createElement('div');\r\n const overlayStyle = this.$overlay.style;\r\n overlayStyle.position = 'absolute';\r\n overlayStyle.display = 'none';\r\n overlayStyle.pointerEvents = 'none';\r\n this.$overlay.classList.add('scan-region-highlight');\r\n if (!gotExternalOverlay && options.highlightScanRegion) {\r\n // default style; can be overwritten via css, e.g. by changing the svg's stroke color, hiding the\r\n // .scan-region-highlight-svg, setting a border, outline, background, etc.\r\n this.$overlay.innerHTML = '<svg class=\"scan-region-highlight-svg\" viewBox=\"0 0 238 238\" '\r\n + 'preserveAspectRatio=\"none\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;'\r\n + 'fill:none;stroke:#e9b213;stroke-width:4;stroke-linecap:round;stroke-linejoin:round\">'\r\n + '<path d=\"M31 2H10a8 8 0 0 0-8 8v21M207 2h21a8 8 0 0 1 8 8v21m0 176v21a8 8 0 0 1-8 8h-21m-176 '\r\n + '0H10a8 8 0 0 1-8-8v-21\"/></svg>';\r\n try {\r\n this.$overlay.firstElementChild!.animate({ transform: ['scale(.98)', 'scale(1.01)'] }, {\r\n duration: 400,\r\n iterations: Infinity,\r\n direction: 'alternate',\r\n easing: 'ease-in-out',\r\n });\r\n } catch (e) {}\r\n videoContainer.insertBefore(this.$overlay, this.$video.nextSibling);\r\n }\r\n if (options.highlightCodeOutline) {\r\n // default style; can be overwritten via css\r\n this.$overlay.insertAdjacentHTML(\r\n 'beforeend',\r\n '<svg class=\"code-outline-highlight\" preserveAspectRatio=\"none\" style=\"display:none;width:100%;'\r\n + 'height:100%;fill:none;stroke:#e9b213;stroke-width:5;stroke-dasharray:25;'\r\n + 'stroke-linecap:round;stroke-linejoin:round\"><polygon/></svg>',\r\n );\r\n this.$codeOutlineHighlight = this.$overlay.lastElementChild as SVGSVGElement;\r\n }\r\n }\r\n this._scanRegion = this._calculateScanRegion(video);\r\n\r\n requestAnimationFrame(() => {\r\n // Checking in requestAnimationFrame which should avoid a potential additional re-flow for getComputedStyle.\r\n const videoStyle = window.getComputedStyle(video);\r\n if (videoStyle.display === 'none') {\r\n video.style.setProperty('display', 'block', 'important');\r\n shouldHideVideo = true;\r\n }\r\n if (videoStyle.visibility !== 'visible') {\r\n video.style.setProperty('visibility', 'visible', 'important');\r\n shouldHideVideo = true;\r\n }\r\n if (shouldHideVideo) {\r\n // Hide the video in a way that doesn't cause Safari to stop the playback.\r\n console.warn('QrScanner has overwritten the video hiding style to avoid Safari stopping the playback.');\r\n video.style.opacity = '0';\r\n video.style.width = '0';\r\n video.style.height = '0';\r\n if (this.$overlay && this.$overlay.parentElement) {\r\n this.$overlay.parentElement.removeChild(this.$overlay);\r\n }\r\n // @ts-ignore\r\n delete this.$overlay!;\r\n // @ts-ignore\r\n delete this.$codeOutlineHighlight!;\r\n }\r\n\r\n if (this.$overlay) {\r\n this._updateOverlay();\r\n }\r\n });\r\n\r\n video.addEventListener('play', this._onPlay);\r\n video.addEventListener('loadedmetadata', this._onLoadedMetaData);\r\n document.addEventListener('visibilitychange', this._onVisibilityChange);\r\n window.addEventListener('resize', this._updateOverlay);\r\n\r\n this._qrEnginePromise = QrScanner.createQrEngine();\r\n }\r\n\r\n async hasFlash(): Promise<boolean> {\r\n let stream: MediaStream | undefined;\r\n try {\r\n if (this.$video.srcObject) {\r\n if (!(this.$video.srcObject instanceof MediaStream)) return false; // srcObject is not a camera stream\r\n stream = this.$video.srcObject;\r\n } else {\r\n stream = (await this._getCameraStream()).stream;\r\n }\r\n return 'torch' in stream.getVideoTracks()[0].getSettings();\r\n } catch (e) {\r\n return false;\r\n } finally {\r\n // close the stream we just opened for detecting whether it supports flash\r\n if (stream && stream !== this.$video.srcObject) {\r\n console.warn('Call hasFlash after successfully starting the scanner to avoid creating '\r\n + 'a temporary video stream');\r\n QrScanner._stopVideoStream(stream);\r\n }\r\n }\r\n }\r\n\r\n isFlashOn(): boolean {\r\n return this._flashOn;\r\n }\r\n\r\n async toggleFlash(): Promise<void> {\r\n if (this._flashOn) {\r\n await this.turnFlashOff();\r\n } else {\r\n await this.turnFlashOn();\r\n }\r\n }\r\n\r\n async turnFlashOn(): Promise<void> {\r\n if (this._flashOn || this._destroyed) return;\r\n this._flashOn = true;\r\n if (!this._active || this._paused) return; // flash will be turned on later on .start()\r\n try {\r\n if (!await this.hasFlash()) throw 'No flash available';\r\n // Note that the video track is guaranteed to exist and to be a MediaStream due to the check in hasFlash\r\n await (this.$video.srcObject as MediaStream).getVideoTracks()[0].applyConstraints({\r\n // @ts-ignore: constraint 'torch' is unknown to ts\r\n advanced: [{ torch: true }],\r\n });\r\n } catch (e) {\r\n this._flashOn = false;\r\n throw e;\r\n }\r\n }\r\n\r\n async turnFlashOff(): Promise<void> {\r\n if (!this._flashOn) return;\r\n // applyConstraints with torch: false does not work to turn the flashlight off, as a stream's torch stays\r\n // continuously on, see https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints#torch. Therefore,\r\n // we have to stop the stream to turn the flashlight off.\r\n this._flashOn = false;\r\n await this._restartVideoStream();\r\n }\r\n\r\n destroy(): void {\r\n this.$video.removeEventListener('loadedmetadata', this._onLoadedMetaData);\r\n this.$video.removeEventListener('play', this._onPlay);\r\n document.removeEventListener('visibilitychange', this._onVisibilityChange);\r\n window.removeEventListener('resize', this._updateOverlay);\r\n\r\n this._destroyed = true;\r\n this._flashOn = false;\r\n this.stop(); // sets this._paused = true and this._active = false\r\n QrScanner._postWorkerMessage(this._qrEnginePromise, 'close');\r\n }\r\n\r\n async start(): Promise<void> {\r\n if (this._destroyed) throw new Error('The QR scanner can not be started as it had been destroyed.');\r\n if (this._active && !this._paused) return;\r\n\r\n if (window.location.protocol !== 'https:') {\r\n // warn but try starting the camera anyways\r\n console.warn('The camera stream is only accessible if the page is transferred via https.');\r\n }\r\n\r\n this._active = true;\r\n if (document.hidden) return; // camera will be started as soon as tab is in foreground\r\n this._paused = false;\r\n if (this.$video.srcObject) {\r\n // camera stream already/still set\r\n await this.$video.play();\r\n return;\r\n }\r\n\r\n try {\r\n const { stream, facingMode } = await this._getCameraStream();\r\n if (!this._active || this._paused) {\r\n // was stopped in the meantime\r\n QrScanner._stopVideoStream(stream);\r\n return;\r\n }\r\n this._setVideoMirror(facingMode);\r\n this.$video.srcObject = stream;\r\n await this.$video.play();\r\n\r\n // Restart the flash if it was previously on\r\n if (this._flashOn) {\r\n this._flashOn = false; // force turnFlashOn to restart the flash\r\n this.turnFlashOn().catch(() => {});\r\n }\r\n } catch (e) {\r\n if (this._paused) return;\r\n this._active = false;\r\n throw e;\r\n }\r\n }\r\n\r\n stop(): void {\r\n this.pause();\r\n this._active = false;\r\n }\r\n\r\n async pause(stopStreamImmediately = false): Promise<boolean> {\r\n this._paused = true;\r\n if (!this._active) return true;\r\n this.$video.pause();\r\n\r\n if (this.$overlay) {\r\n this.$overlay.style.display = 'none';\r\n }\r\n\r\n const stopStream = () => {\r\n if (this.$video.srcObject instanceof MediaStream) {\r\n // revoke srcObject only if it's a stream which was likely set by us\r\n QrScanner._stopVideoStream(this.$video.srcObject);\r\n this.$video.srcObject = null;\r\n }\r\n };\r\n\r\n if (stopStreamImmediately) {\r\n stopStream();\r\n return true;\r\n }\r\n\r\n await new Promise((resolve) => setTimeout(resolve, 300));\r\n if (!this._paused) return false;\r\n stopStream();\r\n return true;\r\n }\r\n\r\n async setCamera(facingModeOrDeviceId: QrScanner.FacingMode | QrScanner.DeviceId): Promise<void> {\r\n if (facingModeOrDeviceId === this._preferredCamera) return;\r\n this._preferredCamera = facingModeOrDeviceId;\r\n // Restart the scanner with the new camera which will also update the video mirror and the scan region.\r\n await this._restartVideoStream();\r\n }\r\n\r\n static async scanImage(\r\n imageOrFileOrBlobOrUrl: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | OffscreenCanvas | ImageBitmap\r\n | SVGImageElement | File | Blob | URL | String,\r\n options: {\r\n scanRegion?: QrScanner.ScanRegion | null,\r\n qrEngine?: Worker | BarcodeDetector | Promise<Worker | BarcodeDetector> | null,\r\n canvas?: HTMLCanvasElement | null,\r\n disallowCanvasResizing?: boolean,\r\n alsoTryWithoutScanRegion?: boolean,\r\n /** just a temporary flag until we switch entirely to the new api */\r\n returnDetailedScanResult?: true,\r\n },\r\n ): Promise<QrScanner.ScanResult>;\r\n /** @deprecated */\r\n static async scanImage(\r\n imageOrFileOrBlobOrUrl: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | OffscreenCanvas | ImageBitmap\r\n | SVGImageElement | File | Blob | URL | String,\r\n scanRegion?: QrScanner.ScanRegion | null,\r\n qrEngine?: Worker | BarcodeDetector | Promise<Worker | BarcodeDetector> | null,\r\n canvas?: HTMLCanvasElement | null,\r\n disallowCanvasResizing?: boolean,\r\n alsoTryWithoutScanRegion?: boolean,\r\n ): Promise<string>;\r\n static async scanImage(\r\n imageOrFileOrBlobOrUrl: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | OffscreenCanvas | ImageBitmap\r\n | SVGImageElement | File | Blob | URL | String,\r\n scanRegionOrOptions?: QrScanner.ScanRegion | {\r\n scanRegion?: QrScanner.ScanRegion | null,\r\n qrEngine?: Worker | BarcodeDetector | Promise<Worker | BarcodeDetector> | null,\r\n canvas?: HTMLCanvasElement | null,\r\n disallowCanvasResizing?: boolean,\r\n alsoTryWithoutScanRegion?: boolean,\r\n /** just a temporary flag until we switch entirely to the new api */\r\n returnDetailedScanResult?: true,\r\n } | null,\r\n qrEngine?: Worker | BarcodeDetector | Promise<Worker | BarcodeDetector> | null,\r\n canvas?: HTMLCanvasElement | null,\r\n disallowCanvasResizing: boolean = false,\r\n alsoTryWithoutScanRegion: boolean = false,\r\n ): Promise<string | QrScanner.ScanResult> {\r\n let scanRegion: QrScanner.ScanRegion | null | undefined;\r\n let returnDetailedScanResult = false;\r\n if (scanRegionOrOptions && (\r\n 'scanRegion' in scanRegionOrOptions\r\n || 'qrEngine' in scanRegionOrOptions\r\n || 'canvas' in scanRegionOrOptions\r\n || 'disallowCanvasResizing' in scanRegionOrOptions\r\n || 'alsoTryWithoutScanRegion' in scanRegionOrOptions\r\n || 'returnDetailedScanResult' in scanRegionOrOptions\r\n )) {\r\n // we got an options object using the new api\r\n scanRegion = scanRegionOrOptions.scanRegion;\r\n qrEngine = scanRegionOrOptions.qrEngine;\r\n canvas = scanRegionOrOptions.canvas;\r\n disallowCanvasResizing = scanRegionOrOptions.disallowCanvasResizing || false;\r\n alsoTryWithoutScanRegion = scanRegionOrOptions.alsoTryWithoutScanRegion || false;\r\n returnDetailedScanResult = true;\r\n } else if (scanRegionOrOptions || qrEngine || canvas || disallowCanvasResizing || alsoTryWithoutScanRegion) {\r\n console.warn('You\\'re using a deprecated api for scanImage which will be removed in the future.');\r\n } else {\r\n // Only imageOrFileOrBlobOrUrl was specified and we can't distinguish between new or old api usage. For\r\n // backwards compatibility we have to assume the old api for now. The options object is marked as non-\r\n // optional in the parameter list above to make clear that ScanResult instead of string is only returned if\r\n // an options object was provided. However, in the future once legacy support is removed, the options object\r\n // should become optional.\r\n console.warn('Note that the return type of scanImage will change in the future. To already switch to the '\r\n + 'new api today, you can pass returnDetailedScanResult: true.');\r\n }\r\n\r\n const gotExternalEngine = !!qrEngine;\r\n\r\n try {\r\n let image: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | OffscreenCanvas | ImageBitmap\r\n | SVGImageElement;\r\n let canvasContext: CanvasRenderingContext2D;\r\n [qrEngine, image] = await Promise.all([\r\n qrEngine || QrScanner.createQrEngine(),\r\n QrScanner._loadImage(imageOrFileOrBlobOrUrl),\r\n ]);\r\n [canvas, canvasContext] = QrScanner._drawToCanvas(image, scanRegion, canvas, disallowCanvasResizing);\r\n let detailedScanResult: QrScanner.ScanResult;\r\n\r\n if (qrEngine instanceof Worker) {\r\n const qrEngineWorker = qrEngine; // for ts to know that it's still a worker later in the event listeners\r\n if (!gotExternalEngine) {\r\n // Enable scanning of inverted color qr codes.\r\n QrScanner._postWorkerMessageSync(qrEngineWorker, 'inversionMode', 'both');\r\n }\r\n detailedScanResult = await new Promise((resolve, reject) => {\r\n let timeout: number;\r\n let onMessage: (event: MessageEvent) => void;\r\n let onError: (error: ErrorEvent | string) => void;\r\n let expectedResponseId = -1;\r\n onMessage = (event: MessageEvent) => {\r\n if (event.data.id !== expectedResponseId) {\r\n return;\r\n }\r\n qrEngineWorker.removeEventListener('message', onMessage);\r\n qrEngineWorker.removeEventListener('error', onError);\r\n clearTimeout(timeout);\r\n if (event.data.data !== null) {\r\n resolve({\r\n data: event.data.data,\r\n cornerPoints: QrScanner._convertPoints(event.data.cornerPoints, scanRegion),\r\n bytes: event.data.bytes\r\n });\r\n } else {\r\n reject(QrScanner.NO_QR_CODE_FOUND);\r\n }\r\n };\r\n onError = (error: ErrorEvent | string) => {\r\n qrEngineWorker.removeEventListener('message', onMessage);\r\n qrEngineWorker.removeEventListener('error', onError);\r\n clearTimeout(timeout);\r\n const errorMessage = !error ? 'Unknown Error' : ((error as ErrorEvent).message || error);\r\n reject('Scanner error: ' + errorMessage);\r\n };\r\n qrEngineWorker.addEventListener('message', onMessage);\r\n qrEngineWorker.addEventListener('error', onError);\r\n timeout = setTimeout(() => onError('timeout'), 10000);\r\n const imageData = canvasContext.getImageData(0, 0, canvas!.width, canvas!.height);\r\n expectedResponseId = QrScanner._postWorkerMessageSync(\r\n qrEngineWorker,\r\n 'decode',\r\n imageData,\r\n [imageData.data.buffer],\r\n );\r\n });\r\n } else {\r\n detailedScanResult = await Promise.race([\r\n new Promise<QrScanner.ScanResult>((resolve, reject) => window.setTimeout(\r\n () => reject('Scanner error: timeout'),\r\n 10000,\r\n )),\r\n (async (): Promise<QrScanner.ScanResult> => {\r\n try {\r\n const [scanResult] = await qrEngine.detect(canvas!);\r\n if (!scanResult) throw QrScanner.NO_QR_CODE_FOUND;\r\n return {\r\n data: scanResult.rawValue,\r\n cornerPoints: QrScanner._convertPoints(scanResult.cornerPoints, scanRegion),\r\n bytes: scanResult.rawValue.split('').map(c => c.charCodeAt(0)),\r\n };\r\n } catch (e) {\r\n const errorMessage = (e as Error).message || e as string;\r\n if (/not implemented|service unavailable/.test(errorMessage)) {\r\n // Not implemented can apparently for some reason happen even though getSupportedFormats\r\n // in createQrScanner reported that it's supported, see issue #98.\r\n // Service unavailable can happen after some time when the BarcodeDetector crashed and\r\n // can theoretically be recovered from by creating a new BarcodeDetector. However, in\r\n // newer browsers this issue does not seem to be present anymore and therefore we do not\r\n // apply this optimization anymore but just set _disableBarcodeDetector in both cases.\r\n // Also note that if we got an external qrEngine that crashed, we should possibly notify\r\n // the caller about it, but we also don't do this here, as it's such an unlikely case.\r\n QrScanner._disableBarcodeDetector = true;\r\n // retry without passing the broken BarcodeScanner instance\r\n return QrScanner.scanImage(imageOrFileOrBlobOrUrl, {\r\n scanRegion,\r\n canvas,\r\n disallowCanvasResizing,\r\n alsoTryWithoutScanRegion,\r\n });\r\n }\r\n throw `Scanner error: ${errorMessage}`;\r\n }\r\n })(),\r\n ]);\r\n }\r\n return returnDetailedScanResult ? detailedScanResult : detailedScanResult.data;\r\n } catch (e) {\r\n if (!scanRegion || !alsoTryWithoutScanRegion) throw e;\r\n const detailedScanResult = await QrScanner.scanImage(\r\n imageOrFileOrBlobOrUrl,\r\n { qrEngine, canvas, disallowCanvasResizing },\r\n );\r\n return returnDetailedScanResult ? detailedScanResult : detailedScanResult.data;\r\n } finally {\r\n if (!gotExternalEngine) {\r\n QrScanner._postWorkerMessage(qrEngine!, 'close');\r\n }\r\n }\r\n }\r\n\r\n setGrayscaleWeights(red: number, green: number, blue: number, useIntegerApproximation: boolean = true): void {\r\n // Note that for the native BarcodeDecoder or if the worker was destroyed, this is a no-op. However, the native\r\n // implementations work also well with colored qr codes.\r\n QrScanner._postWorkerMessage(\r\n this._qrEnginePromise,\r\n 'grayscaleWeights',\r\n { red, green, blue, useIntegerApproximation }\r\n );\r\n }\r\n\r\n setInversionMode(inversionMode: QrScanner.InversionMode): void {\r\n // Note that for the native BarcodeDecoder or if the worker was destroyed, this is a no-op. However, the native\r\n // implementations scan normal and inverted qr codes by default\r\n QrScanner._postWorkerMessage(this._qrEnginePromise, 'inversionMode', inversionMode);\r\n }\r\n\r\n static async createQrEngine(): Promise<Worker | BarcodeDetector>;\r\n /** @deprecated */\r\n static async createQrEngine(workerPath: string): Promise<Worker | BarcodeDetector>;\r\n static async createQrEngine(workerPath?: string): Promise<Worker | BarcodeDetector> {\r\n if (workerPath) {\r\n console.warn('Specifying a worker path is not required and not supported anymore.');\r\n }\r\n\r\n // @ts-ignore no types defined for import\r\n const createWorker = () => (import('./qr-scanner-worker.min.js') as Promise<{ createWorker: () => Worker }>)\r\n .then((module) => module.createWorker());\r\n\r\n const useBarcodeDetector = !QrScanner._disableBarcodeDetector\r\n && 'BarcodeDetector' in window\r\n && BarcodeDetector.getSupportedFormats\r\n && (await BarcodeDetector.getSupportedFormats()).includes('qr_code');\r\n\r\n if (!useBarcodeDetector) return createWorker();\r\n\r\n // On Macs with an M1/M2 processor and macOS Ventura (macOS version 13), the BarcodeDetector is broken in\r\n // Chromium based browsers, regardless of the version. For that constellation, the BarcodeDetector does not\r\n // error but does not detect QR codes. Macs without an M1/M2 or before Ventura are fine.\r\n // See issue #209 and https://bugs.chromium.org/p/chromium/issues/detail?id=1382442\r\n // TODO update this once the issue in macOS is fixed\r\n const userAgentData = navigator.userAgentData;\r\n const isChromiumOnMacWithArmVentura = userAgentData // all Chromium browsers support userAgentData\r\n && userAgentData.brands.some(({ brand }) => /Chromium/i.test(brand))\r\n && /mac ?OS/i.test(userAgentData.platform)\r\n // Does it have an ARM chip (e.g. M1/M2) and Ventura? Check this last as getHighEntropyValues can\r\n // theoretically trigger a browser prompt, although no browser currently does seem to show one.\r\n // If browser or user refused to return the requested values, assume broken ARM Ventura, to be safe.\r\n && await userAgentData.getHighEntropyValues(['architecture', 'platformVersion'])\r\n .then(({ architecture, platformVersion }) =>\r\n /arm/i.test(architecture || 'arm') && parseInt(platformVersion || '13') >= /* Ventura */ 13)\r\n .catch(() => true);\r\n if (isChromiumOnMacWithArmVentura) return createWorker();\r\n\r\n return new BarcodeDetector({ formats: ['qr_code'] });\r\n }\r\n\r\n private _onPlay(): void {\r\n this._scanRegion = this._calculateScanRegion(this.$video);\r\n this._updateOverlay();\r\n if (this.$overlay) {\r\n this.$overlay.style.display = '';\r\n }\r\n this._scanFrame();\r\n }\r\n\r\n private _onLoadedMetaData(): void {\r\n this._scanRegion = this._calculateScanRegion(this.$video);\r\n this._updateOverlay();\r\n }\r\n\r\n private _onVisibilityChange(): void {\r\n if (document.hidden) {\r\n this.pause();\r\n } else if (this._active) {\r\n this.start();\r\n }\r\n }\r\n\r\n private _calculateScanRegion(video: HTMLVideoElement): QrScanner.ScanRegion {\r\n // Default scan region calculation. Note that this can be overwritten in the constructor.\r\n const smallestDimension = Math.min(video.videoWidth, video.videoHeight);\r\n const scanRegionSize = Math.round(2 / 3 * smallestDimension);\r\n return {\r\n x: Math.round((video.videoWidth - scanRegionSize) / 2),\r\n y: Math.round((video.videoHeight - scanRegionSize) / 2),\r\n width: scanRegionSize,\r\n height: scanRegionSize,\r\n downScaledWidth: this._legacyCanvasSize,\r\n downScaledHeight: this._legacyCanvasSize,\r\n };\r\n }\r\n\r\n private _updateOverlay(): void {\r\n requestAnimationFrame(() => {\r\n // Running in requestAnimationFrame which should avoid a potential additional re-flow for getComputedStyle\r\n // and offsetWidth, offsetHeight, offsetLeft, offsetTop.\r\n if (!this.$overlay) return;\r\n const video = this.$video;\r\n const videoWidth = video.videoWidth;\r\n const videoHeight = video.videoHeight;\r\n const elementWidth = video.offsetWidth;\r\n const elementHeight = video.offsetHeight;\r\n const elementX = video.offsetLeft;\r\n const elementY = video.offsetTop;\r\n\r\n const videoStyle = window.getComputedStyle(video);\r\n const videoObjectFit = videoStyle.objectFit;\r\n const videoAspectRatio = videoWidth / videoHeight;\r\n const elementAspectRatio = elementWidth / elementHeight;\r\n let videoScaledWidth: number;\r\n let videoScaledHeight: number;\r\n switch (videoObjectFit) {\r\n case 'none':\r\n videoScaledWidth = videoWidth;\r\n videoScaledHeight = videoHeight;\r\n break;\r\n case 'fill':\r\n videoScaledWidth = elementWidth;\r\n videoScaledHeight = elementHeight;\r\n break;\r\n default: // 'cover', 'contains', 'scale-down'\r\n if (videoObjectFit === 'cover'\r\n ? videoAspectRatio > elementAspectRatio\r\n : videoAspectRatio < elementAspectRatio) {\r\n // The scaled height is the element height\r\n // - for 'cover' if the video aspect ratio is wider than the element aspect ratio\r\n // (scaled height matches element height and scaled width overflows element width)\r\n // - for 'contains'/'scale-down' if element aspect ratio is wider than the video aspect ratio\r\n // (scaled height matched element height and element width overflows scaled width)\r\n videoScaledHeight = elementHeight;\r\n videoScaledWidth = videoScaledHeight * videoAspectRatio;\r\n } else {\r\n videoScaledWidth = elementWidth;\r\n videoScaledHeight = videoScaledWidth / videoAspectRatio;\r\n }\r\n if (videoObjectFit === 'scale-down') {\r\n // for 'scale-down' the dimensions are the minimum of 'contains' and 'none'\r\n videoScaledWidth = Math.min(videoScaledWidth, videoWidth);\r\n videoScaledHeight = Math.min(videoScaledHeight, videoHeight);\r\n }\r\n }\r\n\r\n // getComputedStyle is so nice to convert keywords (left, center, right, top, bottom) to percent and makes\r\n // sure to set the default of 50% if only one or no component was provided, therefore we can be sure that\r\n // both components are set. Additionally, it converts units other than px (e.g. rem) to px.\r\n const [videoX, videoY] = videoStyle.objectPosition.split(' ').map((length, i) => {\r\n const lengthValue = parseFloat(length);\r\n return length.endsWith('%')\r\n ? (!i ? elementWidth - videoScaledWidth : elementHeight - videoScaledHeight) * lengthValue / 100\r\n : lengthValue;\r\n });\r\n\r\n const regionWidth = this._scanRegion.width || videoWidth;\r\n const regionHeight = this._scanRegion.height || videoHeight;\r\n const regionX = this._scanRegion.x || 0;\r\n const regionY = this._scanRegion.y || 0;\r\n\r\n const overlayStyle = this.$overlay.style;\r\n overlayStyle.width = `${regionWidth / videoWidth * videoScaledWidth}px`;\r\n overlayStyle.height = `${regionHeight / videoHeight * videoScaledHeight}px`;\r\n overlayStyle.top = `${elementY + videoY + regionY / videoHeight * videoScaledHeight}px`;\r\n const isVideoMirrored = /scaleX\\(-1\\)/.test(video.style.transform!);\r\n overlayStyle.left = `${elementX\r\n + (isVideoMirrored ? elementWidth - videoX - videoScaledWidth : videoX)\r\n + (isVideoMirrored ? videoWidth - regionX - regionWidth : regionX) / videoWidth * videoScaledWidth}px`;\r\n // apply same mirror as on video\r\n overlayStyle.transform = video.style.transform;\r\n });\r\n }\r\n\r\n private static _convertPoints(\r\n points: QrScanner.Point[],\r\n scanRegion?: QrScanner.ScanRegion | null,\r\n ): QrScanner.Point[] {\r\n if (!scanRegion) return points;\r\n const offsetX = scanRegion.x || 0;\r\n const offsetY = scanRegion.y || 0;\r\n const scaleFactorX = scanRegion.width && scanRegion.downScaledWidth\r\n ? scanRegion.width / scanRegion.downScaledWidth\r\n : 1;\r\n const scaleFactorY = scanRegion.height && scanRegion.downScaledHeight\r\n ? scanRegion.height / scanRegion.downScaledHeight\r\n : 1;\r\n for (const point of points) {\r\n point.x = point.x * scaleFactorX + offsetX;\r\n point.y = point.y * scaleFactorY + offsetY;\r\n }\r\n return points;\r\n }\r\n\r\n private _scanFrame(): void {\r\n if (!this._active || this.$video.paused || this.$video.ended) return;\r\n // If requestVideoFrameCallback is available use that to avoid unnecessary scans on the same frame as the\r\n // camera's framerate can be lower than the screen refresh rate and this._maxScansPerSecond, especially in dark\r\n // settings where the exposure time is longer. Both, requestVideoFrameCallback and requestAnimationFrame are not\r\n // being fired if the tab is in the background, which is what we want.\r\n const requestFrame = 'requestVideoFrameCallback' in this.$video\r\n // @ts-ignore\r\n ? this.$video.requestVideoFrameCallback.bind(this.$video)\r\n : requestAnimationFrame;\r\n requestFrame(async () => {\r\n if (this.$video.readyState <= 1) {\r\n // Skip scans until the video is ready as drawImage() only works correctly on a video with readyState\r\n // > 1, see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage#Notes.\r\n // This also avoids false positives for videos paused after a successful scan which remains visible on\r\n // the canvas until the video is started again and ready.\r\n this._scanFrame();\r\n return;\r\n }\r\n\r\n const timeSinceLastScan = Date.now() - this._lastScanTimestamp;\r\n const minimumTimeBetweenScans = 1000 / this._maxScansPerSecond;\r\n if (timeSinceLastScan < minimumTimeBetweenScans) {\r\n await new Promise((resolve) => setTimeout(resolve, minimumTimeBetweenScans - timeSinceLastScan));\r\n }\r\n // console.log('Scan rate:', Math.round(1000 / (Date.now() - this._lastScanTimestamp)));\r\n this._lastScanTimestamp = Date.now();\r\n\r\n let result: QrScanner.ScanResult | undefined;\r\n try {\r\n result = await QrScanner.scanImage(this.$video, {\r\n scanRegion: this._scanRegion,\r\n qrEngine: this._qrEnginePromise,\r\n canvas: this.$canvas,\r\n });\r\n } catch (error) {\r\n if (!this._active) return;\r\n this._onDecodeError(error as Error | string);\r\n }\r\n\r\n if (QrScanner._disableBarcodeDetector && !(await this._qrEnginePromise instanceof Worker)) {\r\n // replace the disabled BarcodeDetector\r\n this._qrEnginePromise = QrScanner.createQrEngine();\r\n }\r\n\r\n if (result) {\r\n if (this._onDecode) {\r\n this._onDecode(result);\r\n } else if (this._legacyOnDecode) {\r\n this._legacyOnDecode(result.data);\r\n }\r\n\r\n if (this.$codeOutlineHighlight) {\r\n clearTimeout(this._codeOutlineHighlightRemovalTimeout);\r\n this._codeOutlineHighlightRemovalTimeout = undefined;\r\n this.$codeOutlineHighlight.setAttribute(\r\n 'viewBox',\r\n `${this._scanRegion.x || 0} `\r\n + `${this._scanRegion.y || 0} `\r\n + `${this._scanRegion.width || this.$video.videoWidth} `\r\n + `${this._scanRegion.height || this.$video.videoHeight}`,\r\n );\r\n const polygon = this.$codeOutlineHighlight.firstElementChild!;\r\n polygon.setAttribute('points', result.cornerPoints.map(({x, y}) => `${x},${y}`).join(' '));\r\n this.$codeOutlineHighlight.style.display = '';\r\n }\r\n } else if (this.$codeOutlineHighlight && !this._codeOutlineHighlightRemovalTimeout) {\r\n // hide after timeout to make it flash less when on some frames the QR code is detected and on some not\r\n this._codeOutlineHighlightRemovalTimeout = setTimeout(\r\n () => this.$codeOutlineHighlight!.style.display = 'none',\r\n 100,\r\n );\r\n }\r\n\r\n this._scanFrame();\r\n });\r\n }\r\n\r\n private _onDecodeError(error: Error | string): void {\r\n // default error handler; can be overwritten in the constructor\r\n if (error === QrScanner.NO_QR_CODE_FOUND) return;\r\n console.log(error);\r\n }\r\n\r\n private async _getCameraStream(): Promise<{ stream: MediaStream, facingMode: QrScanner.FacingMode }> {\r\n if (!navigator.mediaDevices) throw 'Camera not found.';\r\n\r\n const preferenceType = /^(environment|user)$/.test(this._preferredCamera)\r\n ? 'facingMode'\r\n : 'deviceId';\r\n const constraintsWithoutCamera: Array<MediaTrackConstraints> = [{\r\n width: { min: 1024 }\r\n }, {\r\n width: { min: 768 }\r\n }, {}];\r\n const constraintsWithCamera = constraintsWithoutCamera.map((constraint) => Object.assign({}, constraint, {\r\n [preferenceType]: { exact: this._preferredCamera },\r\n }));\r\n\r\n for (const constraints of [...constraintsWithCamera, ...constraintsWithoutCamera]) {\r\n try {\r\n const stream = await navigator.mediaDevices.getUserMedia({ video: constraints, audio: false });\r\n // Try to determine the facing mode from the stream, otherwise use a guess or 'environment' as\r\n // default. Note that the guess is not always accurate as Safari returns cameras of different facing\r\n // mode, even for exact facingMode constraints.\r\n const facingMode = this._getFacingMode(stream)\r\n || (constraints.facingMode\r\n ? this._preferredCamera as QrScanner.FacingMode // a facing mode we were able to fulfill\r\n : (this._preferredCamera === 'environment'\r\n ? 'user' // switch as _preferredCamera was environment but we are not able to fulfill it\r\n : 'environment' // switch from unfulfilled user facingMode or default to environment\r\n )\r\n );\r\n return { stream, facingMode };\r\n } catch (e) {}\r\n }\r\n\r\n throw 'Camera not found.';\r\n }\r\n\r\n private async _restartVideoStream(): Promise<void> {\r\n // Note that we always pause the stream and not only if !this._paused as even if this._paused === true, the\r\n // stream might still be running, as it's by default only stopped after a delay of 300ms.\r\n const wasPaused = this._paused;\r\n const paused = await this.pause(true);\r\n if (!paused || wasPaused || !this._active) return;\r\n await this.start();\r\n }\r\n\r\n private static _stopVideoStream(stream : MediaStream): void {\r\n for (const track of stream.getTracks()) {\r\n track.stop(); // note that this will also automatically turn the flashlight off\r\n stream.removeTrack(track);\r\n }\r\n }\r\n\r\n private _setVideoMirror(facingMode: QrScanner.FacingMode): void {\r\n // in user facing mode mirror the video to make it easier for the user to position the QR code\r\n const scaleFactor = facingMode === 'user'? -1 : 1;\r\n this.$video.style.transform = 'scaleX(' + scaleFactor + ')';\r\n }\r\n\r\n private _getFacingMode(videoStream: MediaStream): QrScanner.FacingMode | null {\r\n const videoTrack = videoStream.getVideoTracks()[0];\r\n if (!videoTrack) return null; // unknown\r\n // inspired by https://github.com/JodusNodus/react-qr-reader/blob/master/src/getDeviceId.js#L13\r\n return /rear|back|environment/i.test(videoTrack.label)\r\n ? 'environment'\r\n : /front|user|face/i.test(videoTrack.label)\r\n ? 'user'\r\n : null; // unknown\r\n }\r\n\r\n private static _drawToCanvas(\r\n image: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | OffscreenCanvas | ImageBitmap\r\n | SVGImageElement,\r\n scanRegion?: QrScanner.ScanRegion | null,\r\n canvas?: HTMLCanvasElement | null,\r\n disallowCanvasResizing= false,\r\n ): [HTMLCanvasElement, CanvasRenderingContext2D] {\r\n canvas = canvas || document.createElement('canvas');\r\n const scanRegionX = scanRegion && scanRegion.x ? scanRegion.x : 0;\r\n const scanRegionY = scanRegion && scanRegion.y ? scanRegion.y : 0;\r\n const scanRegionWidth = scanRegion && scanRegion.width\r\n ? scanRegion.width\r\n : (image as HTMLVideoElement).videoWidth || image.width as number;\r\n const scanRegionHeight = scanRegion && scanRegion.height\r\n ? scanRegion.height\r\n : (image as HTMLVideoElement).videoHeight || image.height as number;\r\n\r\n if (!disallowCanvasResizing) {\r\n const canvasWidth = scanRegion && scanRegion.downScaledWidth\r\n ? scanRegion.downScaledWidth\r\n : scanRegionWidth;\r\n const canvasHeight = scanRegion && scanRegion.downScaledHeight\r\n ? scanRegion.downScaledHeight\r\n : scanRegionHeight;\r\n // Setting the canvas width or height clears the canvas, even if the values didn't change, therefore only\r\n // set them if they actually changed.\r\n if (canvas.width !== canvasWidth) {\r\n canvas.width = canvasWidth;\r\n }\r\n if (canvas.height !== canvasHeight) {\r\n canvas.height = canvasHeight;\r\n }\r\n }\r\n\r\n const context = canvas.getContext('2d', { alpha: false })!;\r\n context.imageSmoothingEnabled = false; // gives less blurry images\r\n context.drawImage(\r\n image,\r\n scanRegionX, scanRegionY, scanRegionWidth, scanRegionHeight,\r\n 0, 0, canvas.width, canvas.height,\r\n );\r\n return [canvas, context];\r\n }\r\n\r\n private static async _loadImage(\r\n imageOrFileOrBlobOrUrl: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | OffscreenCanvas | ImageBitmap\r\n | SVGImageElement | File | Blob | URL | String,\r\n ): Promise<HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | OffscreenCanvas | ImageBitmap\r\n | SVGImageElement > {\r\n if (imageOrFileOrBlobOrUrl instanceof Image) {\r\n await QrScanner._awaitImageLoad(imageOrFileOrBlobOrUrl);\r\n return imageOrFileOrBlobOrUrl;\r\n } else if (imageOrFileOrBlobOrUrl instanceof HTMLVideoElement\r\n || imageOrFileOrBlobOrUrl instanceof HTMLCanvasElement\r\n || imageOrFileOrBlobOrUrl instanceof SVGImageElement\r\n || 'OffscreenCanvas' in window && imageOrFileOrBlobOrUrl instanceof OffscreenCanvas\r\n || 'ImageBitmap' in window && imageOrFileOrBlobOrUrl instanceof ImageBitmap) {\r\n return imageOrFileOrBlobOrUrl;\r\n } else if (imageOrFileOrBlobOrUrl instanceof File || imageOrFileOrBlobOrUrl instanceof Blob\r\n || imageOrFileOrBlobOrUrl instanceof URL || typeof imageOrFileOrBlobOrUrl === 'string') {\r\n const image = new Image();\r\n if (imageOrFileOrBlobOrUrl instanceof File || imageOrFileOrBlobOrUrl instanceof Blob) {\r\n image.src = URL.createObjectURL(imageOrFileOrBlobOrUrl);\r\n } else {\r\n image.src = imageOrFileOrBlobOrUrl.toString();\r\n }\r\n try {\r\n await QrScanner._awaitImageLoad(image);\r\n return image;\r\n } finally {\r\n if (imageOrFileOrBlobOrUrl instanceof File || imageOrFileOrBlobOrUrl instanceof Blob) {\r\n URL.revokeObjectURL(image.src);\r\n }\r\n }\r\n } else {\r\n throw 'Unsupported image type.';\r\n }\r\n }\r\n\r\n private static async _awaitImageLoad(image: HTMLImageElement): Promise<void> {\r\n if (image.complete && image.naturalWidth !== 0) return; // already loaded\r\n await new Promise<void>((resolve, reject) => {\r\n const listener = (event: ErrorEvent | Event) => {\r\n image.removeEventListener('load', listener);\r\n image.removeEventListener('error', listener);\r\n if (event instanceof ErrorEvent) {\r\n reject('Image load error');\r\n } else {\r\n resolve();\r\n }\r\n };\r\n image.addEventListener('load', listener);\r\n image.addEventListener('error', listener);\r\n });\r\n }\r\n\r\n private static async _postWorkerMessage(\r\n qrEngineOrQrEnginePromise: Worker | BarcodeDetector | Promise<Worker | BarcodeDetector>,\r\n type: string,\r\n data?: any,\r\n transfer?: Transferable[],\r\n ): Promise<number> {\r\n return QrScanner._postWorkerMessageSync(await qrEngineOrQrEnginePromise, type, data, transfer);\r\n }\r\n\r\n // sync version of _postWorkerMessage without performance overhead of async functions\r\n private static _postWorkerMessageSync(\r\n qrEngine: Worker | BarcodeDetector,\r\n type: string,\r\n data?: any,\r\n transfer?: Transferable[],\r\n ): number {\r\n if (!(qrEngine instanceof Worker)) return -1;\r\n const id = QrScanner._workerMessageId++;\r\n qrEngine.postMessage({\r\n id,\r\n type,\r\n data,\r\n }, transfer);\r\n return id;\r\n }\r\n}\r\n\r\ndeclare namespace QrScanner {\r\n export interface ScanRegion {\r\n x?: number;\r\n y?: number;\r\n width?: number;\r\n height?: number;\r\n downScaledWidth?: number;\r\n downScaledHeight?: number;\r\n }\r\n\r\n export type FacingMode = 'environment' | 'user';\r\n export type DeviceId = string;\r\n\r\n export interface Camera {\r\n id: DeviceId;\r\n label: string;\r\n }\r\n\r\n export type InversionMode = 'original' | 'invert' | 'both';\r\n\r\n export interface Point {\r\n x: number;\r\n y: number;\r\n }\r\n\r\n export interface ScanResult {\r\n data: string;\r\n // In clockwise order, starting at top left, but this might not be guaranteed in the future.\r\n cornerPoints: QrScanner.Point[];\r\n bytes: Number[];\r\n }\r\n}\r\n\r\n// simplified from https://wicg.github.io/shape-detection-api/#barcode-detection-api\r\ndeclare class BarcodeDetector {\r\n constructor(options?: { formats: string[] });\r\n static getSupportedFormats(): Promise<string[]>;\r\n detect(image: ImageBitmapSource): Promise<Array<{ rawValue: string, cornerPoints: QrScanner.Point[] }>>;\r\n}\r\n\r\n// simplified from https://github.com/lukewarlow/user-agent-data-types/blob/master/index.d.ts\r\ndeclare global {\r\n interface Navigator {\r\n readonly userAgentData?: {\r\n readonly platform: string;\r\n readonly brands: Array<{\r\n readonly brand: string;\r\n readonly version: string;\r\n }>;\r\n getHighEntropyValues(hints: string[]): Promise<{\r\n readonly architecture?: string;\r\n readonly platformVersion?: string;\r\n }>;\r\n };\r\n }\r\n}\r\n\r\nexport default QrScanner;\r\n"],"names":[],"mappings":"iBAuBQ,QAAA,OAAA,EAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
class e{static set WORKER_PATH(a){console.warn("Setting QrScanner.WORKER_PATH is not required and not supported anymore. Have a look at the README for new setup instructions.")}static async hasCamera(){try{return!!(await e.listCameras(!1)).length}catch(a){return!1}}static async listCameras(a=!1){if(!navigator.mediaDevices)return[];let b=async()=>(await navigator.mediaDevices.enumerateDevices()).filter(d=>"videoinput"===d.kind),c;try{a&&(await b()).every(d=>!d.label)&&(c=await navigator.mediaDevices.getUserMedia({audio:!1,
|
|
2
|
+
video:!0}))}catch(d){}try{return(await b()).map((d,f)=>({id:d.deviceId,label:d.label||(0===f?"Default Camera":`Camera ${f+1}`)}))}finally{c&&(console.warn("Call listCameras after successfully starting a QR scanner to avoid creating a temporary video stream"),e._stopVideoStream(c))}}constructor(a,b,c,d,f){this._legacyCanvasSize=e.DEFAULT_CANVAS_SIZE;this._preferredCamera="environment";this._maxScansPerSecond=25;this._lastScanTimestamp=-1;this._destroyed=this._flashOn=this._paused=this._active=!1;this.$video=
|
|
3
|
+
a;this.$canvas=document.createElement("canvas");c&&"object"===typeof c?this._onDecode=b:(c||d||f?console.warn("You're using a deprecated version of the QrScanner constructor which will be removed in the future"):console.warn("Note that the type of the scan result passed to onDecode will change in the future. To already switch to the new api today, you can pass returnDetailedScanResult: true."),this._legacyOnDecode=b);b="object"===typeof c?c:{};this._onDecodeError=b.onDecodeError||("function"===typeof c?
|
|
4
|
+
c:this._onDecodeError);this._calculateScanRegion=b.calculateScanRegion||("function"===typeof d?d:this._calculateScanRegion);this._preferredCamera=b.preferredCamera||f||this._preferredCamera;this._legacyCanvasSize="number"===typeof c?c:"number"===typeof d?d:this._legacyCanvasSize;this._maxScansPerSecond=b.maxScansPerSecond||this._maxScansPerSecond;this._onPlay=this._onPlay.bind(this);this._onLoadedMetaData=this._onLoadedMetaData.bind(this);this._onVisibilityChange=this._onVisibilityChange.bind(this);
|
|
5
|
+
this._updateOverlay=this._updateOverlay.bind(this);a.disablePictureInPicture=!0;a.playsInline=!0;a.muted=!0;let h=!1;a.hidden&&(a.hidden=!1,h=!0);document.body.contains(a)||(document.body.appendChild(a),h=!0);c=a.parentElement;if(b.highlightScanRegion||b.highlightCodeOutline){d=!!b.overlay;this.$overlay=b.overlay||document.createElement("div");f=this.$overlay.style;f.position="absolute";f.display="none";f.pointerEvents="none";this.$overlay.classList.add("scan-region-highlight");if(!d&&b.highlightScanRegion){this.$overlay.innerHTML=
|
|
6
|
+
'<svg class="scan-region-highlight-svg" viewBox="0 0 238 238" preserveAspectRatio="none" style="position:absolute;width:100%;height:100%;left:0;top:0;fill:none;stroke:#e9b213;stroke-width:4;stroke-linecap:round;stroke-linejoin:round"><path d="M31 2H10a8 8 0 0 0-8 8v21M207 2h21a8 8 0 0 1 8 8v21m0 176v21a8 8 0 0 1-8 8h-21m-176 0H10a8 8 0 0 1-8-8v-21"/></svg>';try{this.$overlay.firstElementChild.animate({transform:["scale(.98)","scale(1.01)"]},{duration:400,iterations:Infinity,direction:"alternate",
|
|
7
|
+
easing:"ease-in-out"})}catch(m){}c.insertBefore(this.$overlay,this.$video.nextSibling)}b.highlightCodeOutline&&(this.$overlay.insertAdjacentHTML("beforeend",'<svg class="code-outline-highlight" preserveAspectRatio="none" style="display:none;width:100%;height:100%;fill:none;stroke:#e9b213;stroke-width:5;stroke-dasharray:25;stroke-linecap:round;stroke-linejoin:round"><polygon/></svg>'),this.$codeOutlineHighlight=this.$overlay.lastElementChild)}this._scanRegion=this._calculateScanRegion(a);requestAnimationFrame(()=>
|
|
8
|
+
{let m=window.getComputedStyle(a);"none"===m.display&&(a.style.setProperty("display","block","important"),h=!0);"visible"!==m.visibility&&(a.style.setProperty("visibility","visible","important"),h=!0);h&&(console.warn("QrScanner has overwritten the video hiding style to avoid Safari stopping the playback."),a.style.opacity="0",a.style.width="0",a.style.height="0",this.$overlay&&this.$overlay.parentElement&&this.$overlay.parentElement.removeChild(this.$overlay),delete this.$overlay,delete this.$codeOutlineHighlight);
|
|
9
|
+
this.$overlay&&this._updateOverlay()});a.addEventListener("play",this._onPlay);a.addEventListener("loadedmetadata",this._onLoadedMetaData);document.addEventListener("visibilitychange",this._onVisibilityChange);window.addEventListener("resize",this._updateOverlay);this._qrEnginePromise=e.createQrEngine()}async hasFlash(){let a;try{if(this.$video.srcObject){if(!(this.$video.srcObject instanceof MediaStream))return!1;a=this.$video.srcObject}else a=(await this._getCameraStream()).stream;return"torch"in
|
|
10
|
+
a.getVideoTracks()[0].getSettings()}catch(b){return!1}finally{a&&a!==this.$video.srcObject&&(console.warn("Call hasFlash after successfully starting the scanner to avoid creating a temporary video stream"),e._stopVideoStream(a))}}isFlashOn(){return this._flashOn}async toggleFlash(){this._flashOn?await this.turnFlashOff():await this.turnFlashOn()}async turnFlashOn(){if(!this._flashOn&&!this._destroyed&&(this._flashOn=!0,this._active&&!this._paused))try{if(!await this.hasFlash())throw"No flash available";
|
|
11
|
+
await this.$video.srcObject.getVideoTracks()[0].applyConstraints({advanced:[{torch:!0}]})}catch(a){throw this._flashOn=!1,a;}}async turnFlashOff(){this._flashOn&&(this._flashOn=!1,await this._restartVideoStream())}destroy(){this.$video.removeEventListener("loadedmetadata",this._onLoadedMetaData);this.$video.removeEventListener("play",this._onPlay);document.removeEventListener("visibilitychange",this._onVisibilityChange);window.removeEventListener("resize",this._updateOverlay);this._destroyed=!0;this._flashOn=
|
|
12
|
+
!1;this.stop();e._postWorkerMessage(this._qrEnginePromise,"close")}async start(){if(this._destroyed)throw Error("The QR scanner can not be started as it had been destroyed.");if(!this._active||this._paused)if("https:"!==window.location.protocol&&console.warn("The camera stream is only accessible if the page is transferred via https."),this._active=!0,!document.hidden)if(this._paused=!1,this.$video.srcObject)await this.$video.play();else try{let {stream:a,facingMode:b}=await this._getCameraStream();
|
|
13
|
+
!this._active||this._paused?e._stopVideoStream(a):(this._setVideoMirror(b),this.$video.srcObject=a,await this.$video.play(),this._flashOn&&(this._flashOn=!1,this.turnFlashOn().catch(()=>{})))}catch(a){if(!this._paused)throw this._active=!1,a;}}stop(){this.pause();this._active=!1}async pause(a=!1){this._paused=!0;if(!this._active)return!0;this.$video.pause();this.$overlay&&(this.$overlay.style.display="none");let b=()=>{this.$video.srcObject instanceof MediaStream&&(e._stopVideoStream(this.$video.srcObject),
|
|
14
|
+
this.$video.srcObject=null)};if(a)return b(),!0;await new Promise(c=>setTimeout(c,300));if(!this._paused)return!1;b();return!0}async setCamera(a){a!==this._preferredCamera&&(this._preferredCamera=a,await this._restartVideoStream())}static async scanImage(a,b,c,d,f=!1,h=!1){let m,n=!1;b&&("scanRegion"in b||"qrEngine"in b||"canvas"in b||"disallowCanvasResizing"in b||"alsoTryWithoutScanRegion"in b||"returnDetailedScanResult"in b)?(m=b.scanRegion,c=b.qrEngine,d=b.canvas,f=b.disallowCanvasResizing||!1,
|
|
15
|
+
h=b.alsoTryWithoutScanRegion||!1,n=!0):b||c||d||f||h?console.warn("You're using a deprecated api for scanImage which will be removed in the future."):console.warn("Note that the return type of scanImage will change in the future. To already switch to the new api today, you can pass returnDetailedScanResult: true.");b=!!c;try{let p,l;[c,p]=await Promise.all([c||e.createQrEngine(),e._loadImage(a)]);[d,l]=e._drawToCanvas(p,m,d,f);let q;if(c instanceof Worker){let g=c;b||e._postWorkerMessageSync(g,"inversionMode",
|
|
16
|
+
"both");q=await new Promise((k,v)=>{let w,u,t,y=-1;u=r=>{r.data.id===y&&(g.removeEventListener("message",u),g.removeEventListener("error",t),clearTimeout(w),null!==r.data.data?k({data:r.data.data,cornerPoints:e._convertPoints(r.data.cornerPoints,m),bytes:r.data.bytes}):v(e.NO_QR_CODE_FOUND))};t=r=>{g.removeEventListener("message",u);g.removeEventListener("error",t);clearTimeout(w);v("Scanner error: "+(r?r.message||r:"Unknown Error"))};g.addEventListener("message",u);g.addEventListener("error",t);
|
|
17
|
+
w=setTimeout(()=>t("timeout"),1E4);let x=l.getImageData(0,0,d.width,d.height);y=e._postWorkerMessageSync(g,"decode",x,[x.data.buffer])})}else q=await Promise.race([new Promise((g,k)=>window.setTimeout(()=>k("Scanner error: timeout"),1E4)),(async()=>{try{var [g]=await c.detect(d);if(!g)throw e.NO_QR_CODE_FOUND;return{data:g.rawValue,cornerPoints:e._convertPoints(g.cornerPoints,m),bytes:g.rawValue.split("").map(k=>k.charCodeAt(0))}}catch(k){g=k.message||k;if(/not implemented|service unavailable/.test(g))return e._disableBarcodeDetector=
|
|
18
|
+
!0,e.scanImage(a,{scanRegion:m,canvas:d,disallowCanvasResizing:f,alsoTryWithoutScanRegion:h});throw`Scanner error: ${g}`;}})()]);return n?q:q.data}catch(p){if(!m||!h)throw p;let l=await e.scanImage(a,{qrEngine:c,canvas:d,disallowCanvasResizing:f});return n?l:l.data}finally{b||e._postWorkerMessage(c,"close")}}setGrayscaleWeights(a,b,c,d=!0){e._postWorkerMessage(this._qrEnginePromise,"grayscaleWeights",{red:a,green:b,blue:c,useIntegerApproximation:d})}setInversionMode(a){e._postWorkerMessage(this._qrEnginePromise,
|
|
19
|
+
"inversionMode",a)}static async createQrEngine(a){a&&console.warn("Specifying a worker path is not required and not supported anymore.");a=()=>import("./qr-scanner-worker.min.js").then(c=>c.createWorker());if(!(!e._disableBarcodeDetector&&"BarcodeDetector"in window&&BarcodeDetector.getSupportedFormats&&(await BarcodeDetector.getSupportedFormats()).includes("qr_code")))return a();let b=navigator.userAgentData;return b&&b.brands.some(({brand:c})=>/Chromium/i.test(c))&&/mac ?OS/i.test(b.platform)&&
|
|
20
|
+
await b.getHighEntropyValues(["architecture","platformVersion"]).then(({architecture:c,platformVersion:d})=>/arm/i.test(c||"arm")&&13<=parseInt(d||"13")).catch(()=>!0)?a():new BarcodeDetector({formats:["qr_code"]})}_onPlay(){this._scanRegion=this._calculateScanRegion(this.$video);this._updateOverlay();this.$overlay&&(this.$overlay.style.display="");this._scanFrame()}_onLoadedMetaData(){this._scanRegion=this._calculateScanRegion(this.$video);this._updateOverlay()}_onVisibilityChange(){document.hidden?
|
|
21
|
+
this.pause():this._active&&this.start()}_calculateScanRegion(a){let b=Math.round(2/3*Math.min(a.videoWidth,a.videoHeight));return{x:Math.round((a.videoWidth-b)/2),y:Math.round((a.videoHeight-b)/2),width:b,height:b,downScaledWidth:this._legacyCanvasSize,downScaledHeight:this._legacyCanvasSize}}_updateOverlay(){requestAnimationFrame(()=>{if(this.$overlay){var a=this.$video,b=a.videoWidth,c=a.videoHeight,d=a.offsetWidth,f=a.offsetHeight,h=a.offsetLeft,m=a.offsetTop,n=window.getComputedStyle(a),p=n.objectFit,
|
|
22
|
+
l=b/c,q=d/f;switch(p){case "none":var g=b;var k=c;break;case "fill":g=d;k=f;break;default:("cover"===p?l>q:l<q)?(k=f,g=k*l):(g=d,k=g/l),"scale-down"===p&&(g=Math.min(g,b),k=Math.min(k,c))}var [v,w]=n.objectPosition.split(" ").map((t,y)=>{const x=parseFloat(t);return t.endsWith("%")?(y?f-k:d-g)*x/100:x});n=this._scanRegion.width||b;q=this._scanRegion.height||c;p=this._scanRegion.x||0;var u=this._scanRegion.y||0;l=this.$overlay.style;l.width=`${n/b*g}px`;l.height=`${q/c*k}px`;l.top=`${m+w+u/c*k}px`;
|
|
23
|
+
c=/scaleX\(-1\)/.test(a.style.transform);l.left=`${h+(c?d-v-g:v)+(c?b-p-n:p)/b*g}px`;l.transform=a.style.transform}})}static _convertPoints(a,b){if(!b)return a;let c=b.x||0,d=b.y||0,f=b.width&&b.downScaledWidth?b.width/b.downScaledWidth:1;b=b.height&&b.downScaledHeight?b.height/b.downScaledHeight:1;for(let h of a)h.x=h.x*f+c,h.y=h.y*b+d;return a}_scanFrame(){!this._active||this.$video.paused||this.$video.ended||("requestVideoFrameCallback"in this.$video?this.$video.requestVideoFrameCallback.bind(this.$video):
|
|
24
|
+
requestAnimationFrame)(async()=>{if(!(1>=this.$video.readyState)){var a=Date.now()-this._lastScanTimestamp,b=1E3/this._maxScansPerSecond;a<b&&await new Promise(d=>setTimeout(d,b-a));this._lastScanTimestamp=Date.now();try{var c=await e.scanImage(this.$video,{scanRegion:this._scanRegion,qrEngine:this._qrEnginePromise,canvas:this.$canvas})}catch(d){if(!this._active)return;this._onDecodeError(d)}!e._disableBarcodeDetector||await this._qrEnginePromise instanceof Worker||(this._qrEnginePromise=e.createQrEngine());
|
|
25
|
+
c?(this._onDecode?this._onDecode(c):this._legacyOnDecode&&this._legacyOnDecode(c.data),this.$codeOutlineHighlight&&(clearTimeout(this._codeOutlineHighlightRemovalTimeout),this._codeOutlineHighlightRemovalTimeout=void 0,this.$codeOutlineHighlight.setAttribute("viewBox",`${this._scanRegion.x||0} `+`${this._scanRegion.y||0} `+`${this._scanRegion.width||this.$video.videoWidth} `+`${this._scanRegion.height||this.$video.videoHeight}`),this.$codeOutlineHighlight.firstElementChild.setAttribute("points",c.cornerPoints.map(({x:d,
|
|
26
|
+
y:f})=>`${d},${f}`).join(" ")),this.$codeOutlineHighlight.style.display="")):this.$codeOutlineHighlight&&!this._codeOutlineHighlightRemovalTimeout&&(this._codeOutlineHighlightRemovalTimeout=setTimeout(()=>this.$codeOutlineHighlight.style.display="none",100))}this._scanFrame()})}_onDecodeError(a){a!==e.NO_QR_CODE_FOUND&&console.log(a)}async _getCameraStream(){if(!navigator.mediaDevices)throw"Camera not found.";let a=/^(environment|user)$/.test(this._preferredCamera)?"facingMode":"deviceId",b=[{width:{min:1024}},
|
|
27
|
+
{width:{min:768}},{}],c=b.map(d=>Object.assign({},d,{[a]:{exact:this._preferredCamera}}));for(let d of[...c,...b])try{let f=await navigator.mediaDevices.getUserMedia({video:d,audio:!1}),h=this._getFacingMode(f)||(d.facingMode?this._preferredCamera:"environment"===this._preferredCamera?"user":"environment");return{stream:f,facingMode:h}}catch(f){}throw"Camera not found.";}async _restartVideoStream(){let a=this._paused;await this.pause(!0)&&!a&&this._active&&await this.start()}static _stopVideoStream(a){for(let b of a.getTracks())b.stop(),
|
|
28
|
+
a.removeTrack(b)}_setVideoMirror(a){this.$video.style.transform="scaleX("+("user"===a?-1:1)+")"}_getFacingMode(a){return(a=a.getVideoTracks()[0])?/rear|back|environment/i.test(a.label)?"environment":/front|user|face/i.test(a.label)?"user":null:null}static _drawToCanvas(a,b,c,d=!1){c=c||document.createElement("canvas");let f=b&&b.x?b.x:0,h=b&&b.y?b.y:0,m=b&&b.width?b.width:a.videoWidth||a.width,n=b&&b.height?b.height:a.videoHeight||a.height;d||(d=b&&b.downScaledWidth?b.downScaledWidth:m,b=b&&b.downScaledHeight?
|
|
29
|
+
b.downScaledHeight:n,c.width!==d&&(c.width=d),c.height!==b&&(c.height=b));b=c.getContext("2d",{alpha:!1});b.imageSmoothingEnabled=!1;b.drawImage(a,f,h,m,n,0,0,c.width,c.height);return[c,b]}static async _loadImage(a){if(a instanceof Image)return await e._awaitImageLoad(a),a;if(a instanceof HTMLVideoElement||a instanceof HTMLCanvasElement||a instanceof SVGImageElement||"OffscreenCanvas"in window&&a instanceof OffscreenCanvas||"ImageBitmap"in window&&a instanceof ImageBitmap)return a;if(a instanceof
|
|
30
|
+
File||a instanceof Blob||a instanceof URL||"string"===typeof a){let b=new Image;b.src=a instanceof File||a instanceof Blob?URL.createObjectURL(a):a.toString();try{return await e._awaitImageLoad(b),b}finally{(a instanceof File||a instanceof Blob)&&URL.revokeObjectURL(b.src)}}else throw"Unsupported image type.";}static async _awaitImageLoad(a){a.complete&&0!==a.naturalWidth||await new Promise((b,c)=>{let d=f=>{a.removeEventListener("load",d);a.removeEventListener("error",d);f instanceof ErrorEvent?
|
|
31
|
+
c("Image load error"):b()};a.addEventListener("load",d);a.addEventListener("error",d)})}static async _postWorkerMessage(a,b,c,d){return e._postWorkerMessageSync(await a,b,c,d)}static _postWorkerMessageSync(a,b,c,d){if(!(a instanceof Worker))return-1;let f=e._workerMessageId++;a.postMessage({id:f,type:b,data:c},d);return f}}e.DEFAULT_CANVAS_SIZE=400;e.NO_QR_CODE_FOUND="No QR code found";e._disableBarcodeDetector=!1;e._workerMessageId=0;export default e
|
|
32
|
+
//# sourceMappingURL=qr-scanner.min.js.map
|