From 7d410d916784234a067dc9b157a88ae8d679f29b Mon Sep 17 00:00:00 2001 From: gjulivan Date: Wed, 3 Sep 2025 00:28:05 +0200 Subject: [PATCH 1/6] feat(barcode): add logic to use barcodedetector API --- .../barcode-scanner-web/CHANGELOG.md | 5 + .../barcode-scanner-web/package.json | 2 +- .../src/components/BarcodeScanner.tsx | 4 +- .../src/helpers/barcode-detector-utils.tsx | 107 +++++++++++++++++ .../src/helpers/barcode-detector.ts | 51 ++++++++ .../src/{components => helpers}/utils.tsx | 21 ++++ .../src/hooks/nativeReader.ts | 77 ++++++++++++ .../src/hooks/useReader.ts | 108 +++-------------- .../barcode-scanner-web/src/hooks/zxReader.ts | 110 ++++++++++++++++++ .../barcode-scanner-web/src/package.xml | 2 +- .../src/ui/BarcodeScanner.scss | 9 ++ 11 files changed, 397 insertions(+), 99 deletions(-) create mode 100644 packages/pluggableWidgets/barcode-scanner-web/src/helpers/barcode-detector-utils.tsx create mode 100644 packages/pluggableWidgets/barcode-scanner-web/src/helpers/barcode-detector.ts rename packages/pluggableWidgets/barcode-scanner-web/src/{components => helpers}/utils.tsx (84%) create mode 100644 packages/pluggableWidgets/barcode-scanner-web/src/hooks/nativeReader.ts create mode 100644 packages/pluggableWidgets/barcode-scanner-web/src/hooks/zxReader.ts diff --git a/packages/pluggableWidgets/barcode-scanner-web/CHANGELOG.md b/packages/pluggableWidgets/barcode-scanner-web/CHANGELOG.md index 5c55e3975e..cb198deae3 100644 --- a/packages/pluggableWidgets/barcode-scanner-web/CHANGELOG.md +++ b/packages/pluggableWidgets/barcode-scanner-web/CHANGELOG.md @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] +### Added + +- We added the logic to switch to use native browser BarcodeDetector API if it is available instead of using zxing library. +- We increase ideal image resolution to improve performance on higher end devices. + ## [2.4.2] - 2024-08-30 ### Fixed diff --git a/packages/pluggableWidgets/barcode-scanner-web/package.json b/packages/pluggableWidgets/barcode-scanner-web/package.json index d8b4e32a3d..4127adaebb 100644 --- a/packages/pluggableWidgets/barcode-scanner-web/package.json +++ b/packages/pluggableWidgets/barcode-scanner-web/package.json @@ -1,7 +1,7 @@ { "name": "@mendix/barcode-scanner-web", "widgetName": "BarcodeScanner", - "version": "2.4.2", + "version": "2.5.0", "description": "Displays a barcode scanner", "copyright": "© Mendix Technology BV 2025. All rights reserved.", "license": "Apache-2.0", diff --git a/packages/pluggableWidgets/barcode-scanner-web/src/components/BarcodeScanner.tsx b/packages/pluggableWidgets/barcode-scanner-web/src/components/BarcodeScanner.tsx index ba9e0da958..1cfd41d4e8 100644 --- a/packages/pluggableWidgets/barcode-scanner-web/src/components/BarcodeScanner.tsx +++ b/packages/pluggableWidgets/barcode-scanner-web/src/components/BarcodeScanner.tsx @@ -69,7 +69,7 @@ export function BarcodeScanner({ }: BarcodeScannerProps): ReactElement | null { const [errorMessage, setError] = useCustomErrorMessage(); const canvasMiddleRef = useRef(null); - const videoRef = useReader({ + const { ref: videoRef, useBrowserAPI } = useReader({ onSuccess: onDetect, onError: setError, useCrop: showMask, @@ -104,7 +104,7 @@ export function BarcodeScanner({ return ( { + const formatMap: Record = { + UPC_A: "upc_a", + UPC_E: "upc_e", + EAN_8: "ean_8", + EAN_13: "ean_13", + CODE_39: "code_39", + CODE_128: "code_128", + ITF: "itf", + QR_CODE: "qr_code", + DATA_MATRIX: "data_matrix", + AZTEC: "aztec", + PDF_417: "pdf417" + }; + return formatMap[format] || format.toLowerCase(); +}; + +// Check if BarcodeDetector API is available +export const isBarcodeDetectorSupported = (): boolean => { + return typeof globalThis !== "undefined" && "BarcodeDetector" in globalThis; +}; + +// Get supported formats for BarcodeDetector +export const getBarcodeDetectorSupportedFormats = async (): Promise => { + if (!isBarcodeDetectorSupported()) { + return []; + } + try { + const detector = new window.BarcodeDetector!(); + return await detector.getSupportedFormats(); + } catch (error) { + console.warn("Failed to get BarcodeDetector supported formats:", error); + return []; + } +}; + +// Create BarcodeDetector options from widget configuration +export const createBarcodeDetectorOptions = ( + useAllFormats: boolean, + barcodeFormats?: BarcodeFormatsType[] +): BarcodeDetectorOptions => { + const options: BarcodeDetectorOptions = {}; + + if (!useAllFormats && barcodeFormats && barcodeFormats.length > 0) { + options.formats = barcodeFormats.map(format => mapToNativeFormat(format.barcodeFormat)) as Array< + BarcodeFormat["format"] + >; + } + // If useAllFormats is true or no specific formats, don't specify formats to use all supported + + return options; +}; + +// Create BarcodeDetector instance +export const createBarcodeDetector = (options?: BarcodeDetectorOptions): BarcodeDetector | null => { + if (!isBarcodeDetectorSupported()) { + return null; + } + + try { + return new window.BarcodeDetector!(options); + } catch (error) { + console.warn("Failed to create BarcodeDetector:", error); + return null; + } +}; + +// Detect barcodes from video or canvas element using BarcodeDetector API +export const detectBarcodesFromElement = async ( + detector: BarcodeDetector, + element: HTMLVideoElement | HTMLCanvasElement +): Promise => { + try { + return await detector.detect(element); + } catch (error) { + console.warn("BarcodeDetector failed to detect:", error); + return []; + } +}; + +// Convert video frame to canvas for processing +export const captureVideoFrame = (video: HTMLVideoElement, canvas?: HTMLCanvasElement): HTMLCanvasElement => { + if (!canvas) { + canvas = document.createElement("canvas"); + } + + canvas.width = video.videoWidth; + canvas.height = video.videoHeight; + + const ctx = canvas.getContext("2d"); + if (ctx) { + ctx.drawImage(video, 0, 0, canvas.width, canvas.height); + } + + return canvas; +}; + +export const setupVideoElement = (video: HTMLVideoElement, stream: MediaStream): void => { + video.autofocus = true; + video.playsInline = true; // Fix error in Safari + video.muted = true; + video.srcObject = stream; +}; diff --git a/packages/pluggableWidgets/barcode-scanner-web/src/helpers/barcode-detector.ts b/packages/pluggableWidgets/barcode-scanner-web/src/helpers/barcode-detector.ts new file mode 100644 index 0000000000..7522ef7d60 --- /dev/null +++ b/packages/pluggableWidgets/barcode-scanner-web/src/helpers/barcode-detector.ts @@ -0,0 +1,51 @@ +// TypeScript definitions for the BarcodeDetector API +// Based on https://developer.mozilla.org/en-US/docs/Web/API/BarcodeDetector + +// https://developer.mozilla.org/en-US/docs/Web/API/Barcode_Detection_API#supported_barcode_formats +export interface BarcodeFormat { + format: + | "aztec" + | "code_128" + | "code_39" + | "code_93" + | "codabar" + | "data_matrix" + | "ean_13" + | "ean_8" + | "itf" + | "pdf417" + | "qr_code" + | "unknown" + | "upc_a" + | "upc_e"; +} + +export interface DetectedBarcode { + boundingBox: DOMRectReadOnly; + cornerPoints: ReadonlyArray<{ x: number; y: number }>; + format: BarcodeFormat["format"]; + rawValue: string; +} + +export interface BarcodeDetectorOptions { + formats?: Array; +} + +export interface BarcodeDetector { + detect(image: ImageBitmapSource): Promise; + getSupportedFormats(): Promise>; +} + +export type BarcodeDetectorConstructor = new (options?: BarcodeDetectorOptions) => BarcodeDetector; + +// Extend Window interface to include BarcodeDetector +declare global { + interface Window { + BarcodeDetector?: BarcodeDetectorConstructor; + } +} + +export interface MxBarcodeReader { + start(onSuccess: (data: string) => void, onError: (e: Error) => void): Promise; + stop(): void; +} diff --git a/packages/pluggableWidgets/barcode-scanner-web/src/components/utils.tsx b/packages/pluggableWidgets/barcode-scanner-web/src/helpers/utils.tsx similarity index 84% rename from packages/pluggableWidgets/barcode-scanner-web/src/components/utils.tsx rename to packages/pluggableWidgets/barcode-scanner-web/src/helpers/utils.tsx index b37ba68039..0eb7d991fc 100644 --- a/packages/pluggableWidgets/barcode-scanner-web/src/components/utils.tsx +++ b/packages/pluggableWidgets/barcode-scanner-web/src/helpers/utils.tsx @@ -7,8 +7,29 @@ import { HybridBinarizer, Result } from "@zxing/library"; +import { RefObject } from "react"; import { BarcodeFormatsType } from "typings/BarcodeScannerProps"; +export const mediaStreamConstraints: MediaStreamConstraints = { + audio: false, + video: { + facingMode: "environment", + width: { min: 1280, ideal: 4096, max: 4096 }, + height: { min: 720, ideal: 2160, max: 2160 } + } +}; + +export type ReaderProps = { + onSuccess?: (data: string) => void; + onError?: (e: Error) => void; + useCrop: boolean; + barcodeFormats?: BarcodeFormatsType[]; + useAllFormats: boolean; + canvasMiddleRef: RefObject; +}; + +export type UseReaderHook = (args: ReaderProps) => RefObject; + export const returnVideoWidthHeight = ( curVideoRef: HTMLVideoElement, canvasMiddle: HTMLDivElement diff --git a/packages/pluggableWidgets/barcode-scanner-web/src/hooks/nativeReader.ts b/packages/pluggableWidgets/barcode-scanner-web/src/hooks/nativeReader.ts new file mode 100644 index 0000000000..3224013323 --- /dev/null +++ b/packages/pluggableWidgets/barcode-scanner-web/src/hooks/nativeReader.ts @@ -0,0 +1,77 @@ +import { RefObject } from "react"; +import { BarcodeDetector, MxBarcodeReader } from "../helpers/barcode-detector"; +import { createBarcodeDetector, createBarcodeDetectorOptions } from "../helpers/barcode-detector-utils"; +import { mediaStreamConstraints, ReaderProps } from "../helpers/utils"; + +export class Reader implements MxBarcodeReader { + private videoRef: RefObject; + barcodeDetector: BarcodeDetector | null; + useCrop: boolean; + stopped: boolean = false; + canvasMiddleRef: RefObject; + stream: MediaStream | null = null; + decodeInterval: NodeJS.Timeout | number | null = null; + + constructor(args: ReaderProps, videoRef: RefObject) { + this.videoRef = videoRef; + this.useCrop = args.useCrop; + this.canvasMiddleRef = args.canvasMiddleRef; + const options = createBarcodeDetectorOptions(args.useAllFormats, args.barcodeFormats); + this.barcodeDetector = createBarcodeDetector(options); + } + + start = async (onSuccess: (data: string) => void, onError: (e: Error) => void): Promise => { + if (this.videoRef.current === null) { + return; + } + + if (this.barcodeDetector === null) { + if (onError) { + onError(new Error("Failed to create barcode detector")); + } + + return; + } + + const stream = await navigator.mediaDevices.getUserMedia(mediaStreamConstraints); + + this.videoRef.current.autofocus = true; + this.videoRef.current.playsInline = true; // Fix error in Safari + this.videoRef.current.muted = true; + this.videoRef.current.autoplay = true; + this.videoRef.current.srcObject = stream; + this.decodeInterval = setTimeout(this.decodeStream, 50, onSuccess, onError); + }; + + stop = (): void => { + if (this.decodeInterval) { + clearTimeout(this.decodeInterval); + } + this.stream?.getVideoTracks().forEach(track => track.stop()); + this.barcodeDetector = null; + }; + + decodeStream = async ( + // loop decode canvas till it finds a result + resolve: (value: string) => void, + reject: (reason?: Error) => void + ): Promise => { + try { + if (this.videoRef.current === null) { + return; + } + if (this.decodeInterval) { + clearTimeout(this.decodeInterval); + } + const detectionCode = await this.barcodeDetector?.detect(this.videoRef.current); + + if (detectionCode && detectionCode.length > 0) { + if (resolve) resolve(detectionCode[0].rawValue); + } else { + this.decodeInterval = setTimeout(this.decodeStream, 50, resolve, reject); + } + } catch (error) { + reject(error); + } + }; +} diff --git a/packages/pluggableWidgets/barcode-scanner-web/src/hooks/useReader.ts b/packages/pluggableWidgets/barcode-scanner-web/src/hooks/useReader.ts index 1cd4eff3fc..93335625bf 100644 --- a/packages/pluggableWidgets/barcode-scanner-web/src/hooks/useReader.ts +++ b/packages/pluggableWidgets/barcode-scanner-web/src/hooks/useReader.ts @@ -1,17 +1,10 @@ -import { RefObject, useEffect, useRef } from "react"; -import { BrowserMultiFormatReader, NotFoundException, Result } from "@zxing/library"; import { useEventCallback } from "@mendix/widget-plugin-hooks/useEventCallback"; +import { RefObject, useEffect, useMemo, useRef } from "react"; +import { MxBarcodeReader } from "src/helpers/barcode-detector"; import { BarcodeFormatsType } from "../../typings/BarcodeScannerProps"; -import { createHints, decodeCanvas, drawCropOnCanvas } from "../components/utils"; - -const mediaStreamConstraints: MediaStreamConstraints = { - audio: false, - video: { - facingMode: "environment", - width: { min: 1280, ideal: 2560, max: 2560 }, - height: { min: 720, ideal: 1440, max: 1440 } - } -}; +import { isBarcodeDetectorSupported } from "../helpers/barcode-detector-utils"; +import { Reader as NativeReader } from "./nativeReader"; +import { Reader as ZxReader } from "./zxReader"; type UseReaderHook = (args: { onSuccess?: (data: string) => void; @@ -20,99 +13,24 @@ type UseReaderHook = (args: { barcodeFormats?: BarcodeFormatsType[]; useAllFormats: boolean; canvasMiddleRef: RefObject; -}) => RefObject; +}) => { ref: RefObject; useBrowserAPI: boolean }; export const useReader: UseReaderHook = args => { const videoRef = useRef(null); const onSuccess = useEventCallback(args.onSuccess); const onError = useEventCallback(args.onError); - const stopped = useRef(false); - const reader = useRef(); - const checkNotFound = (error: any): boolean => { - const ifNotFound = error instanceof NotFoundException; - return ifNotFound && !stopped.current; - }; + const enableBrowserAPI = useMemo(() => isBarcodeDetectorSupported(), []); - const decodeCropFromVideo = ( - // loop decode canvas till it finds a result - resolve: (value: Result) => void, - reject: (reason?: Error) => void, - captureCanvas: HTMLCanvasElement - ): void => { - try { - if (videoRef.current === null || reader.current === undefined || args.canvasMiddleRef.current === null) { - setTimeout(() => decodeCropFromVideo(resolve, reject, captureCanvas), 50); - return; - } - const croppedOnCanvas = drawCropOnCanvas(captureCanvas, videoRef.current, args.canvasMiddleRef.current); - const result = decodeCanvas(reader.current, croppedOnCanvas); - if (result === null) { - throw new NotFoundException(); - } - resolve(result); - } catch (error) { - if (checkNotFound(error)) { - setTimeout(() => decodeCropFromVideo(resolve, reject, captureCanvas), 50); - } else { - reject(error); - } - } - }; + const reader: MxBarcodeReader = useMemo(() => { + return enableBrowserAPI ? new NativeReader(args, videoRef) : new ZxReader(args, videoRef); + }, [enableBrowserAPI, args, videoRef]); useEffect(() => { - const hints = createHints(args.useAllFormats, args.barcodeFormats); - const newReader = new BrowserMultiFormatReader(hints, 500); - reader.current = newReader; - const stop = (): void => { - stopped.current = true; - newReader.stopAsyncDecode(); - newReader.reset(); - }; - const start = async (): Promise => { - let stream; - if (videoRef.current === null) { - return; - } - try { - stream = await navigator.mediaDevices.getUserMedia(mediaStreamConstraints); - - let result: Result; - if (args.useCrop) { - videoRef.current.srcObject = stream; - videoRef.current.autofocus = true; - videoRef.current.playsInline = true; // Fix error in Safari - await videoRef.current.play(); - const captureCanvas = newReader.createCaptureCanvas(videoRef.current); - result = await new Promise((resolve, reject) => - decodeCropFromVideo(resolve, reject, captureCanvas) - ); - } else { - result = await newReader.decodeOnceFromStream(stream, videoRef.current); - } - if (!stopped.current) { - onSuccess(result.getText()); - } - } catch (error) { - // Suppress not found error if widget is closed normally (eg. leaving page); - if (!checkNotFound(error)) { - if (error instanceof Error) { - console.error(error.message); - } - if (onError) { - onError(error); - } - } - } finally { - stop(); - stream?.getVideoTracks().forEach(track => track.stop()); - } - }; - - start(); + reader.start(onSuccess, onError); - return stop; + return reader.stop; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - return videoRef; + return { ref: videoRef, useBrowserAPI: enableBrowserAPI }; }; diff --git a/packages/pluggableWidgets/barcode-scanner-web/src/hooks/zxReader.ts b/packages/pluggableWidgets/barcode-scanner-web/src/hooks/zxReader.ts new file mode 100644 index 0000000000..425d79aa9a --- /dev/null +++ b/packages/pluggableWidgets/barcode-scanner-web/src/hooks/zxReader.ts @@ -0,0 +1,110 @@ +import { BrowserMultiFormatReader, NotFoundException, Result } from "@zxing/library"; +import { RefObject } from "react"; +import { MxBarcodeReader } from "../helpers/barcode-detector"; +import { createHints, decodeCanvas, drawCropOnCanvas, mediaStreamConstraints, ReaderProps } from "../helpers/utils"; + +export class Reader implements MxBarcodeReader { + private videoRef: RefObject; + barcodeDetector: BrowserMultiFormatReader | null; + useCrop: boolean; + stopped: boolean = false; + canvasMiddleRef: RefObject; + + constructor(args: ReaderProps, videoRef: RefObject) { + this.videoRef = videoRef; + this.useCrop = args.useCrop; + this.canvasMiddleRef = args.canvasMiddleRef; + + const hints = createHints(args.useAllFormats, args.barcodeFormats); + this.barcodeDetector = new BrowserMultiFormatReader(hints, 500); + } + + start = async (onSuccess: (data: string) => void, onError: (e: Error) => void): Promise => { + let stream; + if (this.videoRef.current === null) { + return; + } + + if (this.barcodeDetector === null) { + if (onError) { + onError(new Error("Failed to create barcode detector")); + } + + return; + } + try { + stream = await navigator.mediaDevices.getUserMedia(mediaStreamConstraints); + + let result: Result; + if (this.useCrop) { + this.videoRef.current.srcObject = stream; + this.videoRef.current.autofocus = true; + this.videoRef.current.playsInline = true; // Fix error in Safari + await this.videoRef.current.play(); + const captureCanvas = this.barcodeDetector.createCaptureCanvas(this.videoRef.current); + result = await new Promise((resolve, reject) => + this.decodeCropFromVideo(resolve, reject, captureCanvas) + ); + } else { + result = await this.barcodeDetector.decodeOnceFromStream(stream, this.videoRef.current); + } + if (!this.stopped) { + if (onSuccess) onSuccess(result.getText()); + } + } catch (error) { + // Suppress not found error if widget is closed normally (eg. leaving page); + if (!this.checkNotFound(error)) { + if (error instanceof Error) { + console.error(error.message); + } + if (onError) { + onError(error); + } + } + } finally { + stop(); + stream?.getVideoTracks().forEach(track => track.stop()); + } + }; + + stop = (): void => { + this.stopped = true; + this.barcodeDetector?.stopAsyncDecode(); + this.barcodeDetector?.reset(); + }; + + checkNotFound = (error: any): boolean => { + const ifNotFound = error instanceof NotFoundException; + return ifNotFound && !this.stopped; + }; + + decodeCropFromVideo = ( + // loop decode canvas till it finds a result + resolve: (value: Result) => void, + reject: (reason?: Error) => void, + captureCanvas: HTMLCanvasElement + ): void => { + try { + if (this.videoRef === null || this.barcodeDetector === undefined || this.canvasMiddleRef === null) { + setTimeout(() => this.decodeCropFromVideo(resolve, reject, captureCanvas), 50); + return; + } + const croppedOnCanvas = drawCropOnCanvas( + captureCanvas, + this.videoRef.current!, + this.canvasMiddleRef.current! + ); + const result = decodeCanvas(this.barcodeDetector!, croppedOnCanvas); + if (result === null) { + throw new NotFoundException(); + } + resolve(result); + } catch (error) { + if (this.checkNotFound(error)) { + setTimeout(() => this.decodeCropFromVideo(resolve, reject, captureCanvas), 50); + } else { + reject(error); + } + } + }; +} diff --git a/packages/pluggableWidgets/barcode-scanner-web/src/package.xml b/packages/pluggableWidgets/barcode-scanner-web/src/package.xml index 5cbb21ea61..c620024d47 100644 --- a/packages/pluggableWidgets/barcode-scanner-web/src/package.xml +++ b/packages/pluggableWidgets/barcode-scanner-web/src/package.xml @@ -1,6 +1,6 @@ - + diff --git a/packages/pluggableWidgets/barcode-scanner-web/src/ui/BarcodeScanner.scss b/packages/pluggableWidgets/barcode-scanner-web/src/ui/BarcodeScanner.scss index a7d017b7d7..d03b751d37 100644 --- a/packages/pluggableWidgets/barcode-scanner-web/src/ui/BarcodeScanner.scss +++ b/packages/pluggableWidgets/barcode-scanner-web/src/ui/BarcodeScanner.scss @@ -97,6 +97,15 @@ } } } + + &.debug { + // for debug purposes, we need to determine if barcode scanner is using native or zxing + &.mx-barcode-detector { + .mx-barcode-scanner-content { + border: 4px solid var(--brand-success, #16aa16); + } + } + } } // Overwrite `atlas_core/web/core/_legacy/_mxui.scss` for this particular widget because otherwise From 21829e9b79144e13abcd178d00b6875b0025ad3e Mon Sep 17 00:00:00 2001 From: gjulivan Date: Wed, 3 Sep 2025 00:35:50 +0200 Subject: [PATCH 2/6] fix: update based on review feedbacks --- .../barcode-scanner-web/src/helpers/utils.tsx | 2 +- .../src/hooks/nativeReader.ts | 4 ++-- .../src/hooks/useReader.ts | 19 +++++-------------- .../barcode-scanner-web/src/hooks/zxReader.ts | 2 +- 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/packages/pluggableWidgets/barcode-scanner-web/src/helpers/utils.tsx b/packages/pluggableWidgets/barcode-scanner-web/src/helpers/utils.tsx index 0eb7d991fc..6cf7be419c 100644 --- a/packages/pluggableWidgets/barcode-scanner-web/src/helpers/utils.tsx +++ b/packages/pluggableWidgets/barcode-scanner-web/src/helpers/utils.tsx @@ -28,7 +28,7 @@ export type ReaderProps = { canvasMiddleRef: RefObject; }; -export type UseReaderHook = (args: ReaderProps) => RefObject; +export type UseReaderHook = (args: ReaderProps) => { ref: RefObject; useBrowserAPI: boolean }; export const returnVideoWidthHeight = ( curVideoRef: HTMLVideoElement, diff --git a/packages/pluggableWidgets/barcode-scanner-web/src/hooks/nativeReader.ts b/packages/pluggableWidgets/barcode-scanner-web/src/hooks/nativeReader.ts index 3224013323..a7b0667a46 100644 --- a/packages/pluggableWidgets/barcode-scanner-web/src/hooks/nativeReader.ts +++ b/packages/pluggableWidgets/barcode-scanner-web/src/hooks/nativeReader.ts @@ -33,13 +33,13 @@ export class Reader implements MxBarcodeReader { return; } - const stream = await navigator.mediaDevices.getUserMedia(mediaStreamConstraints); + this.stream = await navigator.mediaDevices.getUserMedia(mediaStreamConstraints); this.videoRef.current.autofocus = true; this.videoRef.current.playsInline = true; // Fix error in Safari this.videoRef.current.muted = true; this.videoRef.current.autoplay = true; - this.videoRef.current.srcObject = stream; + this.videoRef.current.srcObject = this.stream; this.decodeInterval = setTimeout(this.decodeStream, 50, onSuccess, onError); }; diff --git a/packages/pluggableWidgets/barcode-scanner-web/src/hooks/useReader.ts b/packages/pluggableWidgets/barcode-scanner-web/src/hooks/useReader.ts index 93335625bf..50befee49e 100644 --- a/packages/pluggableWidgets/barcode-scanner-web/src/hooks/useReader.ts +++ b/packages/pluggableWidgets/barcode-scanner-web/src/hooks/useReader.ts @@ -1,20 +1,11 @@ import { useEventCallback } from "@mendix/widget-plugin-hooks/useEventCallback"; -import { RefObject, useEffect, useMemo, useRef } from "react"; +import { useEffect, useMemo, useRef } from "react"; import { MxBarcodeReader } from "src/helpers/barcode-detector"; -import { BarcodeFormatsType } from "../../typings/BarcodeScannerProps"; import { isBarcodeDetectorSupported } from "../helpers/barcode-detector-utils"; +import { UseReaderHook } from "../helpers/utils"; import { Reader as NativeReader } from "./nativeReader"; import { Reader as ZxReader } from "./zxReader"; -type UseReaderHook = (args: { - onSuccess?: (data: string) => void; - onError?: (e: Error) => void; - useCrop: boolean; - barcodeFormats?: BarcodeFormatsType[]; - useAllFormats: boolean; - canvasMiddleRef: RefObject; -}) => { ref: RefObject; useBrowserAPI: boolean }; - export const useReader: UseReaderHook = args => { const videoRef = useRef(null); const onSuccess = useEventCallback(args.onSuccess); @@ -23,14 +14,14 @@ export const useReader: UseReaderHook = args => { const reader: MxBarcodeReader = useMemo(() => { return enableBrowserAPI ? new NativeReader(args, videoRef) : new ZxReader(args, videoRef); - }, [enableBrowserAPI, args, videoRef]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [enableBrowserAPI, args.barcodeFormats, args.useAllFormats, args.useCrop, videoRef]); useEffect(() => { reader.start(onSuccess, onError); return reader.stop; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + }, [onSuccess, onError, reader]); return { ref: videoRef, useBrowserAPI: enableBrowserAPI }; }; diff --git a/packages/pluggableWidgets/barcode-scanner-web/src/hooks/zxReader.ts b/packages/pluggableWidgets/barcode-scanner-web/src/hooks/zxReader.ts index 425d79aa9a..06e76d1e5a 100644 --- a/packages/pluggableWidgets/barcode-scanner-web/src/hooks/zxReader.ts +++ b/packages/pluggableWidgets/barcode-scanner-web/src/hooks/zxReader.ts @@ -62,7 +62,7 @@ export class Reader implements MxBarcodeReader { } } } finally { - stop(); + this.stop(); stream?.getVideoTracks().forEach(track => track.stop()); } }; From 447ece96d2ea9af6d326ce323b4531bd7ac4cb28 Mon Sep 17 00:00:00 2001 From: gjulivan Date: Wed, 3 Sep 2025 11:21:27 +0200 Subject: [PATCH 3/6] fix: test cases, avoid null on destructure --- .../barcode-scanner-web/src/components/BarcodeScanner.tsx | 5 ++++- .../__tests__/__snapshots__/BarcodeScanner.spec.tsx.snap | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/pluggableWidgets/barcode-scanner-web/src/components/BarcodeScanner.tsx b/packages/pluggableWidgets/barcode-scanner-web/src/components/BarcodeScanner.tsx index 1cfd41d4e8..b75f0d4cd6 100644 --- a/packages/pluggableWidgets/barcode-scanner-web/src/components/BarcodeScanner.tsx +++ b/packages/pluggableWidgets/barcode-scanner-web/src/components/BarcodeScanner.tsx @@ -69,7 +69,7 @@ export function BarcodeScanner({ }: BarcodeScannerProps): ReactElement | null { const [errorMessage, setError] = useCustomErrorMessage(); const canvasMiddleRef = useRef(null); - const { ref: videoRef, useBrowserAPI } = useReader({ + const reader = useReader({ onSuccess: onDetect, onError: setError, useCrop: showMask, @@ -77,6 +77,9 @@ export function BarcodeScanner({ useAllFormats, canvasMiddleRef }); + + const { ref: videoRef, useBrowserAPI } = reader ?? {}; + const supportsCameraAccess = typeof navigator?.mediaDevices?.getUserMedia === "function"; const onCanPlay = useCallback((event: SyntheticEvent) => { if (event.currentTarget.paused) { diff --git a/packages/pluggableWidgets/barcode-scanner-web/src/components/__tests__/__snapshots__/BarcodeScanner.spec.tsx.snap b/packages/pluggableWidgets/barcode-scanner-web/src/components/__tests__/__snapshots__/BarcodeScanner.spec.tsx.snap index 467197958e..0da0f14184 100644 --- a/packages/pluggableWidgets/barcode-scanner-web/src/components/__tests__/__snapshots__/BarcodeScanner.spec.tsx.snap +++ b/packages/pluggableWidgets/barcode-scanner-web/src/components/__tests__/__snapshots__/BarcodeScanner.spec.tsx.snap @@ -3,7 +3,7 @@ exports[`Barcode scanner does not show the overlay when the user opts out of it 1`] = `
Date: Wed, 10 Sep 2025 16:23:01 +0200 Subject: [PATCH 4/6] fix: add more checking for supported barcode detector detect function --- .../src/helpers/barcode-detector-utils.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/pluggableWidgets/barcode-scanner-web/src/helpers/barcode-detector-utils.tsx b/packages/pluggableWidgets/barcode-scanner-web/src/helpers/barcode-detector-utils.tsx index f25d082afc..043048a6d2 100644 --- a/packages/pluggableWidgets/barcode-scanner-web/src/helpers/barcode-detector-utils.tsx +++ b/packages/pluggableWidgets/barcode-scanner-web/src/helpers/barcode-detector-utils.tsx @@ -21,7 +21,12 @@ const mapToNativeFormat = (format: string): string => { // Check if BarcodeDetector API is available export const isBarcodeDetectorSupported = (): boolean => { - return typeof globalThis !== "undefined" && "BarcodeDetector" in globalThis; + return ( + typeof globalThis !== "undefined" && + "BarcodeDetector" in globalThis && + "detect" in (globalThis as any).BarcodeDetector && + typeof (globalThis as any).BarcodeDetector.detect === "function" + ); }; // Get supported formats for BarcodeDetector From 43101cc6569ff4dd4c902137163b424d1ac5cde5 Mon Sep 17 00:00:00 2001 From: gjulivan Date: Fri, 12 Sep 2025 11:00:08 +0200 Subject: [PATCH 5/6] chore: add advance config and handle media not ready state --- .../barcode-scanner-web/src/BarcodeScanner.tsx | 1 + .../barcode-scanner-web/src/BarcodeScanner.xml | 11 ++++++++++- .../src/components/BarcodeScanner.tsx | 7 +++++-- .../src/helpers/barcode-detector-utils.tsx | 16 +++++++--------- .../barcode-scanner-web/src/helpers/utils.tsx | 1 + .../src/hooks/nativeReader.ts | 12 +++++++----- .../barcode-scanner-web/src/hooks/useReader.ts | 5 ++++- .../typings/BarcodeScannerProps.d.ts | 4 ++++ 8 files changed, 39 insertions(+), 18 deletions(-) diff --git a/packages/pluggableWidgets/barcode-scanner-web/src/BarcodeScanner.tsx b/packages/pluggableWidgets/barcode-scanner-web/src/BarcodeScanner.tsx index 6381f5cdc9..22c2079ed2 100644 --- a/packages/pluggableWidgets/barcode-scanner-web/src/BarcodeScanner.tsx +++ b/packages/pluggableWidgets/barcode-scanner-web/src/BarcodeScanner.tsx @@ -28,6 +28,7 @@ export const BarcodeScanner: FunctionComponent = p height={props.height} widthUnit={props.widthUnit} width={props.width} + detectionLogic={props.detectionLogic} /> ); }; diff --git a/packages/pluggableWidgets/barcode-scanner-web/src/BarcodeScanner.xml b/packages/pluggableWidgets/barcode-scanner-web/src/BarcodeScanner.xml index 778dfe1ed9..485a09e4be 100644 --- a/packages/pluggableWidgets/barcode-scanner-web/src/BarcodeScanner.xml +++ b/packages/pluggableWidgets/barcode-scanner-web/src/BarcodeScanner.xml @@ -62,7 +62,6 @@ - @@ -92,5 +91,15 @@ + + + Detection logic + Choose the detection logic to use for barcode scanning. + + ZXing + BarcodeDetector API (experimental fast scan, fallback to ZXing) + + + diff --git a/packages/pluggableWidgets/barcode-scanner-web/src/components/BarcodeScanner.tsx b/packages/pluggableWidgets/barcode-scanner-web/src/components/BarcodeScanner.tsx index b75f0d4cd6..ad8faeeb71 100644 --- a/packages/pluggableWidgets/barcode-scanner-web/src/components/BarcodeScanner.tsx +++ b/packages/pluggableWidgets/barcode-scanner-web/src/components/BarcodeScanner.tsx @@ -4,7 +4,7 @@ import { Alert } from "@mendix/widget-plugin-component-kit/Alert"; import { Dimensions, getDimensions } from "@mendix/widget-plugin-platform/utils/get-dimensions"; import { useCustomErrorMessage } from "../hooks/useCustomErrorMessage"; import { useReader } from "../hooks/useReader"; -import { BarcodeFormatsType } from "../../typings/BarcodeScannerProps"; +import { BarcodeFormatsType, BarcodeScannerContainerProps } from "../../typings/BarcodeScannerProps"; import "../ui/BarcodeScanner.scss"; @@ -57,6 +57,7 @@ export interface BarcodeScannerProps extends Dimensions { class: string; useAllFormats: boolean; barcodeFormats?: BarcodeFormatsType[]; + detectionLogic?: BarcodeScannerContainerProps["detectionLogic"]; } export function BarcodeScanner({ @@ -65,6 +66,7 @@ export function BarcodeScanner({ class: className, barcodeFormats, useAllFormats, + detectionLogic, ...dimensions }: BarcodeScannerProps): ReactElement | null { const [errorMessage, setError] = useCustomErrorMessage(); @@ -75,7 +77,8 @@ export function BarcodeScanner({ useCrop: showMask, barcodeFormats, useAllFormats, - canvasMiddleRef + canvasMiddleRef, + detectionLogic }); const { ref: videoRef, useBrowserAPI } = reader ?? {}; diff --git a/packages/pluggableWidgets/barcode-scanner-web/src/helpers/barcode-detector-utils.tsx b/packages/pluggableWidgets/barcode-scanner-web/src/helpers/barcode-detector-utils.tsx index 043048a6d2..e6de4e292d 100644 --- a/packages/pluggableWidgets/barcode-scanner-web/src/helpers/barcode-detector-utils.tsx +++ b/packages/pluggableWidgets/barcode-scanner-web/src/helpers/barcode-detector-utils.tsx @@ -21,12 +21,7 @@ const mapToNativeFormat = (format: string): string => { // Check if BarcodeDetector API is available export const isBarcodeDetectorSupported = (): boolean => { - return ( - typeof globalThis !== "undefined" && - "BarcodeDetector" in globalThis && - "detect" in (globalThis as any).BarcodeDetector && - typeof (globalThis as any).BarcodeDetector.detect === "function" - ); + return typeof globalThis !== "undefined" && "BarcodeDetector" in globalThis; }; // Get supported formats for BarcodeDetector @@ -76,13 +71,16 @@ export const createBarcodeDetector = (options?: BarcodeDetectorOptions): Barcode // Detect barcodes from video or canvas element using BarcodeDetector API export const detectBarcodesFromElement = async ( - detector: BarcodeDetector, - element: HTMLVideoElement | HTMLCanvasElement + detector: BarcodeDetector | null, + element: HTMLVideoElement | HTMLCanvasElement | null ): Promise => { try { + if (!detector || !element || (element as HTMLVideoElement).readyState < HTMLMediaElement.HAVE_CURRENT_DATA) { + return []; + } return await detector.detect(element); } catch (error) { - console.warn("BarcodeDetector failed to detect:", error); + console.warn("BarcodeDetector failed to detect:", (element as HTMLVideoElement).readyState, error); return []; } }; diff --git a/packages/pluggableWidgets/barcode-scanner-web/src/helpers/utils.tsx b/packages/pluggableWidgets/barcode-scanner-web/src/helpers/utils.tsx index 6cf7be419c..813f5b3f94 100644 --- a/packages/pluggableWidgets/barcode-scanner-web/src/helpers/utils.tsx +++ b/packages/pluggableWidgets/barcode-scanner-web/src/helpers/utils.tsx @@ -26,6 +26,7 @@ export type ReaderProps = { barcodeFormats?: BarcodeFormatsType[]; useAllFormats: boolean; canvasMiddleRef: RefObject; + detectionLogic?: "zxing" | "native"; }; export type UseReaderHook = (args: ReaderProps) => { ref: RefObject; useBrowserAPI: boolean }; diff --git a/packages/pluggableWidgets/barcode-scanner-web/src/hooks/nativeReader.ts b/packages/pluggableWidgets/barcode-scanner-web/src/hooks/nativeReader.ts index a7b0667a46..665af8bfb0 100644 --- a/packages/pluggableWidgets/barcode-scanner-web/src/hooks/nativeReader.ts +++ b/packages/pluggableWidgets/barcode-scanner-web/src/hooks/nativeReader.ts @@ -1,6 +1,10 @@ import { RefObject } from "react"; import { BarcodeDetector, MxBarcodeReader } from "../helpers/barcode-detector"; -import { createBarcodeDetector, createBarcodeDetectorOptions } from "../helpers/barcode-detector-utils"; +import { + createBarcodeDetector, + createBarcodeDetectorOptions, + detectBarcodesFromElement +} from "../helpers/barcode-detector-utils"; import { mediaStreamConstraints, ReaderProps } from "../helpers/utils"; export class Reader implements MxBarcodeReader { @@ -57,13 +61,10 @@ export class Reader implements MxBarcodeReader { reject: (reason?: Error) => void ): Promise => { try { - if (this.videoRef.current === null) { - return; - } if (this.decodeInterval) { clearTimeout(this.decodeInterval); } - const detectionCode = await this.barcodeDetector?.detect(this.videoRef.current); + const detectionCode = await detectBarcodesFromElement(this.barcodeDetector, this.videoRef.current); if (detectionCode && detectionCode.length > 0) { if (resolve) resolve(detectionCode[0].rawValue); @@ -71,6 +72,7 @@ export class Reader implements MxBarcodeReader { this.decodeInterval = setTimeout(this.decodeStream, 50, resolve, reject); } } catch (error) { + console.log("decodeStream error", error); reject(error); } }; diff --git a/packages/pluggableWidgets/barcode-scanner-web/src/hooks/useReader.ts b/packages/pluggableWidgets/barcode-scanner-web/src/hooks/useReader.ts index 50befee49e..8ba4db3ff7 100644 --- a/packages/pluggableWidgets/barcode-scanner-web/src/hooks/useReader.ts +++ b/packages/pluggableWidgets/barcode-scanner-web/src/hooks/useReader.ts @@ -10,7 +10,10 @@ export const useReader: UseReaderHook = args => { const videoRef = useRef(null); const onSuccess = useEventCallback(args.onSuccess); const onError = useEventCallback(args.onError); - const enableBrowserAPI = useMemo(() => isBarcodeDetectorSupported(), []); + const enableBrowserAPI = useMemo( + () => isBarcodeDetectorSupported() && args.detectionLogic === "native", + [args.detectionLogic] + ); const reader: MxBarcodeReader = useMemo(() => { return enableBrowserAPI ? new NativeReader(args, videoRef) : new ZxReader(args, videoRef); diff --git a/packages/pluggableWidgets/barcode-scanner-web/typings/BarcodeScannerProps.d.ts b/packages/pluggableWidgets/barcode-scanner-web/typings/BarcodeScannerProps.d.ts index e082321a7f..ada58af957 100644 --- a/packages/pluggableWidgets/barcode-scanner-web/typings/BarcodeScannerProps.d.ts +++ b/packages/pluggableWidgets/barcode-scanner-web/typings/BarcodeScannerProps.d.ts @@ -16,6 +16,8 @@ export type WidthUnitEnum = "percentage" | "pixels"; export type HeightUnitEnum = "percentageOfWidth" | "pixels" | "percentageOfParent"; +export type DetectionLogicEnum = "zxing" | "native"; + export interface BarcodeFormatsPreviewType { barcodeFormat: BarcodeFormatEnum; } @@ -34,6 +36,7 @@ export interface BarcodeScannerContainerProps { width: number; heightUnit: HeightUnitEnum; height: number; + detectionLogic: DetectionLogicEnum; } export interface BarcodeScannerPreviewProps { @@ -56,4 +59,5 @@ export interface BarcodeScannerPreviewProps { width: number | null; heightUnit: HeightUnitEnum; height: number | null; + detectionLogic: DetectionLogicEnum; } From 6db00cb6bfb68a1dc077806d0a100aa139116142 Mon Sep 17 00:00:00 2001 From: gjulivan Date: Mon, 15 Sep 2025 14:43:03 +0200 Subject: [PATCH 6/6] chore(barcode scanner): add readme oss --- ...2.5.0__READMEOSS_2025-09-15__12-39-13.html | 291 ++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 packages/pluggableWidgets/barcode-scanner-web/SiemensMendixBarcodeScanner__2.5.0__READMEOSS_2025-09-15__12-39-13.html diff --git a/packages/pluggableWidgets/barcode-scanner-web/SiemensMendixBarcodeScanner__2.5.0__READMEOSS_2025-09-15__12-39-13.html b/packages/pluggableWidgets/barcode-scanner-web/SiemensMendixBarcodeScanner__2.5.0__READMEOSS_2025-09-15__12-39-13.html new file mode 100644 index 0000000000..b1fd4a0bb6 --- /dev/null +++ b/packages/pluggableWidgets/barcode-scanner-web/SiemensMendixBarcodeScanner__2.5.0__READMEOSS_2025-09-15__12-39-13.html @@ -0,0 +1,291 @@ + + + + Siemens Third-Party Software disclosure document + + + + + + + + +
+ Siemens Third-Party Software Disclosure Document

English / English
Note to Resellers: Please pass on this document to your customers to avoid license infringements.

Third-Party Software Information

This product, solution or service ("Product") contains third-party software components listed in this document. These components are Open Source Software licensed under a license approved by the Open Source Initiative (www.opensource.org) or similar licenses as determined by SIEMENS ("OSS") and/or commercial or freeware software components. With respect to the OSS components, the applicable OSS license conditions prevail over any other terms and conditions covering the Product. The OSS portions of this Product are provided royalty-free and can be used at no charge.
If SIEMENS has combined or linked certain components of the Product with/to OSS components licensed under the GNU LGPL version 2 or later as per the definition of the applicable license, and if use of the corresponding object file is not unrestricted ("LGPL Licensed Module", whereas the LGPL Licensed Module and the components that the LGPL Licensed Module is combined with or linked to is the "Combined Product"), the following additional rights apply, if the relevant LGPL license criteria are met: (i) you are entitled to modify the Combined Product for your own use, including but not limited to the right to modify the Combined Product to relink modified versions of the LGPL Licensed Module, and (ii) you may reverse-engineer the Combined Product, but only to debug your modifications. The modification right does not include the right to distribute such modifications and you shall maintain in confidence any information resulting from such reverse-engineering of a Combined Product.
Certain OSS licenses require SIEMENS to make source code available, for example, the GNU General Public License, the GNU Lesser General Public License and the Mozilla Public License. If such licenses are applicable and this Product is not shipped with the required source code, a copy of this source code can be obtained by anyone in receipt of this information during the period required by the applicable OSS licenses by contacting the following address.
SIEMENS may charge a handling fee of up to 5 Euro to fulfil the request.
Warranty regarding further use of the Open Source Software
SIEMENS' warranty obligations are set forth in your agreement with SIEMENS. SIEMENS does not provide any warranty or technical support for this Product or any OSS components contained in it if they are modified or used in any manner not specified by SIEMENS. The license conditions listed below may contain disclaimers that apply between you and the respective licensor. For the avoidance of doubt, SIEMENS does not make any warranty commitment on behalf of or binding upon any third party licensor.

German / Deutsch
Hinweis an die Vertriebspartner: Bitte geben Sie dieses Dokument an Ihre Kunden weiter, um urheberrechtliche Lizenzverstöße zu vermeiden.
Informationen zu Fremdsoftware
Dieses Produkt, diese Lösung oder dieser Service ("Produkt") enthält die nachfolgend aufgelisteten Fremdsoftwarekomponenten. Bei diesen handelt es sich entweder um Open Source Software, die unter einer von der Open Source Initiative (www.opensource.org) anerkannten Lizenz oder einer durch Siemens als vergleichbar definierten Lizenz ("OSS") lizenziert ist und/oder um kommerzielle Software oder Freeware. Hinsichtlich der OSS Komponenten gelten die einschlägigen OSS Lizenzbedingungen vorrangig vor allen anderen auf dieses Produkt anwendbaren Bedingungen. SIEMENS stellt Ihnen die OSS-Anteile dieses Produkts ohne zusätzliche Kosten zur Verfügung.
Soweit SIEMENS bestimmte Komponenten des Produkts mit OSS Komponenten gemäß der Definition der anwendbaren Lizenz kombiniert oder verlinkt hat, die unter der GNU LGPL Version 2 oder einer späteren Version lizenziert werden und soweit die entsprechende Objektdatei nicht unbeschränkt genutzt werden darf ("LGPL-lizenziertes Modul", wobei das LGPL-lizenzierte Modul und die Komponenten, mit welchen das LGPL-lizenzierte Modul verbunden ist, nachfolgend "verbundenes Produkt" genannt werden) und die entsprechenden LGPL Lizenzkriterien erfüllt sind, dürfen Sie zusätzlich (i) das verbundene Produkt für eigene Verwendungszwecke bearbeiten und erhalten insbesondere das Recht, das verbundene Produkt zu bearbeiten, um es mit einer modifizierten Version des LGPL lizenzierten Moduls zu verlinken und (ii) das verbundene Produkt rückentwickeln, jedoch ausschließlich zum Zwecke der Fehlerkorrektur Ihrer Bearbeitungen. Das Recht zur Bearbeitung schließt nicht das Recht ein, diese zu distribuieren. Sie müssen sämtliche Informationen, die Sie aus dem Reverse Engineering des verbundenen Produktes gewinnen, vertraulich behandeln.
Bestimmte OSS Lizenzen verpflichten SIEMENS zur Herausgabe des Quellcodes, z.B. die GNU General Public License, die GNU Lesser General Public License sowie die Mozilla Public License. Soweit diese Lizenzen Anwendung finden und das Produkt nicht bereits mit dem notwendigen Quellcode ausgeliefert wurde, so kann eine Kopie des Quellcodes von jedermann während des in der anwendbaren OSS Lizenz angegebenen Zeitraums unter der folgenden Anschrift angefordert werden.
SIEMENS kann für die Erfüllung der Anfrage eine Bearbeitungsgebühr von bis zu 5 Euro in Rechnung stellen.
Gewährleistung betreffend Verwendung der Open Source Software
Die Gewährleistungspflichten von SIEMENS sind in dem jeweiligen Vertrag mit SIEMENS geregelt. Soweit Sie das Produkt oder die OSS Komponenten modifizieren oder in einer anderen als der von SIEMENS spezifizierten Weise verwenden, ist die Gewährleistung ausgeschlossen und eine technische Unterstützung erfolgt nicht. Die nachfolgenden Lizenzbedingungen können Haftungsbeschränkungen enthalten, die zwischen Ihnen und dem jeweiligen Lizenzgeber gelten. Klarstellend wird darauf hingewiesen, dass SIEMENS keine Gewährleistungsverpflichtungen im Namen von oder verpflichtend für einen Drittlizenzgeber abgibt.

Chinese / 中文
经销商须知: 请将本文件转发给您的客户,以避免构成对许可证的侵权。
第三方软件信息
本产品、解决方案或服务(统称“本产品”)中包含本文件列出的第三方软件组件。 这些组件是开放源代码促进会 (www.opensource.org) 批准的许可证或西门子确定的类似许可证所许可的开放源代码软件(简称“OSS”)和/或商业或免费软件组件。 针对 OSS组件,适用的 OSS 许可证条件优先于涵盖本产品的任何其他条款和条件。 本产品的 OSS 部分免许可费,可以免费使用。
如果西门子已经按照所适用的许可证的定义,根据第 2版或之后版本的GNU LGPL将本产品的某些组件与获得许可证的 OSS组件相组合或关联,并且如果使用相应的目标文件并非不受限制(“LGPL许可模块”,LGPL 许可模块以及与 LGPL 许可模块相组合或关联的组件统称为“组合产品”),则在符合以下相关LGPL许可标准的前提下,以下附加权利予以适用: (i) 您有权修改组合产品供自己使用,包括但不限于修改组合产品以重新连接 LGPL 许可模块修改版本的权利,并且 (ii) 您可以对组合产品进行逆向工程(但仅限于调试您的修改)。修改权不包括散布此类修改的权利,您应对此类组合产品逆向工程所获得的任何信息予以保密。
某些 OSS 许可证需要西门子提供源代码,例如 GNU 通用公共许可证、GNU 宽通用公共许可证和 Mozilla 公共许可证。如果适用此类许可证并且本产品发货时未随附所需的源代码,收到本信息的任何 人可以在所适用的OSS许可证要求的期限内通过以下地址联系获取这些源代码的副本。
西门子可收取最多 5 欧元的手续费以完成该请求。
关于进一步使用开放源代码软件的保修
您与西门子的协议中规定了西门子的保修义务。如果以西门子未指明的任何方式修改或使用本产品或其中包含的任何 OSS组件,西门子不为其提供任何保修或技术支持服务。下面列出的许可证条件可能包含适用于您和相应许可人之间的免责声明。为了避免产生疑问,西门子不代表或约束任何第三方许可人作出任何保修承诺。

Spanish / Español
Indicación para los distribuidores: Sírvase entregar este documento a sus clientes para prevenir infracciones de licencia sobre los aspectos de los derechos de autor.
Información sobre software de terceros
Este producto, solución o servicio ("producto") contiene los siguientes componentes de software de terceros listados a continuación. Se trata de Open Source Software cuya licencia ha sido otorgada por la Open Source Initiative (www.opensource.org) o que corresponde a una licencia definida por Siemens como comparable ("OSS") y/o de software o freeware comercial. En relación a los componentes OSS prevalecen las condiciones de concesión de licencia OSS pertinentes por sobre todas las demás condiciones aplicables para este producto. SIEMENS le entrega estas partes OSS del producto sin coste adicional.
En la medida en que SIEMENS haya combinado o enlazado determinados componentes del producto con componentes OSS según la definición de la licencia aplicable, cuya licencia está sujeta a la GNU LGPL versión 2 o una versión posterior y que no se puede utilizar sin restricciones ("módulo con licencia LGPL", denominándose a continuación el módulo de licencia LGPL y los componentes combinados con el módulo de licencia LGPL, como "producto integrado") y que se hayan cumplido los criterios de licencia LGPL correspondientes, usted está autorizado para adicionalmente (i) procesar el producto conectado para sus propios fines de uso y obtener particularmente el derecho a procesar el producto conectado para enlazarlo con una versión modificada del módulo de licencia LGPL y (ii) realizar ingeniería inversa para el producto conectado, pero exclusivamente para fines de corrección de errores de sus procesamientos. El derecho al procesamiento no incluye el derecho a su distribución. Está obligado a tratar de manera confidencial toda la información que obtiene en el marco de la ingeniería inversa del producto conectado.
Determinadas licencias OSS obligan a Siemens a la publicación del código fuente, p. ej. la GNU General Public License, la GNU Lesser General Public License así como la Mozilla Public License. En la medida que se apliquen estas licencias y que el producto no se haya suministrado con el código fuente necesario, puede solicitarse una copia del código fuente por parte de cualquier persona durante el período indicado en la licencia OSS, mediante envío de la solicitud correspondiente a la siguiente dirección.
SIEMENS puede facturar una tasa de servicio de hasta 5 Euros para la tramitación de la consulta.
Garantía en relación al uso del Open Source Software
Las obligaciones de Siemens relacionadas a la garantía del Software, están especificados en el contrato correspondiente con SIEMENS. En caso de modificar el producto o los componentes OSS o usarse de una manera que difiera del modo especificado por SIEMENS, dejará de tener vigencia la garantía y no habrá derechoal soporte técnico asociado a ella. Las siguientes condiciones de concesión de licencia pueden contener limitaciones de responsabilidad que rigen entre su parte y el licenciador correspondiente. Se aclara que SIEMENS no asume obligaciones de garantía en nombre de o en forma vinculante para licenciadores de terceros.

French / Français
Note pour les partenaires de distribution: veuillez transmettre ce document à vos clients pour éviter toutes infractions aux dispositions en matière de droits d’auteur.
Informations sur des logiciels de tiers
Le présent produit, solution ou service (« Produit ») contient des éléments de logiciels indiqués ci-après, appartenant à des tiers. Ces logiciels sont des Open Source Software dont l’utilisation est accordée en vertu d’une licence reconnue par la Open Service Initiative (www.opensource.org), ou d’une licence équivalente définie comme telle par Siemens ("OSS"), et/ou en vertu d’un logiciel commercial ou un freeware. En ce qui concerne les composants OSS, les conditions de licence OSS pertinentes priment sur toutes les autres conditions éventuellement applicables au Produit. SIEMENS met à votre disposition gratuitement et sans frais supplémentaires les parties OSS du Produit.
Si SIEMENS a combiné ou relié certains composants du Produit avec des éléments OSS dont l’utilisation est accordée en vertu de la licence GNU LGPL version 2 ou d'une version postérieure, conformément à la licence applicable, et si l’utilisation du fichier objet correspondant est soumise à des restrictions (« Module Sous Licence LGPL », le module sous licence LGPL et les composants avec lesquels ce module est lié, sont dénommés ci-après "Produit Lié"), si les critères de licence LGPL applicables sont respectés, vous avez également les droits suivants : (i) droit de modifier le Produit Lié pour votre propre usage , inclus notamment le droit de modifier le Produit Lié afin de le relier différentes versions modifiées du Module Sous Licence LGPL et (ii) droit de faire de la retro-ingénierie sur le Produit Lié, mais exclusivement afin de corriger les éventuels dysfonctionnements des modifications que vous y avez apportées. Le droit de modifier n’inclut pas le droit de distribuer ces modifications et toutes les informations que vous avez obtenues à l’occasion d’opérations de retro-ingénierie du Produit Lié seront strictement confidentielles.
Certaines licences OSS, comme par exemple la GNU General Public License, la GNU Lesser General Public License, ainsi que la Mozilla Public License, obligent SIEMENS à divulguer le code source. Si ces licences sont applicables et si le Produit n’a pas été préalablement livré avec le code source nécessaire, une copie du code source peut être demandée pendant la durée de la licence OSS applicable, en s’adressant à l’adresse suivante.
SIEMENS peut facturer des frais de traitement allant jusqu’à 5 Euro pour répondre à cette demande.
Garantie relative à l’utilisation du logiciel Open Source
Les obligations de garantie de SIEMENS sont définies dans votre contrat. Si vous modifiez le Produit ou les éléments OSS y contenus ou si vous les utilisez d’une manière autre que celle spécifiée par SIEMENS, vous perdez le bénéfice de la garantie et aucune assistance technique ne vous sera fournie. Les conditions de licence ci-après peuvent contenir des limitations de responsabilités applicables entre vous et le concédant. En tout état de cause, nous vous signalons que SIEMENS ne prend aucun engagement de garantie au nom et pour le compte de tiers concédants.

Italian / Italiano
IMPORTANTE per i partner commerciali: si prega di inoltrare il presente documento ai clienti per evitare violazioni delle condizioni di licenza.
Informazioni relative al software di altri produttori
Il presente prodotto, soluzione o servizio ("Prodotto") contengono componenti software di altri produttori elencati qui di seguito. Questi software di altri produttori possono essere Open Source Software (OSS), concessi in licenza con una licenza riconosciuta dall'Open Source Initiative (www.opensource.org) o ritenuta equivalente da Siemens ("OSS"), e/o software o freeware commerciali. Per quanto riguarda i componenti dell'OSS, le relative condizioni di licenza pertinenti prevalgono rispetto a tutte le altre condizioni applicabili al presente Prodotto. SIEMENS mette a disposizione i componenti dell'OSS contenuti nel presente Prodotto senza costi aggiuntivi.
Se SIEMENS ha combinato o linkato determinati componenti del Prodotto con prodotti dell'OSS secondo la definizione indicata nella licenza applicabile e concessa ai sensi della licenza GNU LGPL Version 2 o successiva, se il relativo file di oggetto non può essere utilizzato in maniera illimitata ("modulo concesso con licenza LGPL", vale a dire il modulo con licenza LGPL e i componenti a cui detto modello è collegato, denominati qui di seguito "Prodotto Collegato") e, infine, se i relativi criteri di licenza LGPL sono stati soddisfatti, sarà possibile inoltre (i) modificare il Prodotto Collegato per propri scopi di impiego, in particolare elaborare il Prodotto Collegato per linkarlo ad una versione modificata del modulo con licenza LGPL, e (ii) effettuare il reverse engineering del Prodotto Collegato, esclusivamente a fini di correzione degli errori di elaborazione. Il diritto di elaborazione non include il diritto di distribuire tali modifiche. Inoltre, tutte le informazioni ottenute con il reverse engineering del Prodotto Collegato devono essere trattate come riservate.
Determinate licenze OSS obbligano SIEMENS a pubblicare il codice sorgente, ad es. la GNU General Public License, la GNU Lesser General Public License e la Mozilla Public License. Se queste licenze sono applicabili, e il presente Prodotto non è stato già fornito con il necessario codice sorgente, è possibile richiedere una copia di detto codice nel periodo di validità indicato nella licenza OSS applicabile al seguente indirizzo.
Per l'evasione della richiesta, SIEMENS potrà addebitare fino a 5 Euro.
Garanzia di utilizzo dell'Open Source Software
Le obbligazioni di garanzia di SIEMENS sono disciplinate dal vostro contratto sottoscritto con SIEMENS. Se si modifica il Prodotto o i componenti dell'OSS, oppure li si utilizza in un modo diverso da quello specificato da SIEMENS, la garanzia e il supporto tecnico decadono. Le seguenti condizioni di licenza possono contenere limitazioni di responsabilità valevoli nel rapporto tra l'utente e il licenziante. Per maggiore chiarezza, si ribadisce che SIEMENS non concede alcuna garanzia a nome di, o vincolante per, qualsiasi terza parte licenziante.

Japanese / 日本語
再販業者への注意事項:ライセンス違反を防ぐため、本書を顧客の皆様に配布してください。
他社製ソフトウェアの使用に関する情報
本製品、ソリューション、またはサービス(以下「本製品」)には、本書に記載の他社製ソフトウェ アのコンポーネントが含まれています。該当するコンポーネントとは、Open Source Initiative (www.opensource.org) によって認可されたライセンスのもとで使用許諾を得たオープンソースソフ トウェア、または SIEMENS によって決定された同様のライセンス(以下「OSS」)、および/または商用もしくはフリーウェアのソフトウェアコンポーネントを指します。本製品を対象とするその他いかなる契約条件に対しても、OSS のコンポーネントに関しては、適用される OSS ライセンス条件が優先するものとします。本製品の OSS の部分に関しては、著作権使用料無料で提供され、無料で使用する ことができます。
SIEMENS が、本製品の特定のコンポーネントと適用されるライセンスの定義の通りに GNU LGPLのバージョン 2 以降のもとで使用許諾を得た OSS コンポーネントを組み合わせるか、関連付け、なおかつ付随するオブジェクト・ファイルの使用が制限されていない場合(以下「LGPL 使用許諾モジュー ル」、それに対し、LGPL使用許諾モジュールが組み合わされているか、関連付けられている LGPL 使用許諾済みモジュールとコンポーネントを「組み合わせ製品」という)、関連する LGPL 使用許諾の基準を満たしていれば、次の追加の権利が適用されます。(i) 個人的な使用のために組み合わせ製品を変更することができる(LGPL 使用許諾モジュールの変更したバージョンを再度関連付けるために組み合わせ製品を変更する権利を含むが、それに限定されるものではない)、および (ii) 組み合わせ製品にリバースエンジニアリングを行うことができる(ただし変更のデバッグのみ)。変更に関する権利には、該当する変更を配布する権利は含まれていません。また契約者の方は、このような組み合わせ製品のリバースエンジニアリングから生じるいかなる情報に関しても極秘として維持するものとします。
例えば、GNU General Public License (GNU一般公衆利用許諾書)、GNU Lesser General Public License(GNU劣等一般公衆利用許諾書)、Mozilla Public License 等の特定の OSSライセンスでは、SIEMENS がソースコードを利用できるようにする必要があります。該当するライセンスが適用可能であり、本製品が必要とされるソースコードとともに出荷されなかった場合、この情報を受け取った人物が適用される OSS ライセンスによって義務付けられている期間中に以下の住所まで連絡することで、このソースコードのコピーを入手することができます。
リクエストを実行するために SIEMENS では、最高 5 ユーロの手数料を請求する場合があります。
オープンソースソフトウェアのさらなる使用に関する保証
SIEMENS の保証義務は、契約者と SIEMENS との契約書に記載されています。本製品を SIEMENS が指定した以外の方法で変更したり、使用したりした場合、SIEMENS では本製品、またはいかなる OSS コンポーネントに対しても保証やテクニカルサポートを提供いたしません。以下に記載のライセンス条件には、 契約者と個別のライセンサーとの間で適用される免責事項が含まれる場合があります。誤解を避けるため、SIEMENSでは他社のライセンサーを代表、または他社を拘束するいかなる保証義務も負いません。

Russian / Русский
Информация для партнёров по сбыту: просим передать этот документ вашим клиентам во избежание нарушений лицензионных прав.
Информация о программном обеспечении сторонних разработчиков
Настоящий продукт, настоящее решение или сервис ("Продукт") включает в себя программные компоненты сторонних разработчиков, перечисленные ниже. Это компоненты программного обеспечения с открытым кодом, имеющие лицензию, признанную организацией Open Source Initiative (www.opensource.org), либо иную лицензию согласно определению компании SIEMENS ("OSS"), и / или компоненты коммерческого либо свободно распространяемого программного обеспечения. В отношении компонентов OSS соответствующие условия лицензии OSS имеют приоритет перед всеми прочими положениями, применимыми к данному Продукту. SIEMENS предоставляет вам долевые права на OSS в отношении данного Продукта на безвозмездной основе.
Если SIEMENS комбинирует или связывает определённые компоненты Продукта с компонентами OSS в соответствии с определением применимой лицензии, лицензированными по версии 2 или более поздней GNU LGPL, и если неограниченное использование соответствующего объектного файла не разрешено ("Модуль по лицензии LGPL", причём Модуль по лицензии LGPL и компоненты, с которыми скомбинирован или связан Модуль по лицензии LGPL, далее именуются "Комбинированный продукт") и выполнены соответствующие критерии лицензии LGPL, вам разрешается дополнительно (i) обрабатывать Комбинированный продукт в собственных целях и, в частности, но не ограничиваясь, обрабатывать Комбинированный продукт таким образом, чтобы связать его с модифицированной версией Модуля по лицензии LGPL, а также (ii) проводить обратную разработку Комбинированного продукта, но только в целях исправления ошибок вашей обработки. Право на обработку не включает в себя право на дистрибуцию. Вы обязаны сохранять конфиденциальность в отношении всей информации, полученной вами в ходе обратной разработки Комбинированного продукта.
Определённые лицензии OSS обязывают SIEMENS раскрывать исходный код, например, GNU General Public License, GNU Lesser General Public License и Mozilla Public License. Если указанные лицензии применимы и Продукт поставлен без необходимого исходного кода, копия исходного кода может быть запрошена обладателем настоящей информации в течение времени, указанного в применимой лицензии OSS, по следующему адресу.
За выполнение запроса SIEMENS может взимать сбор в размере до 5 евро.
Гарантия в отношении дальнейшего применения программного обеспечения с открытым кодом
Гарантийные обязательства SIEMENS регулируются соответствующим договором с компанией SIEMENS. Если вы модифицируете Продукт или компоненты OSS либо используете их иным образом, чем указано компанией SIEMENS, гарантия аннулируется, техническая поддержка не предоставляется. Приведённые ниже лицензионные условия могут включать в себя положения об ограничении ответственности, действующие в отношениях между вами и соответствующим лицензиаром. Во избежание сомнений подчёркиваем, что SIEMENS не даёт гарантии от имени сторонних лицензиаров и гарантии, налагающей обязательства на сторонних лицензиаров.


Korean / 한국어
제3자 소프트웨어 정보

본 제품, 솔루션 또는 서비스(이하 “제품”)는 본 문서에 기재된 제3자 소프트웨어 구성요소를 포함한다. 이들 구성요소는 오픈 소스 이니셔티브(www.opensource.org)가 승인한 라이선스 또는 지멘스가 유사 라이선스로 판단하는 라이선스 하에 사용 권한이 부여된 오픈 소스 소프트웨어(이하 "OSS") 및/또는 상용 또는 무료 소프트웨어 구성요소이다. OSS 구성요소와 관련하여, 해당되는 OSS 라이선스 조건은 본 제품을 포괄하는 기타 모든 약관에 우선한다. 본 제품의 OSS 일부는 로열티 없이 제공되며 무료로 사용할 수 있다.

지멘스가 해당되는 라이선스의 정의에 따라 GNU LGPL 버전 2 또는 그 이상의 사용 권한이 부여된 OSS 구성요소와 본 제품의 특정 구성요소를 조합 또는 연결한 경우 그리고 해당 오브젝트 파일의 사용이 제한되지 않는 경우(이하 "LGPL 라이선스 모듈"인반면, LGPL 라이선스 모듈과 LGPL 라이선스 모듈이 조합 또는 연결된 구성요소는 "조합 제품"이라 한다) 관련 LPGL 라이선스 기준이 충족되는 경우에 한하여 다음과 같은 추가적인 권한을 가진다. (i) 귀하는 사용을 위한 조합 제품을 수정할 권리가 있으며, 이는 조합 제품을 수정하여 LGPL 라이선스 모듈의 수정 버전에 재연결할 수 있는 권리를 포함하되 이에 한정하지 않는다. 그리고 (ii) 귀하는 조합 제품을 역엔지니어링할 수 있지만 이는 귀하의 수정 항목을 디버깅하기 위해서만 가능하다. 본 수정 권한은 그러한 수정 항목을 배포할 권리는 포함하지 않으며, 귀하는 조합 제품의 그러한 역엔지니어링으로부터 발생한 모든 정보를 기밀로 유지해야 한다.

일부 OSS 라이선스는 지멘스가 소스 코드를 사용할 수 있게 만들 것을 요구하며, 이러한 소스 코드의 예는 GNU 일반 공중 사용 허가서(GNU General Public License), GNU 약소 일반 공중 사용 허가서(GNU Lesser General Public License), 모질라 공용 허가서(Mozilla Public License)가 있다. 이러한 라이선스가 적용되고 본 제품이 요구하는 소스 코드와 함께 배송되지 않은 경우, 해당 OSS 라이선스가 요구하는 기간 동안 본 정보를 받아보는 누구나 다음 주소로 연락하여 해당 소스 코드의 사본을 얻을 수 있다

지멘스는 이 요청을 충족하기 위해 최대 5유로의 취급 수수료를 부과할 수 있다.

오픈 소스 소프트웨어의 추가적 사용과 관련한 보증

지멘스의 보증 의무는 지멘스와 귀하 간의 계약서에 명시되어 있다. 본 제품 또는 본 제품에 포함된 OSS 구성요소가 지멘스에서 지정하지 않은 방식으로 수정 또는 사용된 경우, 지멘스는 본 제품 또는 본 제품에 포함된 어떠한 OSS 구성요소에도 어떠한 보증이나 기술 지원도 제공하지 않는다. 아래 나열된 라이선스 조건에는 귀하와 관련 라이선스 소유자 간에 적용되는 면책 조항이 포함되어 있을 수 있다. 혼동을 피하기 위해 명확히 하자면, 지멘스는 어떠한 제3자 라이선스 소유자를 대신하여 또는 그를 구속하는 어떠한 보증 약속도 하지 않는다.


Open Source Software and/or other third-party software contained in this Product

If you like to receive a copy of the source code, please contact SIEMENS at the following address:

Siemens AG
Attn: Software Licensing
LC TEC IT&SL
Hertha-Sponer-Weg 3
91058 Erlangen
Germany

Subject: Open Source Request (please specify Product name and version)

+
+ +

+ +

+ +

+ Please note the following license conditions and copyright notices applicable to Open Source Software and/or other components (or parts thereof): +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ComponentOpen Source Software
[Yes/No]
Acknowledgements/CommentLicense conditions and copyright notices
@zxing/library (npm) - 0.21.3YesLICENSE AND COPYRIGHT INFORMATION FOR COMPONENT @zxing/library (npm) - 0.21.3
classnames (npm) - 2.5.1YesLICENSE AND COPYRIGHT INFORMATION FOR COMPONENT classnames (npm) - 2.5.1
ts-custom-error (npm) - 3.3.1YesLICENSE AND COPYRIGHT INFORMATION FOR COMPONENT ts-custom-error (npm) - 3.3.1
+ + + + + + + + + + + + + + +
+


LICENSE CONDITIONS AND COPYRIGHT NOTICES

+

Open Source Software: - @zxing/library (npm) - 0.21.3

+

Enclosed you will find the license conditions and + copyright notices applicable for + - @zxing/library (npm) - 0.21.3

+
+ +
License conditions:
+
+ + + + + + + +
Apache License Version 2.0, January 2004

http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

1. Definitions.

"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.

"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."

"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

(b) You must cause any modified files to carry prominent notices stating that You changed the files; and

(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

(d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
CLASSPATH" EXCEPTION TO THE GPL



Certain source files distributed by Oracle are subject to the following clarification and special exception to the GPL Version 2, but only where Oracle has expressly included in the particular source file's header the words "Oracle designates this particular file as subject to the "Classpath" exception as provided by Oracle in the License file that accompanied this code."



Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and conditions of the GNU General Public License Version 2 cover the whole combination.



As a special exception, the copyright holders of this library give you permission to link this library with independent modules to produce an executable, regardless of the license terms of these independent modules, and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version.



The GNU General Public License (GPL)



Version 2, June 1991



Copyright (C) 1989, 1991 Free Software Foundation, Inc.

51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA



Everyone is permitted to copy and distribute verbatim copies of this license

document, but changing it is not allowed.



Preamble



The licenses for most software are designed to take away your freedom to share

and change it. By contrast, the GNU General Public License is intended to

guarantee your freedom to share and change free software--to make sure the

software is free for all its users. This General Public License applies to

most of the Free Software Foundation's software and to any other program whose

authors commit to using it. (Some other Free Software Foundation software is

covered by the GNU Library General Public License instead.) You can apply it to

your programs, too.



When we speak of free software, we are referring to freedom, not price. Our

General Public Licenses are designed to make sure that you have the freedom to

distribute copies of free software (and charge for this service if you wish),

that you receive source code or can get it if you want it, that you can change

the software or use pieces of it in new free programs; and that you know you

can do these things.



To protect your rights, we need to make restrictions that forbid anyone to deny

you these rights or to ask you to surrender the rights. These restrictions

translate to certain responsibilities for you if you distribute copies of the

software, or if you modify it.



For example, if you distribute copies of such a program, whether gratis or for

a fee, you must give the recipients all the rights that you have. You must

make sure that they, too, receive or can get the source code. And you must

show them these terms so they know their rights.



We protect your rights with two steps: (1) copyright the software, and (2)

offer you this license which gives you legal permission to copy, distribute

and/or modify the software.



Also, for each author's protection and ours, we want to make certain that

everyone understands that there is no warranty for this free software. If the

software is modified by someone else and passed on, we want its recipients to

know that what they have is not the original, so that any problems introduced

by others will not reflect on the original authors' reputations.



Finally, any free program is threatened constantly by software patents. We

wish to avoid the danger that redistributors of a free program will

individually obtain patent licenses, in effect making the program proprietary.

To prevent this, we have made it clear that any patent must be licensed for

everyone's free use or not licensed at all.



The precise terms and conditions for copying, distribution and modification

follow.



TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION



0. This License applies to any program or other work which contains a notice

placed by the copyright holder saying it may be distributed under the terms of

this General Public License. The "Program", below, refers to any such program

or work, and a "work based on the Program" means either the Program or any

derivative work under copyright law: that is to say, a work containing the

Program or a portion of it, either verbatim or with modifications and/or

translated into another language. (Hereinafter, translation is included

without limitation in the term "modification".) Each licensee is addressed as

"you".



Activities other than copying, distribution and modification are not covered by

this License; they are outside its scope. The act of running the Program is

not restricted, and the output from the Program is covered only if its contents

constitute a work based on the Program (independent of having been made by

running the Program). Whether that is true depends on what the Program does.



1. You may copy and distribute verbatim copies of the Program's source code as

you receive it, in any medium, provided that you conspicuously and

appropriately publish on each copy an appropriate copyright notice and

disclaimer of warranty; keep intact all the notices that refer to this License

and to the absence of any warranty; and give any other recipients of the

Program a copy of this License along with the Program.



You may charge a fee for the physical act of transferring a copy, and you may

at your option offer warranty protection in exchange for a fee.



2. You may modify your copy or copies of the Program or any portion of it, thus

forming a work based on the Program, and copy and distribute such modifications

or work under the terms of Section 1 above, provided that you also meet all of

these conditions:



a) You must cause the modified files to carry prominent notices stating

that you changed the files and the date of any change.



b) You must cause any work that you distribute or publish, that in whole or

in part contains or is derived from the Program or any part thereof, to be

licensed as a whole at no charge to all third parties under the terms of

this License.



c) If the modified program normally reads commands interactively when run,

you must cause it, when started running for such interactive use in the

most ordinary way, to print or display an announcement including an

appropriate copyright notice and a notice that there is no warranty (or

else, saying that you provide a warranty) and that users may redistribute

the program under these conditions, and telling the user how to view a copy

of this License. (Exception: if the Program itself is interactive but does

not normally print such an announcement, your work based on the Program is

not required to print an announcement.)



These requirements apply to the modified work as a whole. If identifiable

sections of that work are not derived from the Program, and can be reasonably

considered independent and separate works in themselves, then this License, and

its terms, do not apply to those sections when you distribute them as separate

works. But when you distribute the same sections as part of a whole which is a

work based on the Program, the distribution of the whole must be on the terms

of this License, whose permissions for other licensees extend to the entire

whole, and thus to each and every part regardless of who wrote it.



Thus, it is not the intent of this section to claim rights or contest your

rights to work written entirely by you; rather, the intent is to exercise the

right to control the distribution of derivative or collective works based on

the Program.



In addition, mere aggregation of another work not based on the Program with the

Program (or with a work based on the Program) on a volume of a storage or

distribution medium does not bring the other work under the scope of this

License.



3. You may copy and distribute the Program (or a work based on it, under

Section 2) in object code or executable form under the terms of Sections 1 and

2 above provided that you also do one of the following:



a) Accompany it with the complete corresponding machine-readable source

code, which must be distributed under the terms of Sections 1 and 2 above

on a medium customarily used for software interchange; or,



b) Accompany it with a written offer, valid for at least three years, to

give any third party, for a charge no more than your cost of physically

performing source distribution, a complete machine-readable copy of the

corresponding source code, to be distributed under the terms of Sections 1

and 2 above on a medium customarily used for software interchange; or,



c) Accompany it with the information you received as to the offer to

distribute corresponding source code. (This alternative is allowed only

for noncommercial distribution and only if you received the program in

object code or executable form with such an offer, in accord with

Subsection b above.)



The source code for a work means the preferred form of the work for making

modifications to it. For an executable work, complete source code means all

the source code for all modules it contains, plus any associated interface

definition files, plus the scripts used to control compilation and installation

of the executable. However, as a special exception, the source code

distributed need not include anything that is normally distributed (in either

source or binary form) with the major components (compiler, kernel, and so on)

of the operating system on which the executable runs, unless that component

itself accompanies the executable.



If distribution of executable or object code is made by offering access to copy

from a designated place, then offering equivalent access to copy the source

code from the same place counts as distribution of the source code, even though

third parties are not compelled to copy the source along with the object code.



4. You may not copy, modify, sublicense, or distribute the Program except as

expressly provided under this License. Any attempt otherwise to copy, modify,

sublicense or distribute the Program is void, and will automatically terminate

your rights under this License. However, parties who have received copies, or

rights, from you under this License will not have their licenses terminated so

long as such parties remain in full compliance.



5. You are not required to accept this License, since you have not signed it.

However, nothing else grants you permission to modify or distribute the Program

or its derivative works. These actions are prohibited by law if you do not

accept this License. Therefore, by modifying or distributing the Program (or

any work based on the Program), you indicate your acceptance of this License to

do so, and all its terms and conditions for copying, distributing or modifying

the Program or works based on it.



6. Each time you redistribute the Program (or any work based on the Program),

the recipient automatically receives a license from the original licensor to

copy, distribute or modify the Program subject to these terms and conditions.

You may not impose any further restrictions on the recipients' exercise of the

rights granted herein. You are not responsible for enforcing compliance by

third parties to this License.



7. If, as a consequence of a court judgment or allegation of patent

infringement or for any other reason (not limited to patent issues), conditions

are imposed on you (whether by court order, agreement or otherwise) that

contradict the conditions of this License, they do not excuse you from the

conditions of this License. If you cannot distribute so as to satisfy

simultaneously your obligations under this License and any other pertinent

obligations, then as a consequence you may not distribute the Program at all.

For example, if a patent license would not permit royalty-free redistribution

of the Program by all those who receive copies directly or indirectly through

you, then the only way you could satisfy both it and this License would be to

refrain entirely from distribution of the Program.



If any portion of this section is held invalid or unenforceable under any

particular circumstance, the balance of the section is intended to apply and

the section as a whole is intended to apply in other circumstances.



It is not the purpose of this section to induce you to infringe any patents or

other property right claims or to contest validity of any such claims; this

section has the sole purpose of protecting the integrity of the free software

distribution system, which is implemented by public license practices. Many

people have made generous contributions to the wide range of software

distributed through that system in reliance on consistent application of that

system; it is up to the author/donor to decide if he or she is willing to

distribute software through any other system and a licensee cannot impose that

choice.



This section is intended to make thoroughly clear what is believed to be a

consequence of the rest of this License.



8. If the distribution and/or use of the Program is restricted in certain

countries either by patents or by copyrighted interfaces, the original

copyright holder who places the Program under this License may add an explicit

geographical distribution limitation excluding those countries, so that

distribution is permitted only in or among countries not thus excluded. In

such case, this License incorporates the limitation as if written in the body

of this License.



9. The Free Software Foundation may publish revised and/or new versions of the

General Public License from time to time. Such new versions will be similar in

spirit to the present version, but may differ in detail to address new problems

or concerns.



Each version is given a distinguishing version number. If the Program

specifies a version number of this License which applies to it and "any later

version", you have the option of following the terms and conditions either of

that version or of any later version published by the Free Software Foundation.

If the Program does not specify a version number of this License, you may

choose any version ever published by the Free Software Foundation.



10. If you wish to incorporate parts of the Program into other free programs

whose distribution conditions are different, write to the author to ask for

permission. For software which is copyrighted by the Free Software Foundation,

write to the Free Software Foundation; we sometimes make exceptions for this.

Our decision will be guided by the two goals of preserving the free status of

all derivatives of our free software and of promoting the sharing and reuse of

software generally.



NO WARRANTY



11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR

THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE

STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE

PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,

INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND

FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND

PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE,

YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.



12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL

ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE

PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY

GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR

INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA

BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A

FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER

OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.



END OF TERMS AND CONDITIONS



How to Apply These Terms to Your New Programs



If you develop a new program, and you want it to be of the greatest possible

use to the public, the best way to achieve this is to make it free software

which everyone can redistribute and change under these terms.



To do so, attach the following notices to the program. It is safest to attach

them to the start of each source file to most effectively convey the exclusion

of warranty; and each file should have at least the "copyright" line and a

pointer to where the full notice is found.



One line to give the program's name and a brief idea of what it does.



Copyright (C)



This program is free software; you can redistribute it and/or modify it

under the terms of the GNU General Public License as published by the Free

Software Foundation; either version 2 of the License, or (at your option)

any later version.



This program is distributed in the hope that it will be useful, but WITHOUT

ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or

FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for

more details.



You should have received a copy of the GNU General Public License along

with this program; if not, write to the Free Software Foundation, Inc.,

51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.



Also add information on how to contact you by electronic and paper mail.



If the program is interactive, make it output a short notice like this when it

starts in an interactive mode:



Gnomovision version 69, Copyright (C) year name of author Gnomovision comes

with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free

software, and you are welcome to redistribute it under certain conditions;

type 'show c' for details.



The hypothetical commands 'show w' and 'show c' should show the appropriate

parts of the General Public License. Of course, the commands you use may be

called something other than 'show w' and 'show c'; they could even be

mouse-clicks or menu items--whatever suits your program.



You should also get your employer (if you work as a programmer) or your school,

if any, to sign a "copyright disclaimer" for the program, if necessary. Here

is a sample; alter the names:



Yoyodyne, Inc., hereby disclaims all copyright interest in the program

'Gnomovision' (which makes passes at compilers) written by James Hacker.



signature of Ty Coon, 1 April 1989



Ty Coon, President of Vice



This General Public License does not permit incorporating your program into

proprietary programs. If your program is a subroutine library, you may

consider it more useful to permit linking proprietary applications with the

library. If this is what you want to do, use the GNU Library General Public

License instead of this License.
+
+ +
+
Pass-Through Information:
+ + + + +
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

- Redistribution of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

- Redistribution in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.

Neither the name of Sun Microsystems, Inc. or the names of
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.

This software is provided "AS IS," without a warranty of any
kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.

You acknowledge that this software is not designed or intended for
use in the design, construction, operation or maintenance of any
nuclear facility.
+
+
+ +
+
Copyrights:
+ + + + +
+ Alex Dupre; Alex Geller; Arthur van Hoff; Copyright (c) 1994, 2004, Oracle and/or its affiliates; Copyright (c) 1994, 2010, Oracle and/or its affiliates; Copyright (c) 2005 Sun Microsystems, Inc.; Copyright (c) 2010 ZXing; Copyright (c) 2010 ZXing authors; Copyright (c) 2010-2014 University of Manchester; Copyright (c) 2010-2015 Stian Soiland-Reyes; Copyright (c) 2012 ZXing; Copyright (c) 2012 ZXing authors; Copyright (c) 2015 Peter Hull; Copyright 2007 ZXing; Copyright 2007 ZXing authors; Copyright 2008 ZXing; Copyright 2008 ZXing authors; Copyright 2009 ZXing; Copyright 2009 ZXing authors; Copyright 2010 ZXing; Copyright 2010 ZXing authors; Copyright 2012 ZXing; Copyright 2012 ZXing authors; Copyright 2013 ZXing; Copyright 2013 ZXing authors; Daniel Switkin; Daniel Switkin <dswitkin@google.com>; David Olivier; Frank Yellin; Guenther Grau; Mariusz Dabrowski; Rustam Abdullaev; SITA Lab (kevin.osullivan@sita.aero); Satoru Takabayashi; Sean Owen; William Rucklidge; alasdair@google.com; bbrown@google.com; creatale GmbH (christoph.schulz@creatale.de); dswitkin@google.com; encoding.spec.whatwg.org; satorux@google.com +
+
+
+
+


LICENSE CONDITIONS AND COPYRIGHT NOTICES

+

Open Source Software: - classnames (npm) - 2.5.1

+

Enclosed you will find the license conditions and + copyright notices applicable for + - classnames (npm) - 2.5.1

+
+ +
License conditions:
+
+ + + + +
The MIT License

Copyright (c) <year> <copyright holders>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ +
+ +
+
Copyrights:
+ + + + +
+ Copyright (c) 2018 Dave Keen <http://www.keendevelopment.ch> Adi Dahiya <https://github.com/adidahiya> Jason Killian <https://github.com/JKillian>; Copyright (c) 2018 Jed Watson +
+
+
+
+


LICENSE CONDITIONS AND COPYRIGHT NOTICES

+

Open Source Software: - ts-custom-error (npm) - 3.3.1

+

Enclosed you will find the license conditions and + copyright notices applicable for + - ts-custom-error (npm) - 3.3.1

+
+ +
License conditions:
+
+ + + + +
The MIT License

Copyright (c) <year> <copyright holders>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ +
+ +
+
Copyrights:
+ + + + +
+ Adrien Gibrat <adrien.gibrat@gmail.com>; Copyright (c) 2019 Adrien Gibrat https://github.com/adriengibrat +
+
+
+
+ +

+ Portions generated with ScanCode and provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. No content created from ScanCode should be considered or used as legal advice. Consult an Attorney for any legal advice. ScanCode is a free software code scanning tool from nexB Inc. and others. + Visit https://github.com/nexB/scancode-toolkit/ for support and download. +

+ + + \ No newline at end of file