/*!
 * Built by ShiftSoftware
 * Copyright (c)
 */
import { h, Host } from "@stencil/core";
import cn from "../../global/lib/cn";
import validateVin from "../../global/lib/validate-vin";
const CAPTURE_INTERVAL = 2000;
const ACTIVE_CAMERA_ID_KEY = 'activeCameraId';
export class VinExtractor {
    constructor() {
        this.title = '';
        this.captureInterval = CAPTURE_INTERVAL;
        this.verbose = false;
        this.useOcr = false;
        this.readSticker = false;
        // to explicitly opening camera instead of letting choose from files or new image from camera
        this.captureEnvironment = false;
        this.manualCapture = false;
        this.skipValidation = false;
        this.manualCaptureLabel = '';
        this.manualCaptureHint = '';
        this.isOpen = false;
        this.isAnimating = false;
        this.isCameraReady = false;
        this.switchRotateDegree = 0;
        this.containerAnimation = '';
        this.videoInputs = [];
        this.manualCaptureLoading = false;
        this.activeCameraId = localStorage.getItem(ACTIVE_CAMERA_ID_KEY) || '';
        this.registerFileUploader = () => {
            if (this.readSticker && !this.codeReader) {
                setTimeout(() => {
                    this.componentDidLoad();
                }, 100);
                return;
            }
            this.fileButton = document.querySelector('#' + this.uploaderButtonId);
            this.fileInput = this.el.shadowRoot.querySelector('.vin-extractor-input');
            this.fileButton.removeEventListener('click', this.onFileUploaderClick);
            this.fileInput.removeEventListener('change', this.onFileUploaderChange);
            this.fileButton.addEventListener('click', this.onFileUploaderClick);
            this.fileInput.addEventListener('change', this.onFileUploaderChange);
        };
        this.onFileUploaderClick = () => {
            this.fileInput.click();
        };
        this.onFileUploaderChange = () => {
            var _a;
            const file = (_a = this.fileInput.files) === null || _a === void 0 ? void 0 : _a[0];
            if (!file)
                return;
            const img = new Image();
            const reader = new FileReader();
            reader.onload = () => {
                img.src = reader.result;
            };
            img.onload = async () => {
                this.handleOnProcessing(true);
                const imageDataUrl = await this.processCanvasFromSource(img, this.videoCanvas);
                await this.handleImage(imageDataUrl);
                this.handleOnProcessing(false);
            };
            reader.readAsDataURL(file);
        };
        this.triggerCallback = (callback, ...args) => {
            var _a;
            if (callback) {
                if (typeof callback === 'function')
                    callback(...args);
                else if (this.blazorRef && typeof callback === 'string' && !!callback)
                    (_a = this.blazorRef) === null || _a === void 0 ? void 0 : _a.invokeMethodAsync(callback, ...args);
            }
        };
        this.handleError = (error) => {
            this.triggerCallback(this.onError, error);
        };
        this.handleExtract = (vin) => {
            this.triggerCallback(this.onExtract, vin);
        };
        this.handleOnProcessing = (isProcessing) => {
            this.triggerCallback(this.onProcessing, isProcessing);
        };
        this.captureFrame = async (manualCapture = false) => {
            if (!this.isOpen)
                return;
            if (!this.videoPlayer || !this.videoCanvas)
                return this.componentDidLoad();
            this.handleOnProcessing(true);
            if (manualCapture) {
                this.videoPlayer.pause();
                this.manualCaptureLoading = true;
            }
            const imageDataUrl = await this.processCanvasFromSource(this.videoPlayer, this.videoCanvas);
            this.handleImage(imageDataUrl);
            if (!this.manualCapture) {
                this.frameCaptureTimeoutRef = setTimeout(this.captureFrame, this.captureInterval);
                this.handleOnProcessing(false);
            }
            if (manualCapture) {
                setTimeout(() => {
                    this.videoPlayer.play();
                    this.manualCaptureLoading = false;
                    this.handleOnProcessing(false);
                    // Re-engage autofocus last: some devices drop to idle focus after the
                    // pause. Fire-and-forget so it can't affect the resume flow.
                    this.applyAutofocus();
                }, 1000);
            }
        };
        this.handleImage = async (imageDataUrl) => {
            if (this.readSticker)
                await this.stickerHandler(imageDataUrl);
            if (this.useOcr && this.ocrEndpoint)
                await this.ocrHandler(imageDataUrl);
        };
        this.ocrHandler = async (imageDataUrl) => {
            try {
                const response = await fetch(this.ocrEndpoint, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    signal: this.abortController.signal,
                    body: JSON.stringify({ image: imageDataUrl.split(',')[1] }),
                });
                if (!response.ok)
                    throw new Error('Failed to fetch OCR result');
                if (this.verbose)
                    console.log(response);
                const data = await response.text();
                if (this.skipValidation || (!!data.trim() && validateVin(data)))
                    this.handleExtract(data);
            }
            catch (error) {
                this.handleError(error);
            }
        };
        this.stickerHandler = async (imageDataUrl) => {
            try {
                if (this.verbose)
                    console.log('try detecting sticker');
                const result = await this.codeReader.decodeFromImage(undefined, imageDataUrl);
                const text = result.getText();
                if (this.verbose)
                    console.log(text);
                if (!!text.trim()) {
                    if (this.skipValidation)
                        this.handleExtract(text.trim());
                    else {
                        const vin = text.replace(/[qo]/g, '0').replace(/i/g, '1').replace(/ /g, '');
                        if (vin.length === 17 && validateVin(vin))
                            this.handleExtract(vin);
                    }
                }
            }
            catch (error) {
                this.handleError(error);
            }
        };
        this.openScanner = async () => {
            var _a;
            try {
                (_a = this.abortController) === null || _a === void 0 ? void 0 : _a.abort();
                this.abortController = new AbortController();
                const permissionStatus = await navigator.permissions.query({
                    // @ts-ignore
                    name: 'camera',
                });
                if (permissionStatus.state === 'prompt') {
                    try {
                        const probe = await navigator.mediaDevices.getUserMedia({
                            video: true,
                        });
                        probe.getTracks().forEach(track => track.stop());
                    }
                    catch (error) {
                        throw new Error('no camera access');
                    }
                }
                if (permissionStatus.state === 'denied') {
                    throw new Error('no camera access');
                }
                const devices = await navigator.mediaDevices.enumerateDevices();
                const videoInputs = devices.filter(device => {
                    if (device.kind !== 'videoinput')
                        return false;
                    // TODO: this code only works for IOS however android has no standards
                    // const label = device.label.toLowerCase();
                    // const hasDirection = label.includes('front') || label.includes('back');
                    // const isValid = label.includes('front camera') || label.includes('back camera');
                    // return hasDirection ? isValid : true;
                    return true;
                });
                if (videoInputs.length === 0)
                    throw new Error('No Camera Found');
                this.videoInputs = videoInputs;
                if (!videoInputs.some(input => input.deviceId === this.activeCameraId)) {
                    const selectedCamera = videoInputs.find(({ label }) => label.toLowerCase().includes('back') || label.toLowerCase().includes('environment')) || videoInputs[0];
                    this.activeCameraId = selectedCamera.deviceId;
                    localStorage.setItem(ACTIVE_CAMERA_ID_KEY, this.activeCameraId);
                }
                await this.startCamera();
                if (!this.manualCapture)
                    this.frameCaptureTimeoutRef = setTimeout(this.captureFrame, this.captureInterval + 300);
                if (document)
                    document.body.style.overflow = 'hidden';
                this.isCameraReady = true;
                this.containerAnimation = 'show-container';
            }
            catch (error) {
                this.handleError(error);
            }
        };
        this.startCamera = async () => {
            try {
                const constraints = {
                    video: {
                        deviceId: this.activeCameraId,
                        // Best-effort continuous autofocus at acquisition time. `advanced`
                        // entries are advisory — browsers/devices that don't support
                        // focusMode (e.g. iOS, which autofocuses natively) just ignore it,
                        // so this never throws or over-constrains the request.
                        advanced: [{ focusMode: 'continuous' }],
                    },
                };
                this.streamRef = await navigator.mediaDevices.getUserMedia(constraints);
                if (this.videoPlayer) {
                    this.videoPlayer.srcObject = this.streamRef;
                    try {
                        await this.videoPlayer.play();
                    }
                    catch (_) {
                        // play() can reject when interrupted (e.g. the modal closes again
                        // before the stream is ready) — safe to swallow.
                    }
                }
                this.manualCaptureLoading = false;
                // Fire-and-forget: autofocus is a best-effort enhancement and must never
                // block or alter the existing open/capture flow if it stalls or fails.
                this.applyAutofocus();
            }
            catch (error) {
                if (this.verbose)
                    console.error(error);
                throw new Error('Error accessing camera: ');
            }
        };
        // Low-end Android cameras often open with a fixed/idle focus mode, so the live
        // preview never sharpens — whereas iOS autofocuses natively, which is why it
        // "just works" on iPhone. When the track advertises focus control, explicitly
        // request continuous autofocus (falling back to single-shot). Everything here
        // is feature-detected and best-effort; unsupported devices keep their default.
        this.applyAutofocus = async () => {
            var _a, _b, _c, _d;
            try {
                const track = (_b = (_a = this.streamRef) === null || _a === void 0 ? void 0 : _a.getVideoTracks) === null || _b === void 0 ? void 0 : _b.call(_a)[0];
                if (!track || typeof track.getCapabilities !== 'function')
                    return;
                const capabilities = track.getCapabilities();
                const focusModes = (_c = capabilities === null || capabilities === void 0 ? void 0 : capabilities.focusMode) !== null && _c !== void 0 ? _c : [];
                if (this.verbose) {
                    console.log('vin-extractor camera capabilities', capabilities);
                    console.log('vin-extractor camera settings', (_d = track.getSettings) === null || _d === void 0 ? void 0 : _d.call(track));
                }
                if (focusModes.includes('continuous'))
                    await track.applyConstraints({ advanced: [{ focusMode: 'continuous' }] });
                else if (focusModes.includes('single-shot'))
                    await track.applyConstraints({ advanced: [{ focusMode: 'single-shot' }] });
            }
            catch (error) {
                if (this.verbose)
                    console.warn('vin-extractor autofocus not applied', error);
            }
        };
        this.closeScanner = () => {
            var _a;
            this.isCameraReady = false;
            this.manualCaptureLoading = false;
            (_a = this.abortController) === null || _a === void 0 ? void 0 : _a.abort();
            clearTimeout(this.frameCaptureTimeoutRef);
            if (this.codeReader)
                this.codeReader.reset();
            if (this.videoPlayer) {
                try {
                    this.videoPlayer.pause();
                }
                catch (_) {
                    /* ignore */
                }
                this.videoPlayer.srcObject = null;
            }
            if (document)
                document.body.style.overflow = 'auto';
            this.containerAnimation = 'hide-container';
        };
        this.stopCamera = () => {
            if (this.streamRef) {
                this.streamRef.getTracks().forEach(track => track.stop());
                this.streamRef = null;
            }
        };
        this.switchCamera = () => {
            if (this.videoInputs.length > 1) {
                const currentIndex = this.videoInputs.findIndex(device => device.deviceId === this.activeCameraId);
                const newCameraIndex = (currentIndex + 1) % this.videoInputs.length;
                this.activeCameraId = this.videoInputs[newCameraIndex].deviceId;
                localStorage.setItem(ACTIVE_CAMERA_ID_KEY, this.activeCameraId);
                this.stopCamera();
                this.startCamera();
                this.switchRotateDegree += 90;
            }
        };
    }
    async componentDidLoad() {
        this.videoPlayer = this.el.shadowRoot.querySelector('.video-player');
        this.videoCanvas = this.el.shadowRoot.querySelector('.video-canvas');
        this.abortController = new AbortController();
        if (!this.readSticker && this.uploaderButtonId)
            this.registerFileUploader();
        if (this.readSticker) {
            const ZXingSrc = 'https://unpkg.com/@zxing/library@0.21.3/umd/index.min.js';
            const alreadyLoaded = Array.from(document.scripts).some(script => script.src === ZXingSrc);
            if (alreadyLoaded && this.uploaderButtonId)
                this.registerFileUploader();
            if (!alreadyLoaded) {
                const script = document.createElement('script');
                script.src = ZXingSrc;
                script.defer = true;
                document.head.appendChild(script);
                script.onload = () => {
                    // @ts-ignore
                    if (ZXing)
                        this.codeReader = new ZXing.BrowserMultiFormatReader();
                };
            }
            else if (!this.codeReader) {
                try {
                    // @ts-ignore
                    if (ZXing)
                        this.codeReader = new ZXing.BrowserMultiFormatReader();
                }
                catch (error) {
                    setTimeout(() => {
                        this.componentDidLoad();
                    }, 100);
                }
            }
        }
    }
    async setBlazorRef(newBlazorRef) {
        this.blazorRef = newBlazorRef;
    }
    async processCanvasFromSource(source, canvas, maxSize = 400) {
        try {
            const isImage = source instanceof HTMLImageElement;
            const naturalWidth = isImage ? source.width : source.videoWidth;
            const naturalHeight = isImage ? source.height : source.videoHeight;
            let targetWidth = naturalWidth;
            let targetHeight = naturalHeight;
            if (Math.max(naturalWidth, naturalHeight) > maxSize) {
                const scale = maxSize / Math.max(naturalWidth, naturalHeight);
                targetWidth = Math.round(naturalWidth * scale);
                targetHeight = Math.round(naturalHeight * scale);
            }
            canvas.width = targetWidth;
            canvas.height = targetHeight;
            const ctx = canvas.getContext('2d');
            ctx.drawImage(source, 0, 0, targetWidth, targetHeight);
            return canvas.toDataURL('image/png');
        }
        catch (error) {
            this.handleError(error);
            return '';
        }
    }
    async open() {
        this.isOpen = true;
    }
    async close() {
        this.isOpen = false;
    }
    isOpenHandler(newValue) {
        if (newValue)
            this.openScanner();
        else
            this.closeScanner();
        this.triggerCallback(this.onOpenChange, newValue);
    }
    QRChanged(newValue) {
        if (newValue)
            this.componentDidLoad();
    }
    animationHandler(newValue) {
        if (!newValue && !this.isOpen)
            this.stopCamera();
    }
    render() {
        const ariaExpanded = this.isOpen && this.isCameraReady && (this.useOcr || this.readSticker);
        return (h(Host, { key: 'd395f9ca0db8dc72e0bcf9d1901103210423b7b8', translate: "no" }, h("slot", { key: '802045dff22396278837d24db63335de8f277fdf' }), h("input", Object.assign({ key: 'cd3afe286669d18955ce5f49cdef684f1d528b00', class: "vin-extractor-input", type: "file", accept: "image/*", "aria-label": "Upload VIN image" }, (this.captureEnvironment ? { capture: 'environment' } : {}), { hidden: true })), h("canvas", { key: 'e1a42098015aca96ef4f3a146cb7d2eae79adaa3', class: "video-canvas hidden", "aria-hidden": "true" }), !this.uploaderButtonId && (h("div", { key: 'b1917461ea3155c5478195ed24e5f7be296fd39c', onClick: () => (this.isOpen = false), role: "dialog", "aria-modal": ariaExpanded.toString(), "aria-label": this.title || 'VIN Scanner', "aria-hidden": (!ariaExpanded).toString(), class: "vin-extractor-background md:transition-all md:duration-300 fixed flex items-center justify-center w-[100dvw] h-[100dvh] top-0 left-0 z-[9999]" }, h("div", { key: 'b2f9d0b9100b3f180f795ca68dd7a471b5d74be1', role: "document", onClick: e => e.stopPropagation(), "aria-expanded": ariaExpanded.toString(), onAnimationEnd: () => (this.isAnimating = false), onAnimationStart: () => (this.isAnimating = true), class: cn('vin-extractor-container md:w-[600px] md:rounded-lg md:overflow-hidden opacity-0 md:h-auto w-full h-full relative transition-all duration-500', this.containerAnimation) }, h("div", { key: '8ad0cfe44bce013da5144ef48f639e17e2601d76', class: "vin-extractor-heading items-center md:py-[8px] w-full md:!opacity-100 md:!translate-x-0 p-[16px] md:bg-white bg-black/30 shadow-md z-10 md:relative absolute top-0 left-0 flex justify-between" }, this.videoInputs.length > 1 ? (h("button", { type: "button", "aria-label": "Switch camera", onClick: this.switchCamera, class: "size-[32px] md:border-none md:bg-white md:hover:bg-slate-100 bg-slate-100 rounded-lg p-1 hover:text-slate-700 border transition-colors duration-300 hover:bg-slate-300 border-slate-600 text-slate-600 hover:border-slate-700" }, h("svg", { width: "24", height: "24", fill: "none", "stroke-width": "2", "aria-hidden": "true", viewBox: "0 0 24 24", stroke: "currentColor", "stroke-linecap": "round", "stroke-linejoin": "round", xmlns: "http://www.w3.org/2000/svg", class: "size-full transition-all duration-300", style: { rotate: `${this.switchRotateDegree}deg` } }, h("path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" }), h("path", { d: "M21 3v5h-5" }), h("path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" }), h("path", { d: "M8 16H3v5" })))) : (h("div", { class: "size-8", "aria-hidden": "true" })), h("h1", { key: '691dc2cc56ef6139c23b393951344b102b556bd5', class: "text-center text-[18px] md:text-[24px] md:text-black text-slate-100 form-input-label", part: "form-input-label" }, this.title), h("button", { key: '9c46e46378c42badd226140668b00c130c982e1c', type: "button", "aria-label": "Close scanner", onClick: () => (this.isOpen = false), class: "size-[32px] md:border-none md:bg-white md:hover:bg-slate-100 bg-slate-100 rounded-lg p-1 hover:text-slate-700 border transition-colors duration-300 hover:bg-slate-300 border-slate-600 text-slate-600 hover:border-slate-700" }, h("svg", { key: 'e18a1f7056f2070367d7e555636fcf5d74ed9aea', fill: "none", "stroke-width": "2", class: "size-full", "aria-hidden": "true", viewBox: "0 0 24 24", stroke: "currentColor", "stroke-linecap": "round", "stroke-linejoin": "round", xmlns: "http://www.w3.org/2000/svg" }, h("path", { key: '69b54dea4925dfc16c061a6c28ad41e846aaaa98', d: "M18 6 6 18" }), h("path", { key: 'd9b68a20b53c8d6ee117eae01410962b1595ea49', d: "m6 6 12 12" })))), this.manualCapture && !!this.manualCaptureHint && !this.manualCaptureLoading && (h("p", { key: '2f26a42165946a4b76642c1738e3817cf2cf2650', "aria-hidden": "true", class: "vin-extractor-manual-capture-hint absolute left-1/2 -translate-x-1/2 bottom-[88px] z-10 m-0 px-3 py-1 rounded-full bg-black/55 text-white text-center text-[13px] leading-[1.3] whitespace-nowrap pointer-events-none" }, this.manualCaptureHint)), this.manualCapture && (h("button", { key: '745405b0ab64f96146efe6e211dfcadd50559d00', type: "button", part: "vin-extractor-capture-button", disabled: this.manualCaptureLoading, onClick: this.captureFrame.bind(this, true), "aria-label": this.manualCaptureLoading ? 'Capturing...' : this.manualCaptureLabel || 'Capture VIN', class: cn('vin-extractor-capture-button absolute disabled:bg-white/75 outline-none cursor-pointer left-1/2 -translate-x-1/2 flex justify-center items-center h-[60px] py-[10px] rounded-full shadow-lg border border-slate-500 text-slate-500 z-10 bg-white bottom-4', this.manualCaptureLabel ? 'px-6 min-w-[140px] gap-2 text-[15px] font-medium whitespace-nowrap' : 'w-[100px]') }, this.manualCaptureLoading ? (h("svg", { fill: "none", "stroke-width": "2", "aria-hidden": "true", viewBox: "0 0 24 24", stroke: "currentColor", "stroke-linecap": "round", "stroke-linejoin": "round", xmlns: "http://www.w3.org/2000/svg", class: cn('animate-spin animate-spin-v', this.manualCaptureLabel ? 'size-[22px]' : 'size-full') }, h("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }))) : this.manualCaptureLabel ? (h("span", null, this.manualCaptureLabel)) : (h("svg", { fill: "none", "stroke-width": "2", class: "size-full", "aria-hidden": "true", viewBox: "0 0 24 24", stroke: "currentColor", "stroke-linecap": "round", "stroke-linejoin": "round", xmlns: "http://www.w3.org/2000/svg" }, h("path", { d: "M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z" }), h("circle", { cx: "12", cy: "13", r: "3" }))))), h("video", { key: 'e93d3a1baea41f21799b301509d457e649ac842b', autoPlay: true, id: "video", playsInline: true, "aria-label": "Camera preview", class: "video-player aspect-video bg-black min-w-full min-h-full object-cover object-center" }))))));
    }
    static get is() { return "vin-extractor"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["vin-extractor.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["vin-extractor.css"]
        };
    }
    static get properties() {
        return {
            "title": {
                "type": "string",
                "attribute": "title",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "''"
            },
            "captureInterval": {
                "type": "number",
                "attribute": "capture-interval",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "CAPTURE_INTERVAL"
            },
            "verbose": {
                "type": "boolean",
                "attribute": "verbose",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "false"
            },
            "useOcr": {
                "type": "boolean",
                "attribute": "use-ocr",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "false"
            },
            "readSticker": {
                "type": "boolean",
                "attribute": "read-sticker",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "false"
            },
            "uploaderButtonId": {
                "type": "string",
                "attribute": "uploader-button-id",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "captureEnvironment": {
                "type": "boolean",
                "attribute": "capture-environment",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "false"
            },
            "manualCapture": {
                "type": "boolean",
                "attribute": "manual-capture",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "false"
            },
            "skipValidation": {
                "type": "boolean",
                "attribute": "skip-validation",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "false"
            },
            "manualCaptureLabel": {
                "type": "string",
                "attribute": "manual-capture-label",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "''"
            },
            "manualCaptureHint": {
                "type": "string",
                "attribute": "manual-capture-hint",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "''"
            },
            "ocrEndpoint": {
                "type": "string",
                "attribute": "ocr-endpoint",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "onExtract": {
                "type": "string",
                "attribute": "on-extract",
                "mutable": false,
                "complexType": {
                    "original": "((vin: string) => void) | string",
                    "resolved": "((vin: string) => void) | string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "onError": {
                "type": "string",
                "attribute": "on-error",
                "mutable": false,
                "complexType": {
                    "original": "((newError: Error) => void) | string",
                    "resolved": "((newError: Error) => void) | string",
                    "references": {
                        "Error": {
                            "location": "global",
                            "id": "global::Error"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "onProcessing": {
                "type": "string",
                "attribute": "on-processing",
                "mutable": false,
                "complexType": {
                    "original": "((vin: string) => void) | string",
                    "resolved": "((vin: string) => void) | string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "onOpenChange": {
                "type": "string",
                "attribute": "on-open-change",
                "mutable": false,
                "complexType": {
                    "original": "((newError: boolean) => void) | string",
                    "resolved": "((newError: boolean) => void) | string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false
            }
        };
    }
    static get states() {
        return {
            "streamRef": {},
            "isOpen": {},
            "isAnimating": {},
            "isCameraReady": {},
            "switchRotateDegree": {},
            "containerAnimation": {},
            "blazorRef": {},
            "videoInputs": {},
            "manualCaptureLoading": {},
            "activeCameraId": {}
        };
    }
    static get methods() {
        return {
            "setBlazorRef": {
                "complexType": {
                    "signature": "(newBlazorRef: DotNetObjectReference) => Promise<void>",
                    "parameters": [{
                            "name": "newBlazorRef",
                            "type": "{ invokeMethodAsync: (methodName: string, ...args: any[]) => Promise<any>; }",
                            "docs": ""
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "DotNetObjectReference": {
                            "location": "import",
                            "path": "~features/blazor-ref",
                            "id": "src/features/blazor-ref/index.ts::DotNetObjectReference"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "",
                    "tags": []
                }
            },
            "open": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "",
                    "tags": []
                }
            },
            "close": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "",
                    "tags": []
                }
            }
        };
    }
    static get elementRef() { return "el"; }
    static get watchers() {
        return [{
                "propName": "isOpen",
                "methodName": "isOpenHandler"
            }, {
                "propName": "readSticker",
                "methodName": "QRChanged"
            }, {
                "propName": "isAnimating",
                "methodName": "animationHandler"
            }];
    }
}
