From 7a068e9ae762f44c3df71f251a4a1f413e6cf925 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Olle=20M=C3=A5nsson?=
<31876997+ollema@users.noreply.github.com>
Date: Mon, 2 Dec 2024 22:16:54 +0100
Subject: [PATCH 01/25] add components and some initial documentation
---
docs/package.json | 13 +-
docs/src/content/components/BarqodeCapture.md | 87 ++++++
.../src/content/components/BarqodeDropZone.md | 110 +++++++
docs/src/content/components/BarqodeStream.md | 226 ++++++++++++++
docs/src/content/components/button.md | 50 ---
docs/src/content/components/callout.md | 88 ------
docs/src/content/configuration/navigation.md | 19 --
docs/src/content/configuration/theme.md | 52 ---
docs/src/content/getting-started.md | 95 ++----
docs/src/content/index.md | 62 +++-
.../components/demos/barqode-capture.svelte | 33 ++
.../components/demos/barqode-drop-zone.svelte | 50 +++
.../components/demos/barqode-stream.svelte | 75 +++++
docs/src/lib/navigation.ts | 16 +-
docs/src/lib/site-config.ts | 2 +-
docs/src/routes/api/search.json/search.json | 86 +----
docs/velite.config.js | 2 +-
package.json | 22 +-
packages/barqode/package.json | 27 +-
packages/barqode/src/app.html | 12 +
.../src/lib/components/barqode-capture.svelte | 29 ++
.../lib/components/barqode-drop-zone.svelte | 76 +++++
.../src/lib/components/barqode-stream.svelte | 259 +++++++++++++++
.../barqode/src/lib/components/callforth.ts | 49 +++
packages/barqode/src/lib/components/camera.ts | 295 ++++++++++++++++++
packages/barqode/src/lib/components/errors.ts | 35 +++
.../barqode/src/lib/components/global.d.ts | 5 +
.../barqode/src/lib/components/scanner.ts | 226 ++++++++++++++
.../src/lib/components/shimGetUserMedia.ts | 32 ++
packages/barqode/src/lib/components/types.ts | 143 +++++++++
packages/barqode/src/lib/components/util.ts | 51 +++
packages/barqode/src/lib/index.ts | 6 +-
pnpm-lock.yaml | 141 ++++++---
33 files changed, 2038 insertions(+), 436 deletions(-)
create mode 100644 docs/src/content/components/BarqodeCapture.md
create mode 100644 docs/src/content/components/BarqodeDropZone.md
create mode 100644 docs/src/content/components/BarqodeStream.md
delete mode 100644 docs/src/content/components/button.md
delete mode 100644 docs/src/content/components/callout.md
delete mode 100644 docs/src/content/configuration/navigation.md
delete mode 100644 docs/src/content/configuration/theme.md
create mode 100644 docs/src/lib/components/demos/barqode-capture.svelte
create mode 100644 docs/src/lib/components/demos/barqode-drop-zone.svelte
create mode 100644 docs/src/lib/components/demos/barqode-stream.svelte
create mode 100644 packages/barqode/src/app.html
create mode 100644 packages/barqode/src/lib/components/barqode-capture.svelte
create mode 100644 packages/barqode/src/lib/components/barqode-drop-zone.svelte
create mode 100644 packages/barqode/src/lib/components/barqode-stream.svelte
create mode 100644 packages/barqode/src/lib/components/callforth.ts
create mode 100644 packages/barqode/src/lib/components/camera.ts
create mode 100644 packages/barqode/src/lib/components/errors.ts
create mode 100644 packages/barqode/src/lib/components/global.d.ts
create mode 100644 packages/barqode/src/lib/components/scanner.ts
create mode 100644 packages/barqode/src/lib/components/shimGetUserMedia.ts
create mode 100644 packages/barqode/src/lib/components/types.ts
create mode 100644 packages/barqode/src/lib/components/util.ts
diff --git a/docs/package.json b/docs/package.json
index d31cddf..5bc2949 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -16,18 +16,19 @@
"devDependencies": {
"@svecodocs/kit": "^0.0.5",
"@sveltejs/adapter-cloudflare": "^4.8.0",
- "@sveltejs/kit": "^2.0.0",
- "@sveltejs/vite-plugin-svelte": "^4.0.0",
+ "@sveltejs/kit": "^2.9.0",
+ "@sveltejs/vite-plugin-svelte": "^4.0.2",
"@tailwindcss/vite": "4.0.0-beta.4",
+ "barqode": "workspace:^",
"mdsx": "^0.0.6",
"phosphor-svelte": "^3.0.0",
- "svelte": "^5.2.11",
- "svelte-check": "^4.0.0",
+ "svelte": "^5.4.0",
+ "svelte-check": "^4.1.0",
"svelte-preprocess": "^6.0.3",
"tailwindcss": "4.0.0-beta.4",
- "typescript": "^5.0.0",
+ "typescript": "^5.7.2",
"velite": "^0.2.1",
- "vite": "^5.0.11"
+ "vite": "^5.4.11"
},
"private": true
}
diff --git a/docs/src/content/components/BarqodeCapture.md b/docs/src/content/components/BarqodeCapture.md
new file mode 100644
index 0000000..e07a27c
--- /dev/null
+++ b/docs/src/content/components/BarqodeCapture.md
@@ -0,0 +1,87 @@
+---
+title: BarqodeCapture
+description: File input with camera support on mobile.
+section: Components
+---
+
+
+
+The `BarqodeCapture` component is a simple file input with the `capture` attribute set to `environment` which allows users to take a picture with their camera.
+
+## Demo
+
+
+
+## Props
+
+### `formats`
+
+Type: [`BarcodeFormat[]`](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector)
+
+Default: `["qr_code"]`
+
+Configure the barcode formats to detect. By default, only QR codes are detected.
+
+If you want to detect multiple formats, pass an array of formats:
+
+```svelte
+
+```
+
+Under the hood, the standard [BarcodeDetector API](https://developer.mozilla.org/en-US/docs/Web/API/BarcodeDetector) is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation.
+
+Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format `'qr_code'` but the you select the formats `['qr_code', 'aztec']`.
+
+### `onDetect`
+
+Type: `(detectedCodes: DetectedBarcode[]) => void`
+
+Callback function that is called when a barcode is detected.
+
+It receives an array of [detected barcodes](https://developer.mozilla.org/en-US/docs/Web/API/BarcodeDetector/detect#return_value), one callback per image uploaded.
+
+If not barcode is detected, the array will be empty.
+
+### Other props
+
+The `BarqodeCapture` component accepts all attributes that a standard `input` element accepts.
+
+By default, the following attributes are set:
+
+- `type="file"`. This is required to make the input a file input. You should not change this.
+- `name="image"`. This is the name of the file input.
+- `accept="image/*"`. This restricts the file types that can be uploaded to images.
+- `capture="environment"`. This tells the browser to open the camera when the input is clicked on mobile devices. You can choose between `user` and `environment`, which opens the front and back camera respectively. You can also disable this functionality by setting it to `null`.
+- `multiple`. This allows the user to upload multiple files at once. You can disable this by settings this to `false`.
+
+## Usage
+
+```svelte
+
+
+
+
+
+ Last detected: {result}
+
+
+
+```
+
+## Browser Support
+
+This component depends on the [File Reader API](https://developer.mozilla.org/en-US/docs/Web/API/FileReader) which is widely supported in modern browsers.
diff --git a/docs/src/content/components/BarqodeDropZone.md b/docs/src/content/components/BarqodeDropZone.md
new file mode 100644
index 0000000..f6d4ea0
--- /dev/null
+++ b/docs/src/content/components/BarqodeDropZone.md
@@ -0,0 +1,110 @@
+---
+title: BarqodeDropZone
+description: File input with camera support on mobile.
+section: Components
+---
+
+
+
+You can drag-and-drop image files from your desktop or images embedded into other web pages anywhere in the area the component occupies. The images are directly scanned and positive results are indicated by the `onDetect` callback.
+
+## Demo
+
+
+
+## Props
+
+### `formats`
+
+Type: [`BarcodeFormat[]`](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector)
+
+Default: `["qr_code"]`
+
+Configure the barcode formats to detect. By default, only QR codes are detected.
+
+If you want to detect multiple formats, pass an array of formats:
+
+```svelte
+
+```
+
+Under the hood, the standard [BarcodeDetector API](https://developer.mozilla.org/en-US/docs/Web/API/BarcodeDetector) is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation.
+
+Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format `'qr_code'` but the you select the formats `['qr_code', 'aztec']`.
+
+### `onDetect`
+
+Type: `(detectedCodes: DetectedBarcode[]) => void`
+
+Callback function that is called when a barcode is detected.
+
+It receives an array of [detected barcodes](https://developer.mozilla.org/en-US/docs/Web/API/BarcodeDetector/detect#return_value), one callback per image dropped.
+
+If not barcode is detected, the array will be empty.
+
+### `onDragover`
+
+Type: `(isDraggingOver: boolean) => void`
+
+Callback function that is called when a file is dragged over the drop zone.
+
+### `onError`
+
+Type: `(error: Error) => void`
+
+Callback function that is called when an error occurs.
+
+TODO: insert link to errors.
+
+## Usage
+
+```svelte
+
+
+
+ Drop an image here to detect QR-codes
+
+
+
+ Last detected: {result}
+
+
+
+```
+
+## Browser Support
+
+This component depends on the [File Reader API](https://developer.mozilla.org/en-US/docs/Web/API/FileReader) which is widely supported in modern browsers.
diff --git a/docs/src/content/components/BarqodeStream.md b/docs/src/content/components/BarqodeStream.md
new file mode 100644
index 0000000..0d3ec06
--- /dev/null
+++ b/docs/src/content/components/BarqodeStream.md
@@ -0,0 +1,226 @@
+---
+title: BarqodeStream
+description: Continuously scans frames from a camera stream.
+section: Components
+---
+
+
+
+The `BarqodeStream` component continuously scans frames from a camera stream and detects barcodes in real-time.
+
+## Demo
+
+
+
+## Props
+
+### `constraints`
+
+Type: [`MediaTrackConstraints`](https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints)
+
+Default: `{ video: { facingMode: "environment" } }`
+
+Configure the the various camera options, for example whether to use front or rear camera.
+
+The object must be of type `MediaTrackConstraints`.
+
+The object is passed as-is to `getUserMedia`, which is the API call for requesting a camera stream:
+
+```js
+navigator.mediaDevices.getUserMedia({
+ audio: false,
+ video: the_constraint_object_you_provide,
+});
+```
+
+When `constraints` is updated, a new camera stream is requested which triggers the `onCameraOn` callback again. You can catch errors with the `onError` callback. An error can occur when you try to use the front camera on a device that doesn't have one for example.
+
+### `formats`
+
+Type: [`BarcodeFormat[]`](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector)
+
+Default: `["qr_code"]`
+
+Configure the barcode formats to detect. By default, only QR codes are detected.
+
+If you want to detect multiple formats, pass an array of formats:
+
+```svelte
+
+```
+
+
+
+Don't select more barcode formats than needed.
+
+Scanning becomes more expensive the more formats you select.
+
+
+
+Under the hood, the standard [BarcodeDetector API](https://developer.mozilla.org/en-US/docs/Web/API/BarcodeDetector) is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation.
+
+Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format `'qr_code'` but the you select the formats `['qr_code', 'aztec']`.
+
+### `paused`
+
+Type: `boolean` (bindable)
+
+Default: `false`
+
+Whether the camera stream is or should be paused. Bindable, which means that you can pause/unpause the stream from outside the component.
+
+Pausing the stream by setting `paused` to `true` is useful if you want to show some microinteraction after successful scans. When the you set it to `false`, the camera stream will be restarted and the `onCameraOn` callback function will be triggered again.
+
+### `torch`
+
+Type: `boolean`
+
+Default: `false`
+
+Turn the camera flashlight on or off.
+
+This is not consistently supported by all devices and browsers. Support can even vary on the same device with the same browser. For example the rear camera often has a flashlight but the front camera does not.
+
+We can only tell if flashlight control is supported once the camera is loaded and the `onCameraOn` callback has been called. At the moment, enabling the torch may silently fail on unsupported devices, but in the `onCameraOn` callback payload you can access the `MediaTrackCapabilities` object, from which you can determine if the torch is supported.
+
+The camera stream must be reloaded when turning the torch on or off. That means the `onCameraOn` event will be emitted again.
+
+### `track`
+
+Type: `(detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) => void`
+
+Callback function that can be used to visually highlight detected barcodes.
+
+A transparent canvas is overlaid on top of the camera stream. The `track` function is used to draw on this canvas.
+
+It receives an array of [detected barcodes](https://developer.mozilla.org/en-US/docs/Web/API/BarcodeDetector/detect#return_value) and a [CanvasRenderingContext2D](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D) as the second argument.
+
+Note that when `track` is set the scanning frequency has to be increased. So if you want to go easy on your target device you might not want to enable tracking.
+
+
+
+The `track` function is called for every frame. It is important to keep the function as performant as possible.
+
+This can lead to performance issues on low-end devices and memory leaks if not handled correctly.
+
+
+
+### `onCameraOn`
+
+Type: `(capabilities: MediaTrackCapabilities) => void`
+
+Callback function that is called when the camera stream is successfully loaded.
+
+It might take a while before the component is ready and the scanning process starts. The user has to be asked for camera access permission first and the camera stream has to be loaded.
+
+If you want to show a loading indicator, you can wait for this callback to be called. It is called as soon as the camera start streaming.
+
+The callback receives the a promise which resolves with the cameras [`MediaTrackCapabilities`](https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackCapabilities) when everything is ready.
+
+### `onError`
+
+Type: `(error: Error) => void`
+
+Callback function that is called when an error occurs.
+
+TODO: insert link to errors.
+
+### `onCameraOff`
+
+Type: `() => void`
+
+Callback function that is called when the camera stream is stopped.
+
+This can happen when the camera constraints are modified, for example when switching between front and rear camera or when turning the torch on or off.
+
+### `onDetect`
+
+Type: `(detectedCodes: DetectedBarcode[]) => void`
+
+Callback function that is called when a barcode is detected.
+
+It receives an array of [detected barcodes](https://developer.mozilla.org/en-US/docs/Web/API/BarcodeDetector/detect#return_value).
+
+
+
+If you scan the same barcode multiple times in a row, `onDetect` is still only called once. When you hold a barcode in the camera, frames are actually decoded multiple times a second but you don't want to be flooded with callbacks that often. That's why the last decoded QR code is always cached and only new results are propagated. However, changing the value of `paused` resets this internal cache.
+
+
+
+## Usage
+
+```svelte
+
+
+
+
+ {#if loading}
+ Loading...
+ {/if}
+
+
+
+
+ Last detected: {result}
+
+
+
+```
+
+## Browser Support
+
+This component depends on the [Media Capture and Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Media_Capture_and_Streams_API) which is widely supported in modern browsers.
diff --git a/docs/src/content/components/button.md b/docs/src/content/components/button.md
deleted file mode 100644
index 6aaa66f..0000000
--- a/docs/src/content/components/button.md
+++ /dev/null
@@ -1,50 +0,0 @@
----
-title: Button
-description: A button component to use in examples and documentation.
-section: Components
----
-
-
-
-## Usage
-
-```svelte title="document.md"
-
-
-Default
-Brand
-Ghost
-Outline
-Subtle
-Link
-```
-
-## Example
-
-### Default Size
-
-
- Default
- Brand
- Destructive
- Ghost
- Outline
- Subtle
- Link
-
-
-### Small Size
-
-
- Default
- Brand
- Destructive
- Ghost
- Outline
- Subtle
- Link
-
diff --git a/docs/src/content/components/callout.md b/docs/src/content/components/callout.md
deleted file mode 100644
index a7457ff..0000000
--- a/docs/src/content/components/callout.md
+++ /dev/null
@@ -1,88 +0,0 @@
----
-title: Callout
-description: A callout component to highlight important information.
-section: Components
----
-
-
-
-Callouts (also known as _admonitions_) are used to highlight a block of text. There are five types of callouts available: `'note'`, `'warning'`, `'danger'`, `'tip'`, and `'success'`.
-
-You can override the default icon for the callout by passing a component via the `icon` prop.
-
-## Usage
-
-```svelte title="document.md"
-
-
-
-
- This is a note, used to highlight important information or provide additional context. You can use
- markdown in here as well! Just ensure you include a space between the component and the content in
- your Markdown file.
-
-
-```
-
-## Examples
-
-### Warning
-
-
-
-This is an example of a warning callout.
-
-
-
-### Note
-
-
-
-This is an example of a note callout.
-
-
-
-### Danger
-
-
-
-This is an example of a danger callout.
-
-
-
-### Tip
-
-
-
-This is an example of a tip callout.
-
-
-
-### Success
-
-
-
-This is an example of a success callout.
-
-
-
-### Custom Icon
-
-
-
-This is an example of a note callout with a custom icon.
-
-
-
-### Custom Title
-
-
-
-This is an example of a warning callout with a custom title.
-
-
diff --git a/docs/src/content/configuration/navigation.md b/docs/src/content/configuration/navigation.md
deleted file mode 100644
index 506ec69..0000000
--- a/docs/src/content/configuration/navigation.md
+++ /dev/null
@@ -1,19 +0,0 @@
----
-title: Navigation
-description: Learn how to customize the navigation in your Svecodocs project.
-section: Configuration
----
-
-Navigation is a key component of every site, documenting the structure of your site and providing a clear path for users to navigate through your content.
-
-Svecodocs comes with a navigation structure that is designed to be flexible and customizable. Each page in your site should have a corresponding navigation item, and the navigation items should be nested according to their hierarchy.
-
-## Navigation Structure
-
-### Anchors
-
-Anchors are links that are displayed at the top of the sidebar and typically used to either highlight important information or provide quick access to linked content.
-
-### Sections
-
-Sections are used to group related navigation items together. They are typically used to organize content into different categories, such as "Components", "Configuration", and "Utilities".
diff --git a/docs/src/content/configuration/theme.md b/docs/src/content/configuration/theme.md
deleted file mode 100644
index 49b248b..0000000
--- a/docs/src/content/configuration/theme.md
+++ /dev/null
@@ -1,52 +0,0 @@
----
-title: Theme
-description: Learn how to customize the theme in your Svecodocs project.
-section: Configuration
----
-
-The theme determines the branded color scheme for your site. A theme for each of the TailwindCSS colors is provided by the `@svecodocs/kit` package. Each theme has been designed to present well in both light and dark mode.
-
-## Using a theme
-
-To use a theme, import the theme file into your `src/app.css` file _before_ importing the `@svecodocs/kit/globals.css` file.
-
-```css
-/* @import "@svecodocs/kit/theme-orange.css"; */
-@import "@svecodocs/kit/theme-emerald.css";
-@import "@svecodocs/kit/globals.css";
-```
-
-It's not recommended to customize the theme to maintain consistency across the UI components that are provided by Svecodocs and align with the provided themes.
-
-## Available themes
-
-| Theme name | Import path |
-| ---------- | ---------------------------------- |
-| orange | `@svecodocs/kit/theme-orange.css` |
-| green | `@svecodocs/kit/theme-green.css` |
-| blue | `@svecodocs/kit/theme-blue.css` |
-| purple | `@svecodocs/kit/theme-purple.css` |
-| pink | `@svecodocs/kit/theme-pink.css` |
-| lime | `@svecodocs/kit/theme-lime.css` |
-| yellow | `@svecodocs/kit/theme-yellow.css` |
-| cyan | `@svecodocs/kit/theme-cyan.css` |
-| teal | `@svecodocs/kit/theme-teal.css` |
-| violet | `@svecodocs/kit/theme-violet.css` |
-| amber | `@svecodocs/kit/theme-amber.css` |
-| red | `@svecodocs/kit/theme-red.css` |
-| sky | `@svecodocs/kit/theme-sky.css` |
-| emerald | `@svecodocs/kit/theme-emerald.css` |
-| fuchsia | `@svecodocs/kit/theme-fuchsia.css` |
-| rose | `@svecodocs/kit/theme-rose.css` |
-
-## Tailwind Variables
-
-Svecodocs uses TailwindCSS to style the UI components and provides a set of Tailwind variables that can be used to style your examples/custom components.
-
-### Gray
-
-We override the TailwindCSS `gray` color scale to provide our own grays.
-
-### Brand
-
-You can use the `brand` color to use the brand color of your project.
diff --git a/docs/src/content/getting-started.md b/docs/src/content/getting-started.md
index 564de98..c755c5e 100644
--- a/docs/src/content/getting-started.md
+++ b/docs/src/content/getting-started.md
@@ -1,82 +1,47 @@
---
title: Getting Started
-description: A quick guide to get started using Svecodocs
+description: A quick guide to get started using barqode
section: Overview
---
-
-
-The following guide will walk you through the process of getting a Svecodocs project up and running.
+The following guide will walk you through installing and setting up the barqode components in your Svelte project.
-## Clone the starter template
+## Installation
-Clone the Svecodocs starter template:
+Install the package using your preferred package manager:
```bash
-pnpx degit svecosystem/svecodocs/starter
-```
-
-## Navigation
-
-The starter template comes with a basic navigation structure to get your started. To customize the navigation, adjust the `src/lib/navigation.ts` file.
-
-```ts
-import { createNavigation } from "@svecodocs/kit";
-
-export const navigation = createNavigation({
- // Customize the navigation here
-});
-```
-
-## Site config
-
-The site config is used to configure site-wide settings, such as the title, description, keywords, ogImage, and other metadata.
-
-The config is located in the `src/lib/site-config.ts` file.
-
-```ts
-import { defineSiteConfig } from "@svecodocs/kit";
-
-export const siteConfig = defineSiteConfig({
- title: "Svecodocs",
- description: "A SvelteKit docs starter template",
- keywords: ["sveltekit", "docs", "starter", "template"],
- ogImage: {
- url: "https://docs.sveco.dev/og.png",
- height: 630,
- width: 1200,
- },
-});
+npm install barqode
+# or
+pnpm add barqode
+# or
+yarn add barqode
```
-### Per-Route Site Config
-
-You can override any part of the site config on a per-route basis using the `useSiteConfig` hook.
+## Basic Usage
-
-This feature is still being worked on.
-
+The simplest way to use the library is with the `BarqodeStream` component for live scanning:
-## Theme
+```svelte
+
-```css {1-2}
-/* @import "@svecodocs/kit/themes/orange.css"; */
-@import "@svecodocs/kit/themes/emerald.css";
-@import "@svecodocs/kit/globals.css";
+
+
+
+
+
```
-## Logo
-
-To customize the logo displayed in the sidebar header, head to the `src/routes/(docs)/+layout.svelte` file and adjust the contents of the `logo` snippet. If the logo has a light and dark version, ensure to handle those similarly to the default Svecosystem logo.
-
-```svelte title="src/routes/(docs)/+layout.svelte"
-{#snippet logo()}
-
-
- The project name here
-{/snippet}
-```
+For detailed information about each component's capabilities and options, refer to their respective API documentation pages.
diff --git a/docs/src/content/index.md b/docs/src/content/index.md
index 36df5fc..da049fb 100644
--- a/docs/src/content/index.md
+++ b/docs/src/content/index.md
@@ -1,26 +1,58 @@
---
title: Introduction
-description: What exactly is Svecodocs?
+description: What is Barqode?
section: Overview
---
-
+Barqode provides a set of Svelte components for detecting and decoding QR codes and various other barcode formats right in the browser. It's a comprehensive solution that supports both camera streams and static image processing.
-After spending countless hours building documentation sites for various projects, we decided to build a docs package/starter template that we can use for future projects. This project is a result of that effort.
+Barqode started out as a port of [`vue-qrcode-reader`](https://github.com/gruhn/vue-qrcode-reader).
-Svecodocs is a starting point/utility library for building documentation sites under the [Svecosystem](https://github.com/svecosystem) umbrella. The code is open source, but it's built and maintained for our own specific needs, so we won't be accepting any public feature requests.
+## Components
-You are more than welcome to fork the project and customize it to your own needs.
+- **`BarqodeStream`** - continuously scans frames from a camera stream.
+- **`BarqodeDropZone`** - drag & drop image files or web images.
+- **`BarqodeCapture`** - traditional file upload field input with camera support.
## Features
-- **Markdown-based docs**. Write docs using Markdown and Svelte components
-- **Light and dark mode**. Toggle between light and dark mode
-- **Syntax highlighting**. Code blocks are automatically highlighted
-- **SEO-friendly**. Meta tags and Open Graph support out of the box
-- **Pre-built components**. Tabs, callouts, and more to use within the documentation
-- **Custom unified plugins**. Custom remark and rehype plugins to give more flexibility over the rendered HTML
-- **shadcn-svelte**. Beautifully designed Svelte components
-- **Tailwind v4**. Tailwind CSS v4 is used for styling
+- **Real-time scanning**. Detect codes from live camera stream.
+- **Multiple formats**. Support for QR codes and various barcode standards.
+- **Visual feedback**. Customizable canvas based tracking of detected codes.
+- **Cross-browser**. Works across modern browsers with a [WebAssembly-based polyfill](https://github.com/Sec-ant/barcode-detector) if needed.
+- **Camera selection**. Choose between front/rear cameras.
+- **Torch control**. Control device flashlight where supported.
+- **Responsive**. Components adapt to fill available space.
+- **Error handling**. Comprehensive error handling for camera/detection issues.
+
+## Usage Example
+
+```svelte
+
+
+
+
+
+
+
+```
+
+## Browser Support
+
+The components rely primarily on the [Barcode Detection API](https://developer.mozilla.org/en-US/docs/Web/API/Barcode_Detection_API) and [Media Capture and Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Media_Capture_and_Streams_API), with fallbacks where possible.
+
+While the core scanning functionality uses the native `BarcodeDetector` where available, it falls back to a [WebAssembly-based polyfill](https://github.com/Sec-ant/barcode-detector) to ensure consistent behavior across browsers.
+
+For a detailed compatibility overview, check each component's documentation.
diff --git a/docs/src/lib/components/demos/barqode-capture.svelte b/docs/src/lib/components/demos/barqode-capture.svelte
new file mode 100644
index 0000000..4e9e185
--- /dev/null
+++ b/docs/src/lib/components/demos/barqode-capture.svelte
@@ -0,0 +1,33 @@
+
+
+
+ Detecting QR-codes
+
+
+
+
+ Last detected: {result}
+
+
+
+
diff --git a/docs/src/lib/components/demos/barqode-drop-zone.svelte b/docs/src/lib/components/demos/barqode-drop-zone.svelte
new file mode 100644
index 0000000..19a950f
--- /dev/null
+++ b/docs/src/lib/components/demos/barqode-drop-zone.svelte
@@ -0,0 +1,50 @@
+
+
+
+ Detecting QR-codes
+
+
+ Drop an image here to detect QR-codes
+
+
+
+ Last detected: {result}
+
+
+
+
diff --git a/docs/src/lib/components/demos/barqode-stream.svelte b/docs/src/lib/components/demos/barqode-stream.svelte
new file mode 100644
index 0000000..3597e0d
--- /dev/null
+++ b/docs/src/lib/components/demos/barqode-stream.svelte
@@ -0,0 +1,75 @@
+
+
+
+ Detecting QR-codes
+
+
+
+ {#if loading}
+ Loading...
+ {/if}
+
+
+
+
+ Last detected: {result}
+
+
+
+
diff --git a/docs/src/lib/navigation.ts b/docs/src/lib/navigation.ts
index 50f5986..d190879 100644
--- a/docs/src/lib/navigation.ts
+++ b/docs/src/lib/navigation.ts
@@ -13,8 +13,8 @@ const components = allDocs
href: `/docs/${doc.slug}`,
}));
-const configuration = allDocs
- .filter((doc) => doc.section === "Configuration")
+const demos = allDocs
+ .filter((doc) => doc.section === "Demos")
.map((doc) => ({
title: doc.title,
href: `/docs/${doc.slug}`,
@@ -40,12 +40,16 @@ export const navigation = createNavigation({
],
sections: [
{
- title: "Configuration",
- items: configuration,
+ title: "Components",
+ items: components.sort((a, b) => {
+ if (a.title === "BarqodeStream") return -1;
+ if (b.title === "BarqodeStream") return 1;
+ return a.title.localeCompare(b.title);
+ }),
},
{
- title: "Components",
- items: components,
+ title: "Demos",
+ items: demos,
},
],
});
diff --git a/docs/src/lib/site-config.ts b/docs/src/lib/site-config.ts
index 899cea7..ac4610a 100644
--- a/docs/src/lib/site-config.ts
+++ b/docs/src/lib/site-config.ts
@@ -9,7 +9,7 @@ export const siteConfig = defineSiteConfig({
width: "1200",
},
description: "QR and barcode detection for Svelte.",
- author: "Ollema",
+ author: "ollema",
keywords: [
"svelte qr code reader",
"svelte barcodes",
diff --git a/docs/src/routes/api/search.json/search.json b/docs/src/routes/api/search.json/search.json
index 269e220..b45d9ff 100644
--- a/docs/src/routes/api/search.json/search.json
+++ b/docs/src/routes/api/search.json/search.json
@@ -2,85 +2,31 @@
{
"title": "Getting Started",
"href": "/docs/getting-started",
- "description": "A quick guide to get started using Svecodocs",
- "content": " import { Callout } from \"@svecodocs/kit\"; The following guide will walk you through the process of getting a Svecodocs project up and running. Clone the starter template Clone the Svecodocs starter template: pnpx degit svecosystem/svecodocs/starter Navigation The starter template comes with a basic navigation structure to get your started. To customize the navigation, adjust the src/lib/navigation.ts file. import { createNavigation } from \"@svecodocs/kit\"; export const navigation = createNavigation({ // Customize the navigation here }); Site config The site config is used to configure site-wide settings, such as the title, description, keywords, ogImage, and other metadata. The config is located in the src/lib/site-config.ts file. import { defineSiteConfig } from \"@svecodocs/kit\"; export const siteConfig = defineSiteConfig({ title: \"Svecodocs\", description: \"A SvelteKit docs starter template\", keywords: \"sveltekit, docs, starter, template\", ogImage: { url: \"https://docs.svecosystem.com/og.png\", height: 630, width: 1200, }, }); Per-Route Site Config You can override any part of the site config on a per-route basis using the useSiteConfig hook. This feature is still being worked on. Theme The starter template comes with the default Svecodocs theme (orange). To customize the theme, adjust the import in the src/app.css file to reflect the color scheme you want to use for your project. Each theme has been designed to work well in both light and dark mode. /* @import \"@svecodocs/kit/themes/orange.css\"; */ @import \"@svecodocs/kit/themes/emerald.css\"; @import \"@svecodocs/kit/globals.css\"; Logo To customize the logo displayed in the sidebar header, head to the src/routes/(docs)/+layout.svelte file and adjust the contents of the logo snippet. If the logo has a light and dark version, ensure to handle those similarly to the default Svecosystem logo. {#snippet logo()} The project name here {/snippet} `"
+ "description": "A quick guide to get started using barqode",
+ "content": "The following guide will walk you through installing and setting up the barqode components in your Svelte project. Installation Install the package using your preferred package manager: npm install barqode or pnpm add barqode or yarn add barqode Basic Usage The simplest way to use the library is with the BarqodeStream component for live scanning: import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .scanner { width: 100%; max-width: 600px; aspect-ratio: 4/3; } For detailed information about each component's capabilities and options, refer to their respective API documentation pages."
},
{
"title": "Introduction",
"href": "/docs/index",
- "description": "What exactly is Svecodocs?",
- "content": " import { Callout } from '@svecodocs/kit' After spending countless hours building documentation sites for various projects, we decided to build a docs package/starter template that we can use for future projects. This project is a result of that effort. Svecodocs is a starting point/utility library for building documentation sites under the $2 umbrella. The code is open source, but it's built and maintained for our own specific needs, so we won't be accepting any public feature requests. You are more than welcome to fork the project and customize it to your own needs. Features Markdown-based docs**. Write docs using Markdown and Svelte components Light and dark mode**. Toggle between light and dark mode Syntax highlighting**. Code blocks are automatically highlighted SEO-friendly**. Meta tags and Open Graph support out of the box Pre-built components**. Tabs, callouts, and more to use within the documentation Custom unified plugins**. Custom remark and rehype plugins to give more flexibility over the rendered HTML shadcn-svelte**. Beautifully designed Svelte components Tailwind v4**. Tailwind CSS v4 is used for styling"
+ "description": "What is Barqode?",
+ "content": "Barqode provides a set of Svelte components for detecting and decoding QR codes and various other barcode formats right in the browser. It's a comprehensive solution that supports both camera streams and static image processing. Barqode started out as a port of $2. Components BarqodeStream** - continuously scans frames from a camera stream. BarqodeDropZone** - drag & drop image files or web images. BarqodeCapture** - traditional file upload field input with camera support. Features Real-time scanning**. Detect codes from live camera stream. Multiple formats**. Support for QR codes and various barcode standards. Visual feedback**. Customizable canvas based tracking of detected codes. Cross-browser**. Works across modern browsers with a $2 if needed. Camera selection**. Choose between front/rear cameras. Torch control**. Control device flashlight where supported. Responsive**. Components adapt to fill available space. Error handling**. Comprehensive error handling for camera/detection issues. Usage Example import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .scanner { width: 100%; max-width: 600px; aspect-ratio: 4/3; } Browser Support The components rely primarily on the $2 and $2, with fallbacks where possible. While the core scanning functionality uses the native BarcodeDetector where available, it falls back to a $2 to ensure consistent behavior across browsers. For a detailed compatibility overview, check each component's documentation."
},
{
- "title": "Button",
- "href": "/docs/components/button",
- "description": "A button component to use in examples and documentation.",
- "content": " import { Button, DemoContainer } from \"@svecodocs/kit\"; Usage import { Button } from \"@svecodocs/kit\"; Default Brand Ghost Outline Subtle Link Example Default Size Default Brand Destructive Ghost Outline Subtle Link Small Size Default Brand Destructive Ghost Outline Subtle Link "
+ "title": "BarqodeCapture",
+ "href": "/docs/components/BarqodeCapture",
+ "description": "File input with camera support on mobile.",
+ "content": " import Demo from '$lib/components/demos/barqode-capture.svelte'; The BarqodeCapture component is a simple file input with the capture attribute set to environment which allows users to take a picture with their camera. Demo Props formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2, one callback per image uploaded. If not barcode is detected, the array will be empty. Other props The BarqodeCapture component accepts all attributes that a standard input element accepts. By default, the following attributes are set: type=\"file\". This is required to make the input a file input. You should not change this. name=\"image\". This is the name of the file input. accept=\"image/*\". This restricts the file types that can be uploaded to images. capture=\"environment\". This tells the browser to open the camera when the input is clicked on mobile devices. You can choose between user and environment, which opens the front and back camera respectively. You can also disable this functionality by setting it to null. multiple. This allows the user to upload multiple files at once. You can disable this by settings this to false. Usage import { BarqodeCapture, type DetectedBarcode } from \"barqode\"; let result = $state(\"\"); function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCodes.map((detectedCode) => detectedCode.rawValue).join(\", \"); } Last detected: {result} .result { margin-top: 1.25rem; } Browser Support This component depends on the $2 which is widely supported in modern browsers."
},
{
- "title": "Callout",
- "href": "/docs/components/callout",
- "description": "A callout component to highlight important information.",
- "content": " import { Callout } from \"@svecodocs/kit\"; import Avocado from \"phosphor-svelte/lib/Avocado\"; Callouts (also known as admonitions) are used to highlight a block of text. There are five types of callouts available: 'note', 'warning', 'danger', 'tip', and 'success'. You can override the default icon for the callout by passing a component via the icon prop. Usage import { Callout } from \"$lib/components\"; This is a note, used to highlight important information or provide additional context. You can use markdown in here as well! Just ensure you include a space between the component and the content in your Markdown file. Examples Warning This is an example of a warning callout. Note This is an example of a note callout. Danger This is an example of a danger callout. Tip This is an example of a tip callout. Success This is an example of a success callout. Custom Icon This is an example of a note callout with a custom icon. Custom Title This is an example of a warning callout with a custom title. "
+ "title": "BarqodeDropZone",
+ "href": "/docs/components/BarqodeDropZone",
+ "description": "File input with camera support on mobile.",
+ "content": " import Demo from '$lib/components/demos/barqode-drop-zone.svelte'; You can drag-and-drop image files from your desktop or images embedded into other web pages anywhere in the area the component occupies. The images are directly scanned and positive results are indicated by the onDetect callback. Demo Props formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2, one callback per image dropped. If not barcode is detected, the array will be empty. onDragover Type: (isDraggingOver: boolean) => void Callback function that is called when a file is dragged over the drop zone. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. Usage import { BarqodeDropZone, type DetectedBarcode } from \"barqode\"; import { DemoContainer } from \"@svecodocs/kit\"; let result = $state(\"\"); let dragover = $state(false); function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCodes.map((detectedCode) => detectedCode.rawValue).join(\", \"); } function onDragover(isDraggingOver: boolean) { dragover = isDraggingOver; } Drop an image here to detect QR-codes Last detected: {result} .dropzone { width: 100%; height: 200px; border: 2px solid #2563eb; display: flex; justify-content: center; align-items: center; } .dragover { border-color: white; } .result { margin-top: 1.25rem; } Browser Support This component depends on the $2 which is widely supported in modern browsers."
},
{
- "title": "Card Grid",
- "href": "/docs/components/card-grid",
- "description": "Display a grid of cards.",
- "content": " import { CardGrid, Card } from \"@svecodocs/kit\"; import RocketLaunch from \"phosphor-svelte/lib/RocketLaunch\"; import Blueprint from \"phosphor-svelte/lib/Blueprint\"; import Binary from \"phosphor-svelte/lib/Binary\"; import CloudCheck from \"phosphor-svelte/lib/CloudCheck\"; Use the CardGrid component to display a grid of $2 components. Usage import { CardGrid, Card } from \"@svecodocs/ui\"; You can use markdown in here, just ensure to include a space between the component and the content in your Markdown file. You can use markdown in here, just ensure to include a space between the component and the content in your Markdown file. You can use markdown in here, just ensure to include a space between the component and the content in your Markdown file. You can use markdown in here, just ensure to include a space between the component and the content in your Markdown file. Examples 2 Columns (default) You can use markdown in here, just ensure to include a space between the component and the content in your Markdown file. You can use markdown in here, just ensure to include a space between the component and the content in your Markdown file. You can use markdown in here, just ensure to include a space between the component and the content in your Markdown file. You can use markdown in here, just ensure to include a space between the component and the content in your Markdown file. 3 Columns You can use markdown in here, just ensure to include a space between the component and the content in your Markdown file. You can use markdown in here, just ensure to include a space between the component and the content in your Markdown file. You can use markdown in here, just ensure to include a space between the component and the content in your Markdown file. "
- },
- {
- "title": "Card",
- "href": "/docs/components/card",
- "description": "Display a card with a title and optional icon.",
- "content": " import { Card } from \"@svecodocs/kit\"; import RocketLaunch from \"phosphor-svelte/lib/RocketLaunch\"; You can use the Card component to display a card with a title and optional icon. Usage With Icon Pass an icon component to the icon prop to display an icon in the card. import { Card } from \"@svecodocs/ui\"; import RocketLaunch from \"phosphor-svelte/lib/RocketLaunch\"; You can use markdown in here, just ensure to include a space between the component and the content in your Markdown file. Link Card Pass the href prop to convert the card into a link. import { Card } from \"@svecodocs/ui\"; import RocketLaunch from \"phosphor-svelte/lib/RocketLaunch\"; You can use markdown in here, just ensure to include a space between the component and the content in your Markdown file. You can use markdown in here, just ensure to include a space between the component and the content in your Markdown file. Without Icon If you don't want to use an icon, just don't pass the icon prop. import { Card } from \"@svecodocs/ui\"; You can use markdown in here, just ensure to include a space between the component and the content in your Markdown file. You can use markdown in here, just ensure to include a space between the component and the content in your Markdown file. Horizontal You can use the horizontal prop to display the card horizontally. import { Card } from \"@svecodocs/ui\"; import RocketLaunch from \"phosphor-svelte/lib/RocketLaunch\"; You can use markdown in here, just ensure to include a space between the component and the content in your Markdown file. You can use markdown in here, just ensure to include a space between the component and the content in your Markdown file. "
- },
- {
- "title": "Demo Container",
- "href": "/docs/components/demo-container",
- "description": "Display a container with a border and a background color for examples/demos.",
- "content": " import { DemoContainer, Button } from \"@svecodocs/kit\"; Often times you'll want to display some demo/example components in a container. The DemoContainer component is a great way to do this, as it aligns effortlessly with the rest of the docs theme. Usage import { DemoContainer, Button } from \"@svecodocs/ui\"; Default Brand Outline Ghost Subtle Link Example Default Brand Outline Ghost Subtle Link "
- },
- {
- "title": "Input",
- "href": "/docs/components/input",
- "description": "A form input component to use in examples and documentation.",
- "content": " import { Input, Label, DemoContainer, Button } from \"@svecodocs/kit\"; When building documentation, it's often necessary to provide users with a form input to showcase a specific feature. The Input component is a great way to do this, as it aligns effortlessly with the rest of the docs theme. The Label component is also provided to help with accessibility. Usage import { Input, Label } from \"@svecodocs/kit\"; Your name Example First name Last name Update Profile "
- },
- {
- "title": "Native Select",
- "href": "/docs/components/native-select",
- "description": "A styled native select component to use in examples and documentation.",
- "content": " import { NativeSelect, Label, DemoContainer } from \"@svecodocs/kit\"; The NativeSelect component is a styled native select component that you can use in your examples and documentation. Usage import { NativeSelect } from \"@svecodocs/kit\"; Option 1 Option 2 Option 3 Example Select an option Option 1 Option 2 Option 3 "
- },
- {
- "title": "Steps",
- "href": "/docs/components/steps",
- "description": "Display a series of series of steps.",
- "content": " import { Step, Steps, Callout } from \"@svecodocs/kit\"; The Steps and Step components are used to display a series of steps, breaking down a process into more manageable chunks. Usage import { Steps, Step } from \"$lib/components\"; Install the package You can install the project via npm or pnpm. Start your engines You can start the project by running npm run dev or pnpm run dev. Example Install the package You can install the project via npm or pnpm. npm install @svecodocs/ui Start your engines You can start the project by running npm run dev or pnpm dev. npm run dev If you plan to use markdown-specific syntax in your steps, ensure you include a space between the component and the content in your Markdown file. "
- },
- {
- "title": "Tabs",
- "href": "/docs/components/tabs",
- "description": "Break content into multiple panes to reduce cognitive load.",
- "content": " import { Tabs, TabItem, Callout } from \"@svecodocs/kit\"; You can use the Tabs and TabItem components to create tabbed interfaces. A label prop must be provided to each TabItem which will be used to display the label. Whichever tab should be active by default is specified by the value prop on the Tabs component. Usage import { Tabs, TabItem } from \"@svecodocs/kit\"; This is the first tab's content. This is the second tab's content. Examples Simple Text This is the first tab's content. This is the second tab's content. Markdown Syntax import { Button } from \"@svecodocs/kit\"; alert(\"Hello!\")}>Click me export async function load() { return { transactions: [], }; } If you plan to use markdown-specific syntax in your tabs, ensure you include a space between the component and the content in your Markdown file. "
- },
- {
- "title": "Textarea",
- "href": "/docs/components/textarea",
- "description": "A textarea component to use in examples and documentation.",
- "content": " import { Textarea, Label, DemoContainer, Button } from \"@svecodocs/kit\"; When building documentation, it's often necessary to provide users with a textarea to showcase a specific feature. The Textarea component is a great way to do this, as it aligns effortlessly with the rest of the docs theme. The Label component is also provided to help with accessibility. Usage import { Textarea, Label } from \"@svecodocs/kit\"; Your bio Example Bio Update Profile "
- },
- {
- "title": "Navigation",
- "href": "/docs/configuration/navigation",
- "description": "Learn how to customize the navigation in your Svecodocs project.",
- "content": "Navigation is a key component of every site, documenting the structure of your site and providing a clear path for users to navigate through your content. Svecodocs comes with a navigation structure that is designed to be flexible and customizable. Each page in your site should have a corresponding navigation item, and the navigation items should be nested according to their hierarchy. Navigation Structure Main You can think of the main navigation as the root navigation for your site. Links in the main navigation are used to navigation to different sections of your site, such as \"Documentation\", \"API Reference\", and \"Blog\". Anchors Anchors are links that are displayed at the top of the sidebar and typically used to either highlight important information or provide quick access to linked content. Sections Sections are used to group related navigation items together. They are typically used to organize content into different categories, such as \"Components\", \"Configuration\", and \"Utilities\"."
- },
- {
- "title": "Theme",
- "href": "/docs/configuration/theme",
- "description": "Learn how to customize the theme in your Svecodocs project.",
- "content": "The theme determines the branded color scheme for your site. A theme for each of the TailwindCSS colors is provided by the @svecodocs/kit package. Each theme has been designed to present well in both light and dark mode. Using a theme To use a theme, import the theme file into your src/app.css file before importing the @svecodocs/kit/globals.css file. /* @import \"@svecodocs/kit/theme-orange.css\"; */ @import \"@svecodocs/kit/theme-emerald.css\"; @import \"@svecodocs/kit/globals.css\"; It's not recommended to customize the theme to maintain consistency across the UI components that are provided by Svecodocs and align with the provided themes. Available themes | Theme name | Import path | | ---------- | ---------------------------------- | | orange | @svecodocs/kit/theme-orange.css | | green | @svecodocs/kit/theme-green.css | | blue | @svecodocs/kit/theme-blue.css | | purple | @svecodocs/kit/theme-purple.css | | pink | @svecodocs/kit/theme-pink.css | | lime | @svecodocs/kit/theme-lime.css | | yellow | @svecodocs/kit/theme-yellow.css | | cyan | @svecodocs/kit/theme-cyan.css | | teal | @svecodocs/kit/theme-teal.css | | violet | @svecodocs/kit/theme-violet.css | | amber | @svecodocs/kit/theme-amber.css | | red | @svecodocs/kit/theme-red.css | | sky | @svecodocs/kit/theme-sky.css | | emerald | @svecodocs/kit/theme-emerald.css | | fuchsia | @svecodocs/kit/theme-fuchsia.css | | rose | @svecodocs/kit/theme-rose.css | Tailwind Variables Svecodocs uses TailwindCSS to style the UI components and provides a set of Tailwind variables that can be used to style your examples/custom components. Gray We override the TailwindCSS gray color scale to provide our own grays. Brand You can use the brand color to use the brand color of your project."
+ "title": "BarqodeStream",
+ "href": "/docs/components/BarqodeStream",
+ "description": "Continuously scans frames from a camera stream.",
+ "content": " import Demo from '$lib/components/demos/barqode-stream.svelte'; import { Callout } from '@svecodocs/kit'; The BarqodeStream component continuously scans frames from a camera stream and detects barcodes in real-time. Demo Props constraints Type: $2 Default: { video: { facingMode: \"environment\" } } Configure the the various camera options, for example whether to use front or rear camera. The object must be of type MediaTrackConstraints. The object is passed as-is to getUserMedia, which is the API call for requesting a camera stream: navigator.mediaDevices.getUserMedia({ audio: false, video: the_constraint_object_you_provide, }); When constraints is updated, a new camera stream is requested which triggers the onCameraOn callback again. You can catch errors with the onError callback. An error can occur when you try to use the front camera on a device that doesn't have one for example. formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Don't select more barcode formats than needed. Scanning becomes more expensive the more formats you select. Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. paused Type: boolean (bindable) Default: false Whether the camera stream is or should be paused. Bindable, which means that you can pause/unpause the stream from outside the component. Pausing the stream by setting paused to true is useful if you want to show some microinteraction after successful scans. When the you set it to false, the camera stream will be restarted and the onCameraOn callback function will be triggered again. torch Type: boolean Default: false Turn the camera flashlight on or off. This is not consistently supported by all devices and browsers. Support can even vary on the same device with the same browser. For example the rear camera often has a flashlight but the front camera does not. We can only tell if flashlight control is supported once the camera is loaded and the onCameraOn callback has been called. At the moment, enabling the torch may silently fail on unsupported devices, but in the onCameraOn callback payload you can access the MediaTrackCapabilities object, from which you can determine if the torch is supported. The camera stream must be reloaded when turning the torch on or off. That means the onCameraOn event will be emitted again. track Type: (detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) => void Callback function that can be used to visually highlight detected barcodes. A transparent canvas is overlaid on top of the camera stream. The track function is used to draw on this canvas. It receives an array of $2 and a $2 as the second argument. Note that when track is set the scanning frequency has to be increased. So if you want to go easy on your target device you might not want to enable tracking. The track function is called for every frame. It is important to keep the function as performant as possible. This can lead to performance issues on low-end devices and memory leaks if not handled correctly. onCameraOn Type: (capabilities: MediaTrackCapabilities) => void Callback function that is called when the camera stream is successfully loaded. It might take a while before the component is ready and the scanning process starts. The user has to be asked for camera access permission first and the camera stream has to be loaded. If you want to show a loading indicator, you can wait for this callback to be called. It is called as soon as the camera start streaming. The callback receives the a promise which resolves with the cameras $2 when everything is ready. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. onCameraOff Type: () => void Callback function that is called when the camera stream is stopped. This can happen when the camera constraints are modified, for example when switching between front and rear camera or when turning the torch on or off. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2. If you scan the same barcode multiple times in a row, onDetect is still only called once. When you hold a barcode in the camera, frames are actually decoded multiple times a second but you don't want to be flooded with callbacks that often. That's why the last decoded QR code is always cached and only new results are propagated. However, changing the value of paused resets this internal cache. Usage import { BarqodeStream, type DetectedBarcode } from \"barqode\"; let loading = $state(true); let result: string | null = $state(null); function onCameraOn() { loading = false; } function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCode.map((code) => detectedCode.rawValue).join(\", \"); } function track(detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) { for (const detectedCode of detectedCodes) { const [firstPoint, ...otherPoints] = detectedCode.cornerPoints; ctx.strokeStyle = \"#2563eb\"; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(firstPoint.x, firstPoint.y); for (const { x, y } of otherPoints) { ctx.lineTo(x, y); } ctx.lineTo(firstPoint.x, firstPoint.y); ctx.closePath(); ctx.stroke(); } } {#if loading} Loading... {/if} Last detected: {result} .scanner { width: 100%; aspect-ratio: 4 / 3; } .loading-indicator { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; font-weight: bold; font-size: 2rem; } .result { margin-top: 1.25rem; } Browser Support This component depends on the $2 which is widely supported in modern browsers."
}
]
diff --git a/docs/velite.config.js b/docs/velite.config.js
index beaa180..613063b 100644
--- a/docs/velite.config.js
+++ b/docs/velite.config.js
@@ -8,7 +8,7 @@ const baseSchema = s.object({
navLabel: s.string().optional(),
raw: s.raw(),
toc: s.toc(),
- section: s.enum(["Overview", "Components", "Configuration", "Utilities"]),
+ section: s.enum(["Overview", "Components", "Demos"]),
});
const docSchema = baseSchema.transform((data) => {
diff --git a/package.json b/package.json
index 479d0b0..5f062f9 100644
--- a/package.json
+++ b/package.json
@@ -24,23 +24,23 @@
"packageManager": "pnpm@9.14.4",
"devDependencies": {
"@changesets/cli": "^2.27.10",
- "@eslint/js": "^9.12.0",
+ "@eslint/js": "^9.16.0",
"@svitejs/changesets-changelog-github-compact": "^1.2.0",
"@types/node": "^22.10.1",
- "@typescript-eslint/eslint-plugin": "^8.10.0",
- "@typescript-eslint/scope-manager": "^8.10.0",
- "@typescript-eslint/utils": "^8.10.0",
- "eslint": "^9.0.0",
+ "@typescript-eslint/eslint-plugin": "^8.17.0",
+ "@typescript-eslint/scope-manager": "^8.17.0",
+ "@typescript-eslint/utils": "^8.17.0",
+ "eslint": "^9.16.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-svelte": "^2.46.1",
- "globals": "^15.11.0",
- "prettier": "^3.3.3",
+ "globals": "^15.13.0",
+ "prettier": "^3.4.1",
"prettier-plugin-svelte": "^3.3.2",
- "prettier-plugin-tailwindcss": "^0.6.8",
- "svelte": "^5.2.11",
+ "prettier-plugin-tailwindcss": "^0.6.9",
+ "svelte": "^5.4.0",
"svelte-eslint-parser": "^0.43.0",
- "typescript": "^5.6.3",
- "typescript-eslint": "^8.10.0",
+ "typescript": "^5.7.2",
+ "typescript-eslint": "^8.17.0",
"wrangler": "^3.91.0"
}
}
diff --git a/packages/barqode/package.json b/packages/barqode/package.json
index 393e25e..30afe5c 100644
--- a/packages/barqode/package.json
+++ b/packages/barqode/package.json
@@ -38,25 +38,30 @@
"svelte": "^5.0.0"
},
"devDependencies": {
- "@sveltejs/adapter-auto": "^3.0.0",
- "@sveltejs/kit": "^2.0.0",
- "@sveltejs/package": "^2.0.0",
- "@sveltejs/vite-plugin-svelte": "^4.0.0",
- "publint": "^0.2.0",
- "svelte": "^5.0.0",
- "svelte-check": "^4.0.0",
- "typescript": "^5.0.0",
- "vite": "^5.0.11"
+ "@sveltejs/adapter-auto": "^3.3.1",
+ "@sveltejs/kit": "^2.9.0",
+ "@sveltejs/package": "^2.3.7",
+ "@sveltejs/vite-plugin-svelte": "^4.0.2",
+ "publint": "^0.2.12",
+ "svelte": "^5.4.0",
+ "svelte-check": "^4.1.0",
+ "typescript": "^5.7.2",
+ "vite": "^5.4.11"
},
"license": "MIT",
"contributors": [
{
- "name": "Ollie",
+ "name": "Olle",
"url": "https://github.com/ollema"
},
{
"name": "Hunter Johnston",
"url": "https://github.com/huntabyte"
}
- ]
+ ],
+ "dependencies": {
+ "barcode-detector": "^2.3.1",
+ "runed": "^0.16.1",
+ "webrtc-adapter": "^9.0.1"
+ }
}
diff --git a/packages/barqode/src/app.html b/packages/barqode/src/app.html
new file mode 100644
index 0000000..f22aeaa
--- /dev/null
+++ b/packages/barqode/src/app.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+ %sveltekit.head%
+
+
+ %sveltekit.body%
+
+
diff --git a/packages/barqode/src/lib/components/barqode-capture.svelte b/packages/barqode/src/lib/components/barqode-capture.svelte
new file mode 100644
index 0000000..d7da98e
--- /dev/null
+++ b/packages/barqode/src/lib/components/barqode-capture.svelte
@@ -0,0 +1,29 @@
+
+
+
diff --git a/packages/barqode/src/lib/components/barqode-drop-zone.svelte b/packages/barqode/src/lib/components/barqode-drop-zone.svelte
new file mode 100644
index 0000000..1a6abb7
--- /dev/null
+++ b/packages/barqode/src/lib/components/barqode-drop-zone.svelte
@@ -0,0 +1,76 @@
+
+
+
+ {@render children?.()}
+
diff --git a/packages/barqode/src/lib/components/barqode-stream.svelte b/packages/barqode/src/lib/components/barqode-stream.svelte
new file mode 100644
index 0000000..e515f9d
--- /dev/null
+++ b/packages/barqode/src/lib/components/barqode-stream.svelte
@@ -0,0 +1,259 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ {@render children?.()}
+
+
+
+
diff --git a/packages/barqode/src/lib/components/callforth.ts b/packages/barqode/src/lib/components/callforth.ts
new file mode 100644
index 0000000..1c40cb8
--- /dev/null
+++ b/packages/barqode/src/lib/components/callforth.ts
@@ -0,0 +1,49 @@
+// based on vue-qrcode-reader by Niklas Gruhn
+// see https://github.com/gruhn/vue-qrcode-reader
+
+/**
+ * Creates a Promise that resolves when a specified event is triggered on the given EventTarget.
+ *
+ * @param eventTarget - The target to listen for events on.
+ * @param successEvent - The name of the event that will resolve the Promise.
+ * @param errorEvent - The name of the event that will reject the Promise. Defaults to 'error'.
+ *
+ * @returns A Promise that resolves with the event object when the successEvent is triggered,
+ * or rejects with the event object when the errorEvent is triggered.
+ */
+export const eventOn = (
+ eventTarget: EventTarget,
+ successEvent: string,
+ errorEvent = "error"
+): Promise => {
+ let $resolve: (value: Event) => void;
+ let $reject: (reason?: Event) => void;
+
+ const promise = new Promise(
+ (resolve: (value: Event) => void, reject: (reason?: Event) => void) => {
+ $resolve = resolve;
+ $reject = reject;
+
+ eventTarget.addEventListener(successEvent, $resolve);
+ eventTarget.addEventListener(errorEvent, $reject);
+ }
+ );
+
+ promise.finally(() => {
+ eventTarget.removeEventListener(successEvent, $resolve);
+ eventTarget.removeEventListener(errorEvent, $reject);
+ });
+
+ return promise;
+};
+
+/**
+ * Creates a promise that resolves after a specified number of milliseconds.
+ *
+ * @param milliseconds - The number of milliseconds to wait before the promise resolves.
+ *
+ * @returns A promise that resolves after the specified delay.
+ */
+export const timeout = (milliseconds: number) => {
+ return new Promise((resolve: (value: unknown) => void) => setTimeout(resolve, milliseconds));
+};
diff --git a/packages/barqode/src/lib/components/camera.ts b/packages/barqode/src/lib/components/camera.ts
new file mode 100644
index 0000000..d33f837
--- /dev/null
+++ b/packages/barqode/src/lib/components/camera.ts
@@ -0,0 +1,295 @@
+// based on vue-qrcode-reader by Niklas Gruhn
+// see https://github.com/gruhn/vue-qrcode-reader
+
+import {
+ StreamApiNotSupportedError,
+ InsecureContextError,
+ StreamLoadTimeoutError,
+} from "./errors.js";
+import { eventOn, timeout } from "./callforth.js";
+import shimGetUserMedia from "./shimGetUserMedia.js";
+import { assertNever } from "./util.js";
+
+type StartTaskResult = {
+ type: "start";
+ data: {
+ videoEl: HTMLVideoElement;
+ stream: MediaStream;
+ capabilities: Partial;
+ constraints: MediaTrackConstraints;
+ isTorchOn: boolean;
+ };
+};
+
+type StopTaskResult = {
+ type: "stop";
+ data: null;
+};
+
+type FailedTask = {
+ type: "failed";
+ error: Error;
+};
+
+type TaskResult = StartTaskResult | StopTaskResult | FailedTask;
+
+let taskQueue: Promise = Promise.resolve({ type: "stop", data: null });
+
+type CreateObjectURLCompat = (obj: MediaSource | Blob | MediaStream) => string;
+
+/**
+ * Starts the camera with the given constraints and attaches the stream to the provided video element.
+ *
+ * @param videoEl - The HTML video element to which the camera stream will be attached.
+ * @param constraints - The media track constraints to apply when starting the camera.
+ * @param torch - A boolean indicating whether the torch (flashlight) should be enabled if supported.
+ *
+ * @returns A promise that resolves to a `StartTaskResult` object containing details about the started camera stream.
+ *
+ * @throws InsecureContextError - If the page is not loaded in a secure context (HTTPS).
+ * @throws StreamApiNotSupportedError - If the Stream API is not supported by the browser.
+ * @throws StreamLoadTimeoutError - If the video element fails to load the camera stream within a 6-second timeout.
+ */
+async function runStartTask(
+ videoEl: HTMLVideoElement,
+ constraints: MediaTrackConstraints,
+ torch: boolean
+): Promise {
+ console.debug("[barqode] starting camera with constraints: ", JSON.stringify(constraints));
+
+ // at least in Chrome `navigator.mediaDevices` is undefined when the page is
+ // loaded using HTTP rather than HTTPS. thus `STREAM_API_NOT_SUPPORTED` is
+ // initialized with `false` although the API might actually be supported.
+ // so although `getUserMedia` already should have a built-in mechanism to
+ // detect insecure context (by throwing `NotAllowedError`), we have to do a
+ // manual check before even calling `getUserMedia`.
+ if (window.isSecureContext !== true) {
+ throw new InsecureContextError();
+ }
+
+ if (navigator?.mediaDevices?.getUserMedia === undefined) {
+ throw new StreamApiNotSupportedError();
+ }
+
+ // this is a browser API only shim. tt patches the global window object which
+ // is not available during SSR. So we lazily apply this shim at runtime.
+ shimGetUserMedia();
+
+ console.debug("[barqode] calling getUserMedia");
+ const stream = await navigator.mediaDevices.getUserMedia({
+ audio: false,
+ video: constraints,
+ });
+
+ if (videoEl.srcObject !== undefined) {
+ videoEl.srcObject = stream;
+ } else if (videoEl.mozSrcObject !== undefined) {
+ videoEl.mozSrcObject = stream;
+ } else if (window.URL.createObjectURL) {
+ videoEl.src = (window.URL.createObjectURL as CreateObjectURLCompat)(stream);
+ } else if (window.webkitURL) {
+ videoEl.src = (window.webkitURL.createObjectURL as CreateObjectURLCompat)(stream);
+ } else {
+ videoEl.src = stream.id;
+ }
+
+ // in the WeChat browser on iOS, 'loadeddata' event won't get fired unless video is explicitly triggered by play()
+ videoEl.play();
+
+ console.debug("[barqode] waiting for video element to load");
+ await Promise.race([
+ eventOn(videoEl, "loadeddata"),
+
+ // on iOS devices in PWA mode, BarqodeStream works initially, but after killing and restarting the PWA,
+ // all video elements fail to load camera streams and never emit the `loadeddata` event.
+ // looks like this is related to a WebKit issue (see #298). no workarounds at the moment.
+ // to at least detect this situation, we throw an error if the event has not been emitted after a 6 second timeout.
+ timeout(6_000).then(() => {
+ throw new StreamLoadTimeoutError();
+ }),
+ ]);
+ console.debug("[barqode] video element loaded");
+
+ // according to: https://oberhofer.co/mediastreamtrack-and-its-capabilities/#queryingcapabilities
+ // on some devices, getCapabilities only returns a non-empty object after some delay.
+ // there is no appropriate event so we have to add a constant timeout
+ await timeout(500);
+
+ const [track] = stream.getVideoTracks();
+
+ const capabilities: Partial = track?.getCapabilities?.() ?? {};
+
+ let isTorchOn = false;
+ // @ts-expect-error torch is not in the MediaTrackConstraints type but it should be?
+ if (torch && capabilities.torch) {
+ // @ts-expect-error torch is not in the MediaTrackConstraints type but it should be?
+ await track.applyConstraints({ advanced: [{ torch: true }] });
+ isTorchOn = true;
+ }
+
+ console.debug("[barqode] camera ready");
+
+ return {
+ type: "start",
+ data: {
+ videoEl,
+ stream,
+ capabilities,
+ constraints,
+ isTorchOn,
+ },
+ };
+}
+
+/**
+ * Starts the camera with the given video element and settings.
+ *
+ * @param videoEl - The HTML video element to which the camera stream will be attached.
+ * @param options.constraints - The media track constraints to apply when starting the camera.
+ * @param options.torch - A boolean indicating whether the torch (flashlight) should be enabled if supported.
+ * @param options.restart - A boolean indicating whether to restart the camera even if no settings changed. Defaults to false.
+ *
+ * @returns A promise that resolves to a `MediaTrackCapabilities` object containing the camera capabilities.
+ *
+ * @throws Error - If something goes wrong with the camera task queue.
+ */
+export async function start(
+ videoEl: HTMLVideoElement,
+ {
+ constraints,
+ torch,
+ restart = false,
+ }: {
+ constraints: MediaTrackConstraints;
+ torch: boolean;
+ restart?: boolean;
+ }
+): Promise> {
+ // update the task queue synchronously
+ taskQueue = taskQueue
+ .then((prevTaskResult) => {
+ if (prevTaskResult.type === "start") {
+ // previous task is a start task
+ // we'll check if we can reuse the previous result
+ const {
+ data: {
+ videoEl: prevVideoEl,
+ stream: prevStream,
+ constraints: prevConstraints,
+ isTorchOn: prevIsTorchOn,
+ },
+ } = prevTaskResult;
+ // TODO: should we keep this object comparison
+ // this code only checks object sameness not equality
+ // deep comparison requires snapshots and value by value check
+ // which seem too much
+ if (
+ !restart &&
+ videoEl === prevVideoEl &&
+ constraints === prevConstraints &&
+ torch === prevIsTorchOn
+ ) {
+ // things didn't change, reuse the previous result
+ return prevTaskResult;
+ }
+ // something changed, restart (stop then start)
+ return runStopTask(prevVideoEl, prevStream, prevIsTorchOn).then(() =>
+ runStartTask(videoEl, constraints, torch)
+ );
+ } else if (prevTaskResult.type === "stop" || prevTaskResult.type === "failed") {
+ // previous task is a stop/error task
+ // we can safely start
+ return runStartTask(videoEl, constraints, torch);
+ }
+
+ assertNever(prevTaskResult);
+ })
+ .catch((error: Error) => {
+ console.debug(`[barqode] starting camera failed with "${error}"`);
+ return { type: "failed", error };
+ });
+
+ // await the task queue asynchronously
+ const taskResult = await taskQueue;
+
+ if (taskResult.type === "stop") {
+ // we just synchronously updated the task above
+ // to make the latest task a start task
+ // so this case shouldn't happen
+ throw new Error("Something went wrong with the camera task queue (start task).");
+ } else if (taskResult.type === "failed") {
+ throw taskResult.error;
+ } else if (taskResult.type === "start") {
+ // return the data we want
+ return taskResult.data.capabilities;
+ }
+
+ assertNever(taskResult);
+}
+
+/**
+ * Stops the camera stream and cleans up associated resources.
+ *
+ * @param videoEl - The HTML video element displaying the camera stream.
+ * @param stream - The MediaStream object representing the active camera stream.
+ * @param isTorchOn - A boolean indicating whether the torch is currently enabled.
+ *
+ * @returns A promise that resolves to a `StopTaskResult` when the camera is fully stopped.
+ */
+async function runStopTask(
+ videoEl: HTMLVideoElement,
+ stream: MediaStream,
+ isTorchOn: boolean
+): Promise {
+ console.debug("[barqode] stopping camera");
+
+ videoEl.src = "";
+ videoEl.srcObject = null;
+ videoEl.load();
+
+ // wait for load() to emit error
+ // because src and srcObject are empty
+ await eventOn(videoEl, "error");
+
+ for (const track of stream.getTracks()) {
+ // @ts-expect-error torch is not in the MediaTrackConstraints type but it should be?
+ isTorchOn ?? (await track.applyConstraints({ advanced: [{ torch: false }] }));
+ stream.removeTrack(track);
+ track.stop();
+ }
+
+ return {
+ type: "stop",
+ data: null,
+ };
+}
+
+/**
+ * Stops any active camera stream and ensures proper cleanup.
+ *
+ * @returns A promise that resolves when the camera is fully stopped.
+ *
+ * @throws Error - If something goes wrong with the camera task queue.
+ */
+export async function stop() {
+ // update the task queue synchronously
+ taskQueue = taskQueue.then((prevTaskResult) => {
+ if (prevTaskResult.type === "stop" || prevTaskResult.type === "failed") {
+ // previous task is a stop task
+ // no need to stop again
+ return prevTaskResult;
+ }
+ const {
+ data: { videoEl, stream, isTorchOn },
+ } = prevTaskResult;
+ return runStopTask(videoEl, stream, isTorchOn);
+ });
+ // await the task queue asynchronously
+ const taskResult = await taskQueue;
+ if (taskResult.type === "start") {
+ // we just synchronously updated the task above
+ // to make the latest task a stop task
+ // so this case shouldn't happen
+ throw new Error("Something went wrong with the camera task queue (stop task).");
+ }
+}
diff --git a/packages/barqode/src/lib/components/errors.ts b/packages/barqode/src/lib/components/errors.ts
new file mode 100644
index 0000000..e047254
--- /dev/null
+++ b/packages/barqode/src/lib/components/errors.ts
@@ -0,0 +1,35 @@
+export class DropImageFetchError extends Error {
+ constructor() {
+ super("can't process cross-origin image");
+
+ this.name = "DropImageFetchError";
+ }
+}
+
+export class StreamApiNotSupportedError extends Error {
+ constructor() {
+ super("this browser has no Stream API support");
+
+ this.name = "StreamApiNotSupportedError";
+ }
+}
+
+export class InsecureContextError extends Error {
+ constructor() {
+ super(
+ "camera access is only permitted in secure context. Use HTTPS or localhost rather than HTTP."
+ );
+
+ this.name = "InsecureContextError";
+ }
+}
+
+export class StreamLoadTimeoutError extends Error {
+ constructor() {
+ super(
+ "loading camera stream timed out after 6 seconds. If you are on iOS in PWA mode, this is a known issue (see https://github.com/gruhn/vue-qrcode-reader/issues/298)"
+ );
+
+ this.name = "StreamLoadTimeoutError";
+ }
+}
diff --git a/packages/barqode/src/lib/components/global.d.ts b/packages/barqode/src/lib/components/global.d.ts
new file mode 100644
index 0000000..781f628
--- /dev/null
+++ b/packages/barqode/src/lib/components/global.d.ts
@@ -0,0 +1,5 @@
+///
+
+interface HTMLVideoElement {
+ mozSrcObject?: HTMLVideoElement["srcObject"];
+}
diff --git a/packages/barqode/src/lib/components/scanner.ts b/packages/barqode/src/lib/components/scanner.ts
new file mode 100644
index 0000000..a5f1c3c
--- /dev/null
+++ b/packages/barqode/src/lib/components/scanner.ts
@@ -0,0 +1,226 @@
+// based on vue-qrcode-reader by Niklas Gruhn
+// see https://github.com/gruhn/vue-qrcode-reader
+
+import { type DetectedBarcode, type BarcodeFormat, BarcodeDetector } from "barcode-detector/pure";
+import { eventOn } from "./callforth.js";
+import { DropImageFetchError } from "./errors.js";
+
+declare global {
+ interface Window {
+ BarcodeDetector?: typeof BarcodeDetector;
+ }
+}
+
+/**
+ * Singleton `BarcodeDetector` instance used by `BarqodeStream`. This is firstly to avoid
+ * the overhead of creating a new instances for scanning each frame. And secondly, the
+ * instances can seamlessly be replaced in the middle of the scanning process, if the
+ * `formats` prop of `BarqodeStream` is changed.
+ *
+ * This instance is not used by `BarqodeCapture` and `BarqodeDropZone`, because it may not
+ * have the right `formats` configured. For these components we create one-off `BarcodeDetector`
+ * instances because it does not happen so frequently anyway (see: `processFile`/`processUrl`).
+ */
+let barcodeDetector: BarcodeDetector;
+
+/**
+ * Constructs a `BarcodeDetector` instance, given a list of targeted barcode formats.
+ * Preferably, we want to use the native `BarcodeDetector` implementation if supported.
+ * Otherwise, we fall back to the polyfill implementation.
+ *
+ * Note, that we can't just monkey patch the polyfill on load, i.e.
+ *
+ * window.BarcodeDetector ??= BarcodeDetector
+ *
+ * for two reasons. Firstly, this is not SSR compatible, because `window` is not available
+ * during SSR. Secondly, even if the native implementation is available, we still might
+ * want to use the polyfill. For example, if the native implementation only supports the
+ * format `"qr_code"` but the user wants to scan `["qr_code", "aztec"]` (see #450).
+ */
+async function createBarcodeDetector(formats: BarcodeFormat[]): Promise {
+ if (window.BarcodeDetector === undefined) {
+ console.debug("[barqode] native BarcodeDetector not supported. Will use polyfill.");
+ return new BarcodeDetector({ formats });
+ }
+
+ const allSupportedFormats = await window.BarcodeDetector.getSupportedFormats();
+ const unsupportedFormats = formats.filter((format) => !allSupportedFormats.includes(format));
+
+ if (unsupportedFormats.length > 0) {
+ console.debug(
+ `[barqode] native BarcodeDetector does not support formats ${JSON.stringify(unsupportedFormats)}. Will use polyfill.`
+ );
+ return new BarcodeDetector({ formats });
+ }
+
+ console.debug("[barqode] will use native BarcodeDetector.");
+ return new window.BarcodeDetector({ formats });
+}
+
+/**
+ * Update the set of targeted barcode formats. In particular, this function
+ * can be called during scanning and the camera stream doesn't have to be
+ * interrupted.
+ */
+export async function setScanningFormats(formats: BarcodeFormat[]) {
+ barcodeDetector = await createBarcodeDetector(formats);
+}
+
+type ScanHandler = (_: DetectedBarcode[]) => void;
+
+/**
+ * Continuously extracts frames from camera stream and tries to read
+ * potentially pictured QR codes.
+ */
+export const keepScanning = async (
+ videoElement: HTMLVideoElement,
+ {
+ detectHandler,
+ locateHandler,
+ minDelay,
+ formats,
+ }: {
+ detectHandler: ScanHandler;
+ locateHandler: ScanHandler;
+ minDelay: number;
+ formats: BarcodeFormat[];
+ }
+) => {
+ console.debug("[barqode] start scanning");
+ await setScanningFormats(formats);
+
+ const processFrame =
+ (state: { lastScanned: number; contentBefore: string[]; lastScanHadContent: boolean }) =>
+ async (timeNow: number) => {
+ if (videoElement.readyState === 0) {
+ console.debug("[barqode] stop scanning: video element readyState is 0");
+ } else {
+ const { lastScanned, contentBefore, lastScanHadContent } = state;
+
+ // Scanning is expensive and we don't need to scan camera frames with
+ // the maximum possible frequency. In particular when visual tracking
+ // is disabled. So we skip scanning a frame if `minDelay` has not passed
+ // yet. Notice that this approach is different from doing a `setTimeout`
+ // after each scan. With `setTimeout`, delay and scanning are sequential:
+ //
+ // |-- scan --|---- minDelay ----|-- scan --|---- minDelay ----|
+ //
+ // Instead we do it concurrently:
+ //
+ // |---- minDelay ----|---- minDelay ----|---- minDelay ----|
+ // |-- scan --| |-- scan --| |-- scan --|
+ //
+ // Let's say `minDelay` is 40ms, then we scan every 40ms as long as
+ // scanning itself does not take more than 40ms. In particular when
+ // visual tracking is enabled, that means we can repaint the tracking
+ // canvas every 40ms. So we paint
+ //
+ // 1000ms / 40ms = 25fps (frames per second)
+ //
+ // 24fps is the minimum frame-rate that is perceived as a continuous
+ // animation. We target 25fps just because 24 doesn't divide 1000ms
+ // evenly.
+ if (timeNow - lastScanned < minDelay) {
+ window.requestAnimationFrame(processFrame(state));
+ } else {
+ const detectedCodes = await barcodeDetector.detect(videoElement);
+
+ // Only emit a detect event, if at least one of the detected codes has
+ // not been seen before. Otherwise we spam tons of detect events while
+ // a QR code is in view of the camera. To avoid that we store the previous
+ // detection in `contentBefore`.
+ //
+ // Implicitly we also don't emit a `detect` event if `detectedCodes` is an
+ // empty array.
+ const anyNewCodesDetected = detectedCodes.some((code) => {
+ return !contentBefore.includes(code.rawValue);
+ });
+
+ if (anyNewCodesDetected) {
+ detectHandler(detectedCodes);
+ }
+
+ const currentScanHasContent = detectedCodes.length > 0;
+
+ // In contrast to the QR code content, the location changes all the time.
+ // So we call the locate handler on every detection to repaint the tracking
+ // canvas.
+ if (currentScanHasContent) {
+ locateHandler(detectedCodes);
+ }
+
+ // Additionally, we need to clear the tracking canvas once when no QR code
+ // is in view of the camera anymore. Technically this can be merged with the
+ // previous if-statement but this way it's more explicit.
+ if (!currentScanHasContent && lastScanHadContent) {
+ locateHandler(detectedCodes);
+ }
+
+ const newState = {
+ lastScanned: timeNow,
+ lastScanHadContent: currentScanHasContent,
+
+ // It can happen that a QR code is constantly in view of the camera but
+ // maybe a scanned frame is a bit blurry and we detect nothing but in the
+ // next frame we detect the code again. We also want to avoid emitting
+ // a `detect` event in such a case. So we don't reset `contentBefore`,
+ // if we detect nothing, only if we detect something new.
+ contentBefore: anyNewCodesDetected
+ ? detectedCodes.map((code) => code.rawValue)
+ : contentBefore,
+ };
+
+ window.requestAnimationFrame(processFrame(newState));
+ }
+ }
+ };
+
+ processFrame({
+ lastScanned: performance.now(),
+ contentBefore: [],
+ lastScanHadContent: false,
+ })(performance.now());
+};
+
+const imageElementFromUrl = async (url: string) => {
+ if (url.startsWith("http") && url.includes(location.host) === false) {
+ throw new DropImageFetchError();
+ }
+
+ const image = document.createElement("img");
+ image.src = url;
+
+ await eventOn(image, "load");
+
+ return image;
+};
+
+export const processFile = async (
+ file: File,
+ formats: BarcodeFormat[] = ["qr_code"]
+): Promise => {
+ // To scan files/urls we use one-off `BarcodeDetector` instances,
+ // since we don't scan as often as camera frames. Note, that we
+ // always use the polyfill. This is because (at the time of writing)
+ // some browser/OS combinations don't support `Blob`/`File` inputs
+ // into the `detect` function.
+ const barcodeDetector = new BarcodeDetector({ formats });
+
+ return await barcodeDetector.detect(file);
+};
+
+export const processUrl = async (
+ url: string,
+ formats: BarcodeFormat[] = ["qr_code"]
+): Promise => {
+ // To scan files/urls we use one-off `BarcodeDetector` instances,
+ // since we don't scan as often as camera frames. Note, that we
+ // always use the polyfill. This is because (at the time of writing)
+ // some browser/OS combinations don't support `Blob`/`File` inputs
+ // into the `detect` function.
+ const barcodeDetector = new BarcodeDetector({ formats });
+
+ const image = await imageElementFromUrl(url);
+
+ return await barcodeDetector.detect(image);
+};
diff --git a/packages/barqode/src/lib/components/shimGetUserMedia.ts b/packages/barqode/src/lib/components/shimGetUserMedia.ts
new file mode 100644
index 0000000..cb6829d
--- /dev/null
+++ b/packages/barqode/src/lib/components/shimGetUserMedia.ts
@@ -0,0 +1,32 @@
+// based on vue-qrcode-reader by Niklas Gruhn
+// see https://github.com/gruhn/vue-qrcode-reader
+
+// @ts-expect-error no types available
+import { shimGetUserMedia as chromeShim } from "webrtc-adapter/dist/chrome/getusermedia";
+// @ts-expect-error no types available
+import { shimGetUserMedia as firefoxShim } from "webrtc-adapter/dist/firefox/getusermedia";
+// @ts-expect-error no types available
+import { shimGetUserMedia as safariShim } from "webrtc-adapter/dist/safari/safari_shim";
+// @ts-expect-error no types available
+import { detectBrowser } from "webrtc-adapter/dist/utils";
+
+import { StreamApiNotSupportedError } from "./errors.js";
+import { idempotent } from "./util.js";
+
+export default idempotent(() => {
+ const browserDetails = detectBrowser(window);
+
+ switch (browserDetails.browser) {
+ case "chrome":
+ chromeShim(window, browserDetails);
+ break;
+ case "firefox":
+ firefoxShim(window, browserDetails);
+ break;
+ case "safari":
+ safariShim(window, browserDetails);
+ break;
+ default:
+ throw new StreamApiNotSupportedError();
+ }
+});
diff --git a/packages/barqode/src/lib/components/types.ts b/packages/barqode/src/lib/components/types.ts
new file mode 100644
index 0000000..0a50005
--- /dev/null
+++ b/packages/barqode/src/lib/components/types.ts
@@ -0,0 +1,143 @@
+import type { BarcodeFormat, DetectedBarcode, Point2D } from "barcode-detector/pure";
+import type { Snippet } from "svelte";
+import type { HTMLInputAttributes } from "svelte/elements";
+
+export type { DetectedBarcode, BarcodeFormat, Point2D };
+
+export type CaptureProps = {
+ /**
+ * The formats of the barcodes to detect.
+ *
+ * @default ['qr_code']
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Barcode_Detection_API#supported_barcode_formats
+ */
+ formats?: BarcodeFormat[];
+
+ /**
+ * A callback function called a detection is made.
+ *
+ * @param codes - The detected barcodes.
+ */
+ onDetect?: (detectedCodes: DetectedBarcode[]) => void;
+} & HTMLInputAttributes;
+
+export type DropZoneProps = {
+ /**
+ * The formats of the barcodes to detect.
+ *
+ * @default ['qr_code']
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Barcode_Detection_API#supported_barcode_formats
+ */
+ formats?: BarcodeFormat[];
+
+ /**
+ * A callback function called when the user drops an image file.
+ *
+ * @param codes - The detected barcodes.
+ */
+ onDetect?: (detectedCodes: DetectedBarcode[]) => void;
+
+ /**
+ * A callback function called when the user drags an image file over the drop zone.
+ *
+ * @param isDraggingOver - Whether the user is dragging an image file over the drop zone.
+ */
+ onDragover?: (isDraggingOver: boolean) => void;
+
+ /**
+ * A callback function called when the user drags an image file out of the drop zone.
+ *
+ * @param error - The error that occurred.
+ */
+ onError?: (error: Error) => void;
+
+ /**
+ * Optional prop for content to be overlayed on top of the drop zone.
+ */
+ children?: Snippet;
+};
+
+export type StreamProps = {
+ /**
+ * The MediaTrackConstraints specifying the desired media types and their constraints.
+ *
+ * @default { video: { facingMode: 'environment' } }
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints
+ */
+ constraints?: MediaTrackConstraints;
+
+ /**
+ * The formats of the barcodes to detect.
+ *
+ * @default ['qr_code']
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Barcode_Detection_API#supported_barcode_formats
+ */
+ formats?: BarcodeFormat[];
+
+ /**
+ * Whether the camera stream is paused. Bindable.
+ *
+ * @default false
+ *
+ * Can also be set to `true` to pause the camera stream, which is useful when you want to show
+ * some microinteraction after successful scans. When the you set it to `false`, the camera
+ * stream will be restarted and the `onCameraOn` callback function will be triggered again.
+ */
+ paused?: boolean;
+
+ /**
+ * Whether the torch is enabled.
+ *
+ * @default false
+ *
+ * Not consistently supported across devices.
+ */
+ torch?: boolean;
+
+ /**
+ * Function to visually highlight the detected barcodes.
+ *
+ * @param codes - The detected barcodes with their adjusted corner points.
+ * @param ctx - The canvas rendering context.
+ */
+ track?: (detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) => void;
+
+ /**
+ * A callback function called when the camera stream is turned on.
+ *
+ * @param capabilities - The MediaTrackCapabilities of the camera stream.
+ */
+ onCameraOn?: (capabilities: MediaTrackCapabilities) => void;
+
+ /**
+ * A callback function called when the camera stream encounters an error.
+ *
+ * @param error - The error that occurred.
+ */
+ onError?: (error: Error) => void;
+
+ /**
+ * A callback function called when the camera stream is turned off.
+ */
+ onCameraOff?: () => void;
+
+ /**
+ * A callback function called a detection is made.
+ *
+ * Note: if you scan the same barcode code multiple times in a row, onDetect is still called once.
+ * When you hold a barcode in the camera, frames are actually decoded multiple times a second
+ * but you don't want to be flooded with onDetect callbacks that often.
+ * That's why the last decoded barcode is always cached and only new results are propagated.
+ * However changing the value of `paused` resets this internal cache.
+ */
+ onDetect?: (detectedCodes: DetectedBarcode[]) => void;
+
+ /**
+ * Optional prop for content to be overlayed on top of the camera stream.
+ */
+ children?: Snippet;
+};
diff --git a/packages/barqode/src/lib/components/util.ts b/packages/barqode/src/lib/components/util.ts
new file mode 100644
index 0000000..43d9475
--- /dev/null
+++ b/packages/barqode/src/lib/components/util.ts
@@ -0,0 +1,51 @@
+// based on vue-qrcode-reader by Niklas Gruhn
+// see https://github.com/gruhn/vue-qrcode-reader
+
+/**
+ * Creates a function that ensures the given action is only executed once.
+ * Subsequent calls to the returned function will return the result of the first call.
+ *
+ * @template T - The return type of the action.
+ * @template U - The type of the arguments passed to the action.
+ * @param {function(U[]): T} action - The action to be executed idempotently.
+ * @returns {function(...U[]): T | undefined} A function that, when called, will execute the action only once and return the result.
+ */
+export const idempotent = (action: (x: U[]) => T) => {
+ let called = false;
+ let result: T | undefined = undefined;
+
+ return (...args: U[]) => {
+ if (called) {
+ return result;
+ } else {
+ result = action(args);
+ called = true;
+
+ return result;
+ }
+ };
+};
+
+/**
+ * Asserts that a given condition is true. If the condition is false, it throws an error with the provided failure message.
+ *
+ * @param condition - The condition to assert.
+ * @param failureMessage - Optional message to include in the error if the assertion fails.
+ * @throws {Error} If the condition is false.
+ */
+export function assert(condition: boolean, failureMessage?: string): asserts condition {
+ if (condition === false) {
+ throw new Error(failureMessage ?? "assertion failure");
+ }
+}
+
+/**
+ * Asserts that a given value is of type `never`, indicating that this code path should be unreachable.
+ * Throws an error if called, signaling a logic error in the code.
+ *
+ * @param _witness - The value that should be of type `never`.
+ * @throws {Error} Always throws an error to indicate unreachable code.
+ */
+export function assertNever(_witness: never): never {
+ throw new Error("this code should be unreachable");
+}
diff --git a/packages/barqode/src/lib/index.ts b/packages/barqode/src/lib/index.ts
index 47d3c46..19b6167 100644
--- a/packages/barqode/src/lib/index.ts
+++ b/packages/barqode/src/lib/index.ts
@@ -1 +1,5 @@
-// Reexport your entry components here
+export { default as BarqodeCapture } from "./components/barqode-capture.svelte";
+export { default as BarqodeDropZone } from "./components/barqode-drop-zone.svelte";
+export { default as BarqodeStream } from "./components/barqode-stream.svelte";
+
+export type { DetectedBarcode, BarcodeFormat, Point2D, StreamProps } from "./components/types.js";
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 5b9b482..4bfe73b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -12,7 +12,7 @@ importers:
specifier: ^2.27.10
version: 2.27.10
'@eslint/js':
- specifier: ^9.12.0
+ specifier: ^9.16.0
version: 9.16.0
'@svitejs/changesets-changelog-github-compact':
specifier: ^1.2.0
@@ -21,16 +21,16 @@ importers:
specifier: ^22.10.1
version: 22.10.1
'@typescript-eslint/eslint-plugin':
- specifier: ^8.10.0
+ specifier: ^8.17.0
version: 8.17.0(@typescript-eslint/parser@8.17.0(eslint@9.16.0(jiti@2.4.1))(typescript@5.7.2))(eslint@9.16.0(jiti@2.4.1))(typescript@5.7.2)
'@typescript-eslint/scope-manager':
- specifier: ^8.10.0
+ specifier: ^8.17.0
version: 8.17.0
'@typescript-eslint/utils':
- specifier: ^8.10.0
+ specifier: ^8.17.0
version: 8.17.0(eslint@9.16.0(jiti@2.4.1))(typescript@5.7.2)
eslint:
- specifier: ^9.0.0
+ specifier: ^9.16.0
version: 9.16.0(jiti@2.4.1)
eslint-config-prettier:
specifier: ^9.1.0
@@ -39,32 +39,32 @@ importers:
specifier: ^2.46.1
version: 2.46.1(eslint@9.16.0(jiti@2.4.1))(svelte@5.4.0)
globals:
- specifier: ^15.11.0
+ specifier: ^15.13.0
version: 15.13.0
prettier:
- specifier: ^3.3.3
+ specifier: ^3.4.1
version: 3.4.1
prettier-plugin-svelte:
specifier: ^3.3.2
version: 3.3.2(prettier@3.4.1)(svelte@5.4.0)
prettier-plugin-tailwindcss:
- specifier: ^0.6.8
+ specifier: ^0.6.9
version: 0.6.9(prettier-plugin-svelte@3.3.2(prettier@3.4.1)(svelte@5.4.0))(prettier@3.4.1)
svelte:
- specifier: ^5.2.11
+ specifier: ^5.4.0
version: 5.4.0
svelte-eslint-parser:
specifier: ^0.43.0
version: 0.43.0(svelte@5.4.0)
typescript:
- specifier: ^5.6.3
+ specifier: ^5.7.2
version: 5.7.2
typescript-eslint:
- specifier: ^8.10.0
+ specifier: ^8.17.0
version: 8.17.0(eslint@9.16.0(jiti@2.4.1))(typescript@5.7.2)
wrangler:
specifier: ^3.91.0
- version: 3.91.0(@cloudflare/workers-types@4.20241127.0)
+ version: 3.91.0(@cloudflare/workers-types@4.20241202.0)
docs:
devDependencies:
@@ -73,16 +73,19 @@ importers:
version: 0.0.5(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(bits-ui@1.0.0-next.65(svelte@5.4.0))(svelte@5.4.0)(tailwindcss@4.0.0-beta.4)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
'@sveltejs/adapter-cloudflare':
specifier: ^4.8.0
- version: 4.8.0(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(wrangler@3.91.0(@cloudflare/workers-types@4.20241127.0))
+ version: 4.8.0(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(wrangler@3.91.0(@cloudflare/workers-types@4.20241202.0))
'@sveltejs/kit':
- specifier: ^2.0.0
+ specifier: ^2.9.0
version: 2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
'@sveltejs/vite-plugin-svelte':
- specifier: ^4.0.0
+ specifier: ^4.0.2
version: 4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
'@tailwindcss/vite':
specifier: 4.0.0-beta.4
version: 4.0.0-beta.4(postcss-load-config@3.1.4(postcss@8.4.49))(postcss@8.4.49)(svelte@5.4.0)(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
+ barqode:
+ specifier: workspace:^
+ version: link:../packages/barqode
mdsx:
specifier: ^0.0.6
version: 0.0.6(svelte@5.4.0)
@@ -90,10 +93,10 @@ importers:
specifier: ^3.0.0
version: 3.0.0(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
svelte:
- specifier: ^5.2.11
+ specifier: ^5.4.0
version: 5.4.0
svelte-check:
- specifier: ^4.0.0
+ specifier: ^4.1.0
version: 4.1.0(svelte@5.4.0)(typescript@5.7.2)
svelte-preprocess:
specifier: ^6.0.3
@@ -102,43 +105,53 @@ importers:
specifier: 4.0.0-beta.4
version: 4.0.0-beta.4
typescript:
- specifier: ^5.0.0
+ specifier: ^5.7.2
version: 5.7.2
velite:
specifier: ^0.2.1
version: 0.2.1(acorn@8.14.0)
vite:
- specifier: ^5.0.11
+ specifier: ^5.4.11
version: 5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)
packages/barqode:
+ dependencies:
+ barcode-detector:
+ specifier: ^2.3.1
+ version: 2.3.1
+ runed:
+ specifier: ^0.16.1
+ version: 0.16.1(svelte@5.4.0)
+ webrtc-adapter:
+ specifier: ^9.0.1
+ version: 9.0.1
devDependencies:
'@sveltejs/adapter-auto':
- specifier: ^3.0.0
+ specifier: ^3.3.1
version: 3.3.1(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))
'@sveltejs/kit':
- specifier: ^2.0.0
+ specifier: ^2.9.0
version: 2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
'@sveltejs/package':
- specifier: ^2.0.0
+ specifier: ^2.3.7
version: 2.3.7(svelte@5.4.0)(typescript@5.7.2)
'@sveltejs/vite-plugin-svelte':
- specifier: ^4.0.0
+ specifier: ^4.0.2
version: 4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
publint:
- specifier: ^0.2.0
+ specifier: ^0.2.12
version: 0.2.12
svelte:
- specifier: ^5.0.0
+ specifier: ^5.4.0
version: 5.4.0
svelte-check:
- specifier: ^4.0.0
+ specifier: ^4.1.0
version: 4.1.0(svelte@5.4.0)(typescript@5.7.2)
typescript:
- specifier: ^5.0.0
+ specifier: ^5.7.2
version: 5.7.2
vite:
- specifier: ^5.0.11
+ specifier: ^5.4.11
version: 5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)
packages:
@@ -247,8 +260,8 @@ packages:
resolution: {integrity: sha512-eP6Ir45uPbKnpADVzUCtkRUYxYxjB1Ew6n/whTJvHu8H4m93USHAceCMm736VBZdlxuhXXUjEP3fCUxKPn+cfw==}
engines: {node: '>=16.7.0'}
- '@cloudflare/workers-types@4.20241127.0':
- resolution: {integrity: sha512-UqlvtqV8eI0CdPR7nxlbVlE52+lcjHvGdbYXEPwisy23+39RsFV7OOy0da0moJAhqnL2OhDmWTOaKdsVcPHiJQ==}
+ '@cloudflare/workers-types@4.20241202.0':
+ resolution: {integrity: sha512-ts4JD6Wih62SDmlc+OcnN1Db/DgEBcl+BUpJr7ht7pgWP81PCLyPcomgDXIeAqt2NLiOIOMMkYQZ1ZtWDo3/8A==}
'@cspotcode/source-map-support@0.8.1':
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
@@ -1152,6 +1165,12 @@ packages:
'@types/debug@4.1.12':
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
+ '@types/dom-webcodecs@0.1.11':
+ resolution: {integrity: sha512-yPEZ3z7EohrmOxbk/QTAa0yonMFkNkjnVXqbGb7D4rMr+F1dGQ8ZUFxXkyLLJuiICPejZ0AZE9Rrk9wUCczx4A==}
+
+ '@types/emscripten@1.39.13':
+ resolution: {integrity: sha512-cFq+fO/isvhvmuP/+Sl4K4jtU6E23DoivtbO4r50e3odaxAiVdbfSYRDdJ4gCdxx+3aRjhphS5ZMwIH4hFy/Cw==}
+
'@types/estree-jsx@1.0.5':
resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==}
@@ -1318,6 +1337,9 @@ packages:
balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+ barcode-detector@2.3.1:
+ resolution: {integrity: sha512-D9KEtrquS1tmBZduxBZl8qublIKnRrFqD8TAHDYcLCyrHQBo+vitIxmjMJ61LvXjXyAMalOlO7q0Oh/9Rl2PbQ==}
+
better-path-resolve@1.0.0:
resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==}
engines: {node: '>=4'}
@@ -1489,8 +1511,8 @@ packages:
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
engines: {node: '>=8'}
- dotenv@16.4.5:
- resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==}
+ dotenv@16.4.6:
+ resolution: {integrity: sha512-JhcR/+KIjkkjiU8yEpaB/USlzVi3i5whwOjpIRNGi9svKEXZSe+Qp6IWAjFjv+2GViAoDRCUv/QLNziQxsLqDg==}
engines: {node: '>=12'}
emoji-regex-xs@1.0.0:
@@ -2645,6 +2667,11 @@ packages:
peerDependencies:
svelte: ^5.0.0-next.1
+ runed@0.16.1:
+ resolution: {integrity: sha512-k9ylt7sfEQiqOo2FmuilkLSk92pDzMSeVHFb8aPJGFPQPG9ErUxhfcHQwnmUhT03F8oQeO6bKB/TDoPKhdXbTA==}
+ peerDependencies:
+ svelte: ^5.0.0-next.1
+
sade@1.8.1:
resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==}
engines: {node: '>=6'}
@@ -2652,6 +2679,9 @@ packages:
safer-buffer@2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
+ sdp@3.2.0:
+ resolution: {integrity: sha512-d7wDPgDV3DDiqulJjKiV2865wKsJ34YI+NDREbm+FySq6WuKOikwyNQcm+doLAZ1O6ltdO0SeKle2xMpN3Brgw==}
+
selfsigned@2.4.1:
resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==}
engines: {node: '>=10'}
@@ -3013,6 +3043,10 @@ packages:
webidl-conversions@3.0.1:
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
+ webrtc-adapter@9.0.1:
+ resolution: {integrity: sha512-1AQO+d4ElfVSXyzNVTOewgGT/tAomwwztX/6e3totvyyzXPvXIIuUUjAmyZGbKBKbZOXauuJooZm3g6IuFuiNQ==}
+ engines: {node: '>=6.0.0', npm: '>=3.10.0'}
+
whatwg-url@5.0.0:
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
@@ -3087,6 +3121,9 @@ packages:
zwitch@2.0.4:
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
+ zxing-wasm@1.3.4:
+ resolution: {integrity: sha512-9l0QymyATF19FmI92QHe7Dayb+BUN7P7zFAt5iDgTnUf0dFWokz6GVA/W9EepjW5q8s3e89fIE/7uxpX27yqEQ==}
+
snapshots:
'@ampproject/remapping@2.3.0':
@@ -3271,7 +3308,7 @@ snapshots:
mime: 3.0.0
zod: 3.23.8
- '@cloudflare/workers-types@4.20241127.0': {}
+ '@cloudflare/workers-types@4.20241202.0': {}
'@cspotcode/source-map-support@0.8.1':
dependencies:
@@ -3841,13 +3878,13 @@ snapshots:
'@sveltejs/kit': 2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
import-meta-resolve: 4.1.0
- '@sveltejs/adapter-cloudflare@4.8.0(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(wrangler@3.91.0(@cloudflare/workers-types@4.20241127.0))':
+ '@sveltejs/adapter-cloudflare@4.8.0(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(wrangler@3.91.0(@cloudflare/workers-types@4.20241202.0))':
dependencies:
- '@cloudflare/workers-types': 4.20241127.0
+ '@cloudflare/workers-types': 4.20241202.0
'@sveltejs/kit': 2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
esbuild: 0.24.0
worktop: 0.8.0-next.18
- wrangler: 3.91.0(@cloudflare/workers-types@4.20241127.0)
+ wrangler: 3.91.0(@cloudflare/workers-types@4.20241202.0)
'@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))':
dependencies:
@@ -3903,7 +3940,7 @@ snapshots:
'@svitejs/changesets-changelog-github-compact@1.2.0':
dependencies:
'@changesets/get-github-info': 0.6.0
- dotenv: 16.4.5
+ dotenv: 16.4.6
transitivePeerDependencies:
- encoding
@@ -3995,6 +4032,10 @@ snapshots:
dependencies:
'@types/ms': 0.7.34
+ '@types/dom-webcodecs@0.1.11': {}
+
+ '@types/emscripten@1.39.13': {}
+
'@types/estree-jsx@1.0.5':
dependencies:
'@types/estree': 1.0.6
@@ -4164,6 +4205,11 @@ snapshots:
balanced-match@1.0.2: {}
+ barcode-detector@2.3.1:
+ dependencies:
+ '@types/dom-webcodecs': 0.1.11
+ zxing-wasm: 1.3.4
+
better-path-resolve@1.0.0:
dependencies:
is-windows: 1.0.2
@@ -4305,7 +4351,7 @@ snapshots:
dependencies:
path-type: 4.0.0
- dotenv@16.4.5: {}
+ dotenv@16.4.6: {}
emoji-regex-xs@1.0.0: {}
@@ -5880,12 +5926,19 @@ snapshots:
esm-env: 1.2.1
svelte: 5.4.0
+ runed@0.16.1(svelte@5.4.0):
+ dependencies:
+ esm-env: 1.2.1
+ svelte: 5.4.0
+
sade@1.8.1:
dependencies:
mri: 1.2.0
safer-buffer@2.1.2: {}
+ sdp@3.2.0: {}
+
selfsigned@2.4.1:
dependencies:
'@types/node-forge': 1.3.11
@@ -6237,6 +6290,10 @@ snapshots:
webidl-conversions@3.0.1: {}
+ webrtc-adapter@9.0.1:
+ dependencies:
+ sdp: 3.2.0
+
whatwg-url@5.0.0:
dependencies:
tr46: 0.0.3
@@ -6261,7 +6318,7 @@ snapshots:
mrmime: 2.0.0
regexparam: 3.0.0
- wrangler@3.91.0(@cloudflare/workers-types@4.20241127.0):
+ wrangler@3.91.0(@cloudflare/workers-types@4.20241202.0):
dependencies:
'@cloudflare/kv-asset-handler': 0.3.4
'@cloudflare/workers-shared': 0.9.0
@@ -6283,7 +6340,7 @@ snapshots:
workerd: 1.20241106.1
xxhash-wasm: 1.1.0
optionalDependencies:
- '@cloudflare/workers-types': 4.20241127.0
+ '@cloudflare/workers-types': 4.20241202.0
fsevents: 2.3.3
transitivePeerDependencies:
- bufferutil
@@ -6313,3 +6370,7 @@ snapshots:
zod@3.23.8: {}
zwitch@2.0.4: {}
+
+ zxing-wasm@1.3.4:
+ dependencies:
+ '@types/emscripten': 1.39.13
From c9334e1e0a074afd32f9b9fbaeba77ba9afc6897 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Olle=20M=C3=A5nsson?=
<31876997+ollema@users.noreply.github.com>
Date: Tue, 3 Dec 2024 12:22:50 +0100
Subject: [PATCH 02/25] add changeset
---
.changeset/gentle-lobsters-knock.md | 5 +++++
1 file changed, 5 insertions(+)
create mode 100644 .changeset/gentle-lobsters-knock.md
diff --git a/.changeset/gentle-lobsters-knock.md b/.changeset/gentle-lobsters-knock.md
new file mode 100644
index 0000000..37b3ddd
--- /dev/null
+++ b/.changeset/gentle-lobsters-knock.md
@@ -0,0 +1,5 @@
+---
+"barqode": minor
+---
+
+Initial release
From 28ba09a2c0ab2cb90597c55645966ff02ba11377 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Olle=20M=C3=A5nsson?=
<31876997+ollema@users.noreply.github.com>
Date: Tue, 3 Dec 2024 12:34:01 +0100
Subject: [PATCH 03/25] export all props
---
packages/barqode/src/lib/index.ts | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/packages/barqode/src/lib/index.ts b/packages/barqode/src/lib/index.ts
index 19b6167..d432389 100644
--- a/packages/barqode/src/lib/index.ts
+++ b/packages/barqode/src/lib/index.ts
@@ -2,4 +2,11 @@ export { default as BarqodeCapture } from "./components/barqode-capture.svelte";
export { default as BarqodeDropZone } from "./components/barqode-drop-zone.svelte";
export { default as BarqodeStream } from "./components/barqode-stream.svelte";
-export type { DetectedBarcode, BarcodeFormat, Point2D, StreamProps } from "./components/types.js";
+export type {
+ DetectedBarcode,
+ BarcodeFormat,
+ Point2D,
+ CaptureProps,
+ DropZoneProps,
+ StreamProps,
+} from "./components/types.js";
From 77a85e7cf71b20bdc01a4607cdd4231d5c78fee6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Olle=20M=C3=A5nsson?=
<31876997+ollema@users.noreply.github.com>
Date: Tue, 3 Dec 2024 12:47:50 +0100
Subject: [PATCH 04/25] reorder components listing
---
docs/src/content/index.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/src/content/index.md b/docs/src/content/index.md
index da049fb..514d906 100644
--- a/docs/src/content/index.md
+++ b/docs/src/content/index.md
@@ -11,8 +11,8 @@ Barqode started out as a port of [`vue-qrcode-reader`](https://github.com/gruhn/
## Components
- **`BarqodeStream`** - continuously scans frames from a camera stream.
-- **`BarqodeDropZone`** - drag & drop image files or web images.
- **`BarqodeCapture`** - traditional file upload field input with camera support.
+- **`BarqodeDropZone`** - drag & drop image files or web images.
## Features
From 891619845968e3beb21f6324d41caa916733eb1a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Olle=20M=C3=A5nsson?=
<31876997+ollema@users.noreply.github.com>
Date: Tue, 3 Dec 2024 13:44:30 +0100
Subject: [PATCH 05/25] improve element binding and naming
---
.../src/lib/components/barqode-stream.svelte | 70 +++++++------------
packages/barqode/src/lib/components/camera.ts | 56 +++++++--------
packages/barqode/src/lib/components/util.ts | 13 ----
3 files changed, 52 insertions(+), 87 deletions(-)
diff --git a/packages/barqode/src/lib/components/barqode-stream.svelte b/packages/barqode/src/lib/components/barqode-stream.svelte
index e515f9d..25e2f17 100644
--- a/packages/barqode/src/lib/components/barqode-stream.svelte
+++ b/packages/barqode/src/lib/components/barqode-stream.svelte
@@ -1,7 +1,6 @@
-
+
-
+
{@render children?.()}
diff --git a/packages/barqode/src/lib/components/camera.ts b/packages/barqode/src/lib/components/camera.ts
index d33f837..e32bdbc 100644
--- a/packages/barqode/src/lib/components/camera.ts
+++ b/packages/barqode/src/lib/components/camera.ts
@@ -13,7 +13,7 @@ import { assertNever } from "./util.js";
type StartTaskResult = {
type: "start";
data: {
- videoEl: HTMLVideoElement;
+ video: HTMLVideoElement;
stream: MediaStream;
capabilities: Partial
;
constraints: MediaTrackConstraints;
@@ -40,7 +40,7 @@ type CreateObjectURLCompat = (obj: MediaSource | Blob | MediaStream) => string;
/**
* Starts the camera with the given constraints and attaches the stream to the provided video element.
*
- * @param videoEl - The HTML video element to which the camera stream will be attached.
+ * @param video - The HTML video element to which the camera stream will be attached.
* @param constraints - The media track constraints to apply when starting the camera.
* @param torch - A boolean indicating whether the torch (flashlight) should be enabled if supported.
*
@@ -51,7 +51,7 @@ type CreateObjectURLCompat = (obj: MediaSource | Blob | MediaStream) => string;
* @throws StreamLoadTimeoutError - If the video element fails to load the camera stream within a 6-second timeout.
*/
async function runStartTask(
- videoEl: HTMLVideoElement,
+ video: HTMLVideoElement,
constraints: MediaTrackConstraints,
torch: boolean
): Promise {
@@ -81,24 +81,24 @@ async function runStartTask(
video: constraints,
});
- if (videoEl.srcObject !== undefined) {
- videoEl.srcObject = stream;
- } else if (videoEl.mozSrcObject !== undefined) {
- videoEl.mozSrcObject = stream;
+ if (video.srcObject !== undefined) {
+ video.srcObject = stream;
+ } else if (video.mozSrcObject !== undefined) {
+ video.mozSrcObject = stream;
} else if (window.URL.createObjectURL) {
- videoEl.src = (window.URL.createObjectURL as CreateObjectURLCompat)(stream);
+ video.src = (window.URL.createObjectURL as CreateObjectURLCompat)(stream);
} else if (window.webkitURL) {
- videoEl.src = (window.webkitURL.createObjectURL as CreateObjectURLCompat)(stream);
+ video.src = (window.webkitURL.createObjectURL as CreateObjectURLCompat)(stream);
} else {
- videoEl.src = stream.id;
+ video.src = stream.id;
}
// in the WeChat browser on iOS, 'loadeddata' event won't get fired unless video is explicitly triggered by play()
- videoEl.play();
+ video.play();
console.debug("[barqode] waiting for video element to load");
await Promise.race([
- eventOn(videoEl, "loadeddata"),
+ eventOn(video, "loadeddata"),
// on iOS devices in PWA mode, BarqodeStream works initially, but after killing and restarting the PWA,
// all video elements fail to load camera streams and never emit the `loadeddata` event.
@@ -132,7 +132,7 @@ async function runStartTask(
return {
type: "start",
data: {
- videoEl,
+ video,
stream,
capabilities,
constraints,
@@ -144,7 +144,7 @@ async function runStartTask(
/**
* Starts the camera with the given video element and settings.
*
- * @param videoEl - The HTML video element to which the camera stream will be attached.
+ * @param video - The HTML video element to which the camera stream will be attached.
* @param options.constraints - The media track constraints to apply when starting the camera.
* @param options.torch - A boolean indicating whether the torch (flashlight) should be enabled if supported.
* @param options.restart - A boolean indicating whether to restart the camera even if no settings changed. Defaults to false.
@@ -154,7 +154,7 @@ async function runStartTask(
* @throws Error - If something goes wrong with the camera task queue.
*/
export async function start(
- videoEl: HTMLVideoElement,
+ video: HTMLVideoElement,
{
constraints,
torch,
@@ -173,7 +173,7 @@ export async function start(
// we'll check if we can reuse the previous result
const {
data: {
- videoEl: prevVideoEl,
+ video: prevVideo,
stream: prevStream,
constraints: prevConstraints,
isTorchOn: prevIsTorchOn,
@@ -185,7 +185,7 @@ export async function start(
// which seem too much
if (
!restart &&
- videoEl === prevVideoEl &&
+ video === prevVideo &&
constraints === prevConstraints &&
torch === prevIsTorchOn
) {
@@ -193,13 +193,13 @@ export async function start(
return prevTaskResult;
}
// something changed, restart (stop then start)
- return runStopTask(prevVideoEl, prevStream, prevIsTorchOn).then(() =>
- runStartTask(videoEl, constraints, torch)
+ return runStopTask(prevVideo, prevStream, prevIsTorchOn).then(() =>
+ runStartTask(video, constraints, torch)
);
} else if (prevTaskResult.type === "stop" || prevTaskResult.type === "failed") {
// previous task is a stop/error task
// we can safely start
- return runStartTask(videoEl, constraints, torch);
+ return runStartTask(video, constraints, torch);
}
assertNever(prevTaskResult);
@@ -230,26 +230,26 @@ export async function start(
/**
* Stops the camera stream and cleans up associated resources.
*
- * @param videoEl - The HTML video element displaying the camera stream.
+ * @param video - The HTML video element displaying the camera stream.
* @param stream - The MediaStream object representing the active camera stream.
* @param isTorchOn - A boolean indicating whether the torch is currently enabled.
*
* @returns A promise that resolves to a `StopTaskResult` when the camera is fully stopped.
*/
async function runStopTask(
- videoEl: HTMLVideoElement,
+ video: HTMLVideoElement,
stream: MediaStream,
isTorchOn: boolean
): Promise {
console.debug("[barqode] stopping camera");
- videoEl.src = "";
- videoEl.srcObject = null;
- videoEl.load();
+ video.src = "";
+ video.srcObject = null;
+ video.load();
// wait for load() to emit error
// because src and srcObject are empty
- await eventOn(videoEl, "error");
+ await eventOn(video, "error");
for (const track of stream.getTracks()) {
// @ts-expect-error torch is not in the MediaTrackConstraints type but it should be?
@@ -280,9 +280,9 @@ export async function stop() {
return prevTaskResult;
}
const {
- data: { videoEl, stream, isTorchOn },
+ data: { video, stream, isTorchOn },
} = prevTaskResult;
- return runStopTask(videoEl, stream, isTorchOn);
+ return runStopTask(video, stream, isTorchOn);
});
// await the task queue asynchronously
const taskResult = await taskQueue;
diff --git a/packages/barqode/src/lib/components/util.ts b/packages/barqode/src/lib/components/util.ts
index 43d9475..295790e 100644
--- a/packages/barqode/src/lib/components/util.ts
+++ b/packages/barqode/src/lib/components/util.ts
@@ -26,19 +26,6 @@ export const idempotent = (action: (x: U[]) => T) => {
};
};
-/**
- * Asserts that a given condition is true. If the condition is false, it throws an error with the provided failure message.
- *
- * @param condition - The condition to assert.
- * @param failureMessage - Optional message to include in the error if the assertion fails.
- * @throws {Error} If the condition is false.
- */
-export function assert(condition: boolean, failureMessage?: string): asserts condition {
- if (condition === false) {
- throw new Error(failureMessage ?? "assertion failure");
- }
-}
-
/**
* Asserts that a given value is of type `never`, indicating that this code path should be unreachable.
* Throws an error if called, signaling a logic error in the code.
From cfc6a25f7daf20643ca41f2ab5af408a394b1a13 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Olle=20M=C3=A5nsson?=
<31876997+ollema@users.noreply.github.com>
Date: Tue, 3 Dec 2024 23:02:42 +0100
Subject: [PATCH 06/25] Update .changeset/gentle-lobsters-knock.md
Co-authored-by: Hunter Johnston <64506580+huntabyte@users.noreply.github.com>
---
.changeset/gentle-lobsters-knock.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.changeset/gentle-lobsters-knock.md b/.changeset/gentle-lobsters-knock.md
index 37b3ddd..389d6a1 100644
--- a/.changeset/gentle-lobsters-knock.md
+++ b/.changeset/gentle-lobsters-knock.md
@@ -1,5 +1,5 @@
---
-"barqode": minor
+"barqode": patch
---
Initial release
From f69ba8bbcd851bb9a331f259a2b666b57422a6d0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Olle=20M=C3=A5nsson?=
<31876997+ollema@users.noreply.github.com>
Date: Tue, 3 Dec 2024 23:04:15 +0100
Subject: [PATCH 07/25] use kebab-case
---
.../content/components/{BarqodeCapture.md => barqode-capture.md} | 0
.../components/{BarqodeDropZone.md => barqode-drop-zone.md} | 0
.../content/components/{BarqodeStream.md => barqode-stream.md} | 0
3 files changed, 0 insertions(+), 0 deletions(-)
rename docs/src/content/components/{BarqodeCapture.md => barqode-capture.md} (100%)
rename docs/src/content/components/{BarqodeDropZone.md => barqode-drop-zone.md} (100%)
rename docs/src/content/components/{BarqodeStream.md => barqode-stream.md} (100%)
diff --git a/docs/src/content/components/BarqodeCapture.md b/docs/src/content/components/barqode-capture.md
similarity index 100%
rename from docs/src/content/components/BarqodeCapture.md
rename to docs/src/content/components/barqode-capture.md
diff --git a/docs/src/content/components/BarqodeDropZone.md b/docs/src/content/components/barqode-drop-zone.md
similarity index 100%
rename from docs/src/content/components/BarqodeDropZone.md
rename to docs/src/content/components/barqode-drop-zone.md
diff --git a/docs/src/content/components/BarqodeStream.md b/docs/src/content/components/barqode-stream.md
similarity index 100%
rename from docs/src/content/components/BarqodeStream.md
rename to docs/src/content/components/barqode-stream.md
From 55c1b854fbf4a8c5e5e4a57c1d76274334d2ac15 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Olle=20M=C3=A5nsson?=
<31876997+ollema@users.noreply.github.com>
Date: Tue, 3 Dec 2024 23:10:38 +0100
Subject: [PATCH 08/25] rearrange usage section and remove distracting styling
---
.../src/content/components/barqode-capture.md | 44 +++---
.../content/components/barqode-drop-zone.md | 78 ++++------
docs/src/content/components/barqode-stream.md | 136 +++++++++---------
3 files changed, 114 insertions(+), 144 deletions(-)
diff --git a/docs/src/content/components/barqode-capture.md b/docs/src/content/components/barqode-capture.md
index e07a27c..6759c1f 100644
--- a/docs/src/content/components/barqode-capture.md
+++ b/docs/src/content/components/barqode-capture.md
@@ -14,6 +14,24 @@ The `BarqodeCapture` component is a simple file input with the `capture` attribu
+## Usage
+
+```svelte
+
+
+
+
+Last detected: {result}
+```
+
## Props
### `formats`
@@ -56,32 +74,6 @@ By default, the following attributes are set:
- `capture="environment"`. This tells the browser to open the camera when the input is clicked on mobile devices. You can choose between `user` and `environment`, which opens the front and back camera respectively. You can also disable this functionality by setting it to `null`.
- `multiple`. This allows the user to upload multiple files at once. You can disable this by settings this to `false`.
-## Usage
-
-```svelte
-
-
-
-
-
- Last detected: {result}
-
-
-
-```
-
## Browser Support
This component depends on the [File Reader API](https://developer.mozilla.org/en-US/docs/Web/API/FileReader) which is widely supported in modern browsers.
diff --git a/docs/src/content/components/barqode-drop-zone.md b/docs/src/content/components/barqode-drop-zone.md
index f6d4ea0..7c25459 100644
--- a/docs/src/content/components/barqode-drop-zone.md
+++ b/docs/src/content/components/barqode-drop-zone.md
@@ -14,6 +14,37 @@ You can drag-and-drop image files from your desktop or images embedded into othe
+## Usage
+
+```svelte
+
+
+
+ Drop an image here to detect QR-codes
+
+
+Last detected: {result}
+
+
+```
+
## Props
### `formats`
@@ -58,53 +89,6 @@ Callback function that is called when an error occurs.
TODO: insert link to errors.
-## Usage
-
-```svelte
-
-
-
- Drop an image here to detect QR-codes
-
-
-
- Last detected: {result}
-
-
-
-```
-
## Browser Support
This component depends on the [File Reader API](https://developer.mozilla.org/en-US/docs/Web/API/FileReader) which is widely supported in modern browsers.
diff --git a/docs/src/content/components/barqode-stream.md b/docs/src/content/components/barqode-stream.md
index 0d3ec06..cf53926 100644
--- a/docs/src/content/components/barqode-stream.md
+++ b/docs/src/content/components/barqode-stream.md
@@ -15,6 +15,71 @@ The `BarqodeStream` component continuously scans frames from a camera stream and
+## Usage
+
+```svelte
+
+
+
+
+ {#if loading}
+ Loading...
+ {/if}
+
+
+
+Last detected: {result}
+
+
+```
+
## Props
### `constraints`
@@ -150,77 +215,6 @@ If you scan the same barcode multiple times in a row, `onDetect` is still only c
-## Usage
-
-```svelte
-
-
-
-
- {#if loading}
- Loading...
- {/if}
-
-
-
-
- Last detected: {result}
-
-
-
-```
-
## Browser Support
This component depends on the [Media Capture and Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Media_Capture_and_Streams_API) which is widely supported in modern browsers.
From 91c65714c0b5c8c7beffcd52ea054f5deeedd565 Mon Sep 17 00:00:00 2001
From: Hunter Johnston
Date: Tue, 3 Dec 2024 17:14:43 -0600
Subject: [PATCH 09/25] some things
---
packages/barqode/README.md | 59 +------------------
.../lib/components/barqode-drop-zone.svelte | 4 +-
.../src/lib/components/barqode-stream.svelte | 17 +++---
3 files changed, 11 insertions(+), 69 deletions(-)
diff --git a/packages/barqode/README.md b/packages/barqode/README.md
index 16c70df..b907ada 100644
--- a/packages/barqode/README.md
+++ b/packages/barqode/README.md
@@ -1,58 +1 @@
-# create-svelte
-
-Everything you need to build a Svelte library, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/main/packages/create-svelte).
-
-Read more about creating a library [in the docs](https://svelte.dev/docs/kit/packaging).
-
-## Creating a project
-
-If you're seeing this, you've probably already done this step. Congrats!
-
-```bash
-# create a new project in the current directory
-npx sv create
-
-# create a new project in my-app
-npx sv create my-app
-```
-
-## Developing
-
-Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
-
-```bash
-npm run dev
-
-# or start the server and open the app in a new browser tab
-npm run dev -- --open
-```
-
-Everything inside `src/lib` is part of your library, everything inside `src/routes` can be used as a showcase or preview app.
-
-## Building
-
-To build your library:
-
-```bash
-npm run package
-```
-
-To create a production version of your showcase app:
-
-```bash
-npm run build
-```
-
-You can preview the production build with `npm run preview`.
-
-> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
-
-## Publishing
-
-Go into the `package.json` and give your package the desired name through the `"name"` option. Also consider adding a `"license"` field and point it to a `LICENSE` file which you can create from a template (one popular option is the [MIT license](https://opensource.org/license/mit/)).
-
-To publish your library to [npm](https://www.npmjs.com):
-
-```bash
-npm publish
-```
+# Barqode
diff --git a/packages/barqode/src/lib/components/barqode-drop-zone.svelte b/packages/barqode/src/lib/components/barqode-drop-zone.svelte
index 1a6abb7..70fbbec 100644
--- a/packages/barqode/src/lib/components/barqode-drop-zone.svelte
+++ b/packages/barqode/src/lib/components/barqode-drop-zone.svelte
@@ -1,9 +1,9 @@
From a1221570d4d629317b7565f11a3463150c0b8342 Mon Sep 17 00:00:00 2001
From: Hunter Johnston
Date: Tue, 3 Dec 2024 17:26:19 -0600
Subject: [PATCH 10/25] some more ocd things
---
.../lib/components/barqode-drop-zone.svelte | 12 ++---
.../src/lib/components/barqode-stream.svelte | 45 ++++++++++---------
.../barqode/src/lib/components/callforth.ts | 18 ++++----
packages/barqode/src/lib/components/camera.ts | 6 +--
.../barqode/src/lib/components/scanner.ts | 41 ++++++++---------
5 files changed, 60 insertions(+), 62 deletions(-)
diff --git a/packages/barqode/src/lib/components/barqode-drop-zone.svelte b/packages/barqode/src/lib/components/barqode-drop-zone.svelte
index 70fbbec..bf40ad2 100644
--- a/packages/barqode/src/lib/components/barqode-drop-zone.svelte
+++ b/packages/barqode/src/lib/components/barqode-drop-zone.svelte
@@ -10,20 +10,20 @@
children,
}: DropZoneProps = $props();
- const onDetectFile = async (promise: Promise) => {
+ async function onDetectFile(promise: Promise) {
try {
const detectedCodes = await promise;
onDetect?.(detectedCodes);
} catch (error) {
onError?.(error as Error);
}
- };
+ }
- const onDragOverChange = (isDraggingOver: boolean) => {
+ async function onDragOverChange(isDraggingOver: boolean) {
onDragover?.(isDraggingOver);
- };
+ }
- const onDrop = async (event: DragEvent) => {
+ async function onDrop(event: DragEvent) {
if (!event.dataTransfer) return;
onDragOverChange(false);
@@ -38,7 +38,7 @@
if (droppedUrl !== "") {
onDetectFile(processUrl(droppedUrl, formats));
}
- };
+ }
function handleDrop(e: DragEvent) {
e.preventDefault();
diff --git a/packages/barqode/src/lib/components/barqode-stream.svelte b/packages/barqode/src/lib/components/barqode-stream.svelte
index 777176b..fcdcd41 100644
--- a/packages/barqode/src/lib/components/barqode-stream.svelte
+++ b/packages/barqode/src/lib/components/barqode-stream.svelte
@@ -39,28 +39,7 @@
const settings = cameraSettings;
const ctx = pauseFrame.getContext("2d")!;
- if (settings.shouldStream) {
- cameraController.stop();
- cameraActive = false;
-
- try {
- cameraController
- .start(video, settings)
- .then((capabilities) => {
- if (isMounted) {
- cameraActive = true;
- onCameraOn?.(capabilities);
- } else {
- cameraController.stop();
- }
- })
- .catch((error) => {
- onError?.(error);
- });
- } catch (error) {
- onError?.(error as Error);
- }
- } else {
+ if (!settings.shouldStream) {
pauseFrame.width = video.videoWidth;
pauseFrame.height = video.videoHeight;
ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
@@ -68,6 +47,28 @@
cameraController.stop();
cameraActive = false;
onCameraOff?.();
+ return;
+ }
+
+ cameraController.stop();
+ cameraActive = false;
+
+ try {
+ cameraController
+ .start(video, settings)
+ .then((capabilities) => {
+ if (isMounted) {
+ cameraActive = true;
+ onCameraOn?.(capabilities);
+ } else {
+ cameraController.stop();
+ }
+ })
+ .catch((error) => {
+ onError?.(error);
+ });
+ } catch (error) {
+ onError?.(error as Error);
}
}
);
diff --git a/packages/barqode/src/lib/components/callforth.ts b/packages/barqode/src/lib/components/callforth.ts
index 1c40cb8..79f9d23 100644
--- a/packages/barqode/src/lib/components/callforth.ts
+++ b/packages/barqode/src/lib/components/callforth.ts
@@ -8,14 +8,14 @@
* @param successEvent - The name of the event that will resolve the Promise.
* @param errorEvent - The name of the event that will reject the Promise. Defaults to 'error'.
*
- * @returns A Promise that resolves with the event object when the successEvent is triggered,
- * or rejects with the event object when the errorEvent is triggered.
+ * @returns A Promise that resolves with the event object when the successEvent is
+ * triggered, or rejects with the event object when the errorEvent is triggered.
*/
-export const eventOn = (
+export function eventOn(
eventTarget: EventTarget,
successEvent: string,
errorEvent = "error"
-): Promise => {
+): Promise {
let $resolve: (value: Event) => void;
let $reject: (reason?: Event) => void;
@@ -35,15 +35,15 @@ export const eventOn = (
});
return promise;
-};
+}
/**
* Creates a promise that resolves after a specified number of milliseconds.
*
- * @param milliseconds - The number of milliseconds to wait before the promise resolves.
+ * @param ms - The number of milliseconds to wait before the promise resolves.
*
* @returns A promise that resolves after the specified delay.
*/
-export const timeout = (milliseconds: number) => {
- return new Promise((resolve: (value: unknown) => void) => setTimeout(resolve, milliseconds));
-};
+export function sleep(ms: number) {
+ return new Promise((resolve: (value: unknown) => void) => setTimeout(resolve, ms));
+}
diff --git a/packages/barqode/src/lib/components/camera.ts b/packages/barqode/src/lib/components/camera.ts
index e32bdbc..0328538 100644
--- a/packages/barqode/src/lib/components/camera.ts
+++ b/packages/barqode/src/lib/components/camera.ts
@@ -6,7 +6,7 @@ import {
InsecureContextError,
StreamLoadTimeoutError,
} from "./errors.js";
-import { eventOn, timeout } from "./callforth.js";
+import { eventOn, sleep } from "./callforth.js";
import shimGetUserMedia from "./shimGetUserMedia.js";
import { assertNever } from "./util.js";
@@ -104,7 +104,7 @@ async function runStartTask(
// all video elements fail to load camera streams and never emit the `loadeddata` event.
// looks like this is related to a WebKit issue (see #298). no workarounds at the moment.
// to at least detect this situation, we throw an error if the event has not been emitted after a 6 second timeout.
- timeout(6_000).then(() => {
+ sleep(6_000).then(() => {
throw new StreamLoadTimeoutError();
}),
]);
@@ -113,7 +113,7 @@ async function runStartTask(
// according to: https://oberhofer.co/mediastreamtrack-and-its-capabilities/#queryingcapabilities
// on some devices, getCapabilities only returns a non-empty object after some delay.
// there is no appropriate event so we have to add a constant timeout
- await timeout(500);
+ await sleep(500);
const [track] = stream.getVideoTracks();
diff --git a/packages/barqode/src/lib/components/scanner.ts b/packages/barqode/src/lib/components/scanner.ts
index a5f1c3c..1f9c7ed 100644
--- a/packages/barqode/src/lib/components/scanner.ts
+++ b/packages/barqode/src/lib/components/scanner.ts
@@ -68,24 +68,21 @@ export async function setScanningFormats(formats: BarcodeFormat[]) {
type ScanHandler = (_: DetectedBarcode[]) => void;
+type KeepScanningOptions = {
+ detectHandler: ScanHandler;
+ locateHandler: ScanHandler;
+ minDelay: number;
+ formats: BarcodeFormat[];
+};
+
/**
* Continuously extracts frames from camera stream and tries to read
* potentially pictured QR codes.
*/
-export const keepScanning = async (
+export async function keepScanning(
videoElement: HTMLVideoElement,
- {
- detectHandler,
- locateHandler,
- minDelay,
- formats,
- }: {
- detectHandler: ScanHandler;
- locateHandler: ScanHandler;
- minDelay: number;
- formats: BarcodeFormat[];
- }
-) => {
+ { detectHandler, locateHandler, minDelay, formats }: KeepScanningOptions
+) {
console.debug("[barqode] start scanning");
await setScanningFormats(formats);
@@ -180,9 +177,9 @@ export const keepScanning = async (
contentBefore: [],
lastScanHadContent: false,
})(performance.now());
-};
+}
-const imageElementFromUrl = async (url: string) => {
+async function imageElementFromUrl(url: string) {
if (url.startsWith("http") && url.includes(location.host) === false) {
throw new DropImageFetchError();
}
@@ -193,12 +190,12 @@ const imageElementFromUrl = async (url: string) => {
await eventOn(image, "load");
return image;
-};
+}
-export const processFile = async (
+export async function processFile(
file: File,
formats: BarcodeFormat[] = ["qr_code"]
-): Promise => {
+): Promise {
// To scan files/urls we use one-off `BarcodeDetector` instances,
// since we don't scan as often as camera frames. Note, that we
// always use the polyfill. This is because (at the time of writing)
@@ -207,12 +204,12 @@ export const processFile = async (
const barcodeDetector = new BarcodeDetector({ formats });
return await barcodeDetector.detect(file);
-};
+}
-export const processUrl = async (
+export async function processUrl(
url: string,
formats: BarcodeFormat[] = ["qr_code"]
-): Promise => {
+): Promise {
// To scan files/urls we use one-off `BarcodeDetector` instances,
// since we don't scan as often as camera frames. Note, that we
// always use the polyfill. This is because (at the time of writing)
@@ -223,4 +220,4 @@ export const processUrl = async (
const image = await imageElementFromUrl(url);
return await barcodeDetector.detect(image);
-};
+}
From 672e7dc94981bda301a89b9e64ab56a7a5ec80f9 Mon Sep 17 00:00:00 2001
From: Hunter Johnston
Date: Tue, 3 Dec 2024 17:31:24 -0600
Subject: [PATCH 11/25] more stuff
---
.../components/{barqode-drop-zone.md => barqode-dropzone.md} | 2 +-
docs/src/content/getting-started.md | 4 ----
docs/src/content/index.md | 2 +-
.../{barqode-drop-zone.svelte => barqode-dropzone.svelte} | 0
packages/barqode/src/lib/index.ts | 2 +-
5 files changed, 3 insertions(+), 7 deletions(-)
rename docs/src/content/components/{barqode-drop-zone.md => barqode-dropzone.md} (99%)
rename packages/barqode/src/lib/components/{barqode-drop-zone.svelte => barqode-dropzone.svelte} (100%)
diff --git a/docs/src/content/components/barqode-drop-zone.md b/docs/src/content/components/barqode-dropzone.md
similarity index 99%
rename from docs/src/content/components/barqode-drop-zone.md
rename to docs/src/content/components/barqode-dropzone.md
index 7c25459..1147326 100644
--- a/docs/src/content/components/barqode-drop-zone.md
+++ b/docs/src/content/components/barqode-dropzone.md
@@ -1,5 +1,5 @@
---
-title: BarqodeDropZone
+title: BarqodeDropzone
description: File input with camera support on mobile.
section: Components
---
diff --git a/docs/src/content/getting-started.md b/docs/src/content/getting-started.md
index c755c5e..10bb4fd 100644
--- a/docs/src/content/getting-started.md
+++ b/docs/src/content/getting-started.md
@@ -12,10 +12,6 @@ Install the package using your preferred package manager:
```bash
npm install barqode
-# or
-pnpm add barqode
-# or
-yarn add barqode
```
## Basic Usage
diff --git a/docs/src/content/index.md b/docs/src/content/index.md
index 514d906..41855a9 100644
--- a/docs/src/content/index.md
+++ b/docs/src/content/index.md
@@ -12,7 +12,7 @@ Barqode started out as a port of [`vue-qrcode-reader`](https://github.com/gruhn/
- **`BarqodeStream`** - continuously scans frames from a camera stream.
- **`BarqodeCapture`** - traditional file upload field input with camera support.
-- **`BarqodeDropZone`** - drag & drop image files or web images.
+- **`BarqodeDropzone`** - drag & drop image files or web images.
## Features
diff --git a/packages/barqode/src/lib/components/barqode-drop-zone.svelte b/packages/barqode/src/lib/components/barqode-dropzone.svelte
similarity index 100%
rename from packages/barqode/src/lib/components/barqode-drop-zone.svelte
rename to packages/barqode/src/lib/components/barqode-dropzone.svelte
diff --git a/packages/barqode/src/lib/index.ts b/packages/barqode/src/lib/index.ts
index d432389..dccf6a4 100644
--- a/packages/barqode/src/lib/index.ts
+++ b/packages/barqode/src/lib/index.ts
@@ -1,5 +1,5 @@
export { default as BarqodeCapture } from "./components/barqode-capture.svelte";
-export { default as BarqodeDropZone } from "./components/barqode-drop-zone.svelte";
+export { default as BarqodeDropzone } from "./components/barqode-dropzone.svelte";
export { default as BarqodeStream } from "./components/barqode-stream.svelte";
export type {
From 44eced30e235d1afb1e452a73d37fa9d6c6949d3 Mon Sep 17 00:00:00 2001
From: Hunter Johnston
Date: Tue, 3 Dec 2024 17:31:43 -0600
Subject: [PATCH 12/25] m
---
docs/src/lib/navigation.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/src/lib/navigation.ts b/docs/src/lib/navigation.ts
index d190879..8b63a54 100644
--- a/docs/src/lib/navigation.ts
+++ b/docs/src/lib/navigation.ts
@@ -1,4 +1,4 @@
-import { createNavigation } from "@svecodocs/kit";
+import { defineNavigation } from "@svecodocs/kit";
import ChalkboardTeacher from "phosphor-svelte/lib/ChalkboardTeacher";
import RocketLaunch from "phosphor-svelte/lib/RocketLaunch";
import Tag from "phosphor-svelte/lib/Tag";
@@ -20,7 +20,7 @@ const demos = allDocs
href: `/docs/${doc.slug}`,
}));
-export const navigation = createNavigation({
+export const navigation = defineNavigation({
anchors: [
{
title: "Introduction",
From eebacdd794f31c7935c1e1bd365f220394b95212 Mon Sep 17 00:00:00 2001
From: Hunter Johnston
Date: Tue, 3 Dec 2024 17:36:49 -0600
Subject: [PATCH 13/25] still want to do some more
---
packages/barqode/src/lib/components/barqode-capture.svelte | 2 +-
packages/barqode/src/lib/components/barqode-dropzone.svelte | 6 +++---
packages/barqode/src/lib/components/barqode-stream.svelte | 4 ++--
packages/barqode/src/lib/components/types.ts | 2 +-
packages/barqode/src/lib/index.ts | 2 +-
.../barqode/src/lib/{components => internal}/callforth.ts | 0
packages/barqode/src/lib/{components => internal}/camera.ts | 0
packages/barqode/src/lib/{components => internal}/errors.ts | 0
.../barqode/src/lib/{components => internal}/global.d.ts | 0
.../barqode/src/lib/{components => internal}/scanner.ts | 0
.../shimGetUserMedia.ts => internal/shim-get-user-media.ts} | 0
packages/barqode/src/lib/{components => internal}/util.ts | 0
12 files changed, 8 insertions(+), 8 deletions(-)
rename packages/barqode/src/lib/{components => internal}/callforth.ts (100%)
rename packages/barqode/src/lib/{components => internal}/camera.ts (100%)
rename packages/barqode/src/lib/{components => internal}/errors.ts (100%)
rename packages/barqode/src/lib/{components => internal}/global.d.ts (100%)
rename packages/barqode/src/lib/{components => internal}/scanner.ts (100%)
rename packages/barqode/src/lib/{components/shimGetUserMedia.ts => internal/shim-get-user-media.ts} (100%)
rename packages/barqode/src/lib/{components => internal}/util.ts (100%)
diff --git a/packages/barqode/src/lib/components/barqode-capture.svelte b/packages/barqode/src/lib/components/barqode-capture.svelte
index d7da98e..f1449c1 100644
--- a/packages/barqode/src/lib/components/barqode-capture.svelte
+++ b/packages/barqode/src/lib/components/barqode-capture.svelte
@@ -1,5 +1,5 @@
You can drag-and-drop image files from your desktop or images embedded into other web pages anywhere in the area the component occupies. The images are directly scanned and positive results are indicated by the `onDetect` callback.
diff --git a/docs/src/lib/components/demos/barqode-drop-zone.svelte b/docs/src/lib/components/demos/barqode-dropzone.svelte
similarity index 87%
rename from docs/src/lib/components/demos/barqode-drop-zone.svelte
rename to docs/src/lib/components/demos/barqode-dropzone.svelte
index 19a950f..666da85 100644
--- a/docs/src/lib/components/demos/barqode-drop-zone.svelte
+++ b/docs/src/lib/components/demos/barqode-dropzone.svelte
@@ -1,5 +1,5 @@
-
-The `BarqodeCapture` component is a simple file input with the `capture` attribute set to `environment` which allows users to take a picture with their camera.
-
-## Demo
-
-
-
-## Usage
-
-```svelte
-
-
-
-
-Last detected: {result}
-```
-
-## Props
-
-### `formats`
-
-Type: [`BarcodeFormat[]`](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector)
-
-Default: `["qr_code"]`
-
-Configure the barcode formats to detect. By default, only QR codes are detected.
-
-If you want to detect multiple formats, pass an array of formats:
-
-```svelte
-
-```
-
-Under the hood, the standard [BarcodeDetector API](https://developer.mozilla.org/en-US/docs/Web/API/BarcodeDetector) is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation.
-
-Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format `'qr_code'` but the you select the formats `['qr_code', 'aztec']`.
-
-### `onDetect`
-
-Type: `(detectedCodes: DetectedBarcode[]) => void`
-
-Callback function that is called when a barcode is detected.
-
-It receives an array of [detected barcodes](https://developer.mozilla.org/en-US/docs/Web/API/BarcodeDetector/detect#return_value), one callback per image uploaded.
-
-If not barcode is detected, the array will be empty.
-
-### Other props
-
-The `BarqodeCapture` component accepts all attributes that a standard `input` element accepts.
-
-By default, the following attributes are set:
-
-- `type="file"`. This is required to make the input a file input. You should not change this.
-- `name="image"`. This is the name of the file input.
-- `accept="image/*"`. This restricts the file types that can be uploaded to images.
-- `capture="environment"`. This tells the browser to open the camera when the input is clicked on mobile devices. You can choose between `user` and `environment`, which opens the front and back camera respectively. You can also disable this functionality by setting it to `null`.
-- `multiple`. This allows the user to upload multiple files at once. You can disable this by settings this to `false`.
-
-## Browser Support
-
-This component depends on the [File Reader API](https://developer.mozilla.org/en-US/docs/Web/API/FileReader) which is widely supported in modern browsers.
diff --git a/docs/src/content/components/barqode-dropzone.md b/docs/src/content/components/barqode-dropzone.md
index 815c887..8427ae0 100644
--- a/docs/src/content/components/barqode-dropzone.md
+++ b/docs/src/content/components/barqode-dropzone.md
@@ -1,6 +1,6 @@
---
title: BarqodeDropzone
-description: File input with camera support on mobile.
+description: Click to upload images, drag & drop or use your camera to scan.
section: Components
---
@@ -8,7 +8,7 @@ section: Components
import Demo from '$lib/components/demos/barqode-dropzone.svelte';
-You can drag-and-drop image files from your desktop or images embedded into other web pages anywhere in the area the component occupies. The images are directly scanned and positive results are indicated by the `onDetect` callback.
+This component functions as a file input with the `capture` attribute set to `environment` which allows users to take a picture with their camera. You can also drag-and-drop image files from your desktop or images embedded into other web pages anywhere in the area the component occupies. The images are directly scanned and positive results are indicated by the `onDetect` callback.
## Demo
@@ -18,7 +18,7 @@ You can drag-and-drop image files from your desktop or images embedded into othe
```svelte
-
- Drop an image here to detect QR-codes
-
+
+
+
+
Click to upload or drop an image here
+
+
+
Last detected: {result}
```
@@ -71,7 +89,7 @@ Type: `(detectedCodes: DetectedBarcode[]) => void`
Callback function that is called when a barcode is detected.
-It receives an array of [detected barcodes](https://developer.mozilla.org/en-US/docs/Web/API/BarcodeDetector/detect#return_value), one callback per image dropped.
+It receives an array of [detected barcodes](https://developer.mozilla.org/en-US/docs/Web/API/BarcodeDetector/detect#return_value), one callback per image.
If not barcode is detected, the array will be empty.
@@ -89,6 +107,18 @@ Callback function that is called when an error occurs.
TODO: insert link to errors.
+### Other props
+
+The `BarqodeDropzone` component accepts all attributes that a standard `input` element accepts.
+
+By default, the following attributes are set:
+
+- `type="file"`. This is required to make the input a file input. You should not change this.
+- `name="image"`. This is the name of the file input.
+- `accept="image/*"`. This restricts the file types that can be uploaded to images.
+- `capture="environment"`. This tells the browser to open the camera when the input is clicked on mobile devices. You can choose between `user` and `environment`, which opens the front and back camera respectively. You can also disable this functionality by setting it to `null`.
+- `multiple`. This allows the user to upload multiple files at once. You can disable this by settings this to `false`.
+
## Browser Support
This component depends on the [File Reader API](https://developer.mozilla.org/en-US/docs/Web/API/FileReader) which is widely supported in modern browsers.
diff --git a/docs/src/content/components/barqode-stream.md b/docs/src/content/components/barqode-stream.md
index cf53926..e2a3319 100644
--- a/docs/src/content/components/barqode-stream.md
+++ b/docs/src/content/components/barqode-stream.md
@@ -52,7 +52,7 @@ The `BarqodeStream` component continuously scans frames from a camera stream and
}
-
+
{#if loading}
Loading...
@@ -63,7 +63,7 @@ The `BarqodeStream` component continuously scans frames from a camera stream and
Last detected: {result}
diff --git a/docs/src/lib/components/demos/barqode-dropzone.svelte b/docs/src/lib/components/demos/barqode-dropzone.svelte
index 666da85..3ac448e 100644
--- a/docs/src/lib/components/demos/barqode-dropzone.svelte
+++ b/docs/src/lib/components/demos/barqode-dropzone.svelte
@@ -17,9 +17,13 @@
Detecting QR-codes
-
- Drop an image here to detect QR-codes
-
+
+
+
+
Click to upload or drop an image here
+
+
+
Last detected: {result}
@@ -31,19 +35,24 @@
margin-bottom: 1.25rem;
}
- .dropzone {
+ .barqode {
width: 100%;
- height: 200px;
+ aspect-ratio: 4 / 3;
border: 2px solid #2563eb;
- display: flex;
- justify-content: center;
- align-items: center;
}
.dragover {
border-color: white;
}
+ .instructions {
+ height: 100%;
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+
.result {
margin-top: 1.25rem;
}
diff --git a/docs/src/lib/components/demos/barqode-stream.svelte b/docs/src/lib/components/demos/barqode-stream.svelte
index 3597e0d..8073869 100644
--- a/docs/src/lib/components/demos/barqode-stream.svelte
+++ b/docs/src/lib/components/demos/barqode-stream.svelte
@@ -36,7 +36,7 @@
Detecting QR-codes
-
+
{#if loading}
Loading...
@@ -54,7 +54,7 @@
margin-bottom: 1.25rem;
}
- .scanner {
+ .barqode {
width: 100%;
aspect-ratio: 4 / 3;
}
diff --git a/docs/src/routes/api/search.json/search.json b/docs/src/routes/api/search.json/search.json
index b45d9ff..48c5b4a 100644
--- a/docs/src/routes/api/search.json/search.json
+++ b/docs/src/routes/api/search.json/search.json
@@ -9,7 +9,7 @@
"title": "Introduction",
"href": "/docs/index",
"description": "What is Barqode?",
- "content": "Barqode provides a set of Svelte components for detecting and decoding QR codes and various other barcode formats right in the browser. It's a comprehensive solution that supports both camera streams and static image processing. Barqode started out as a port of $2. Components BarqodeStream** - continuously scans frames from a camera stream. BarqodeDropZone** - drag & drop image files or web images. BarqodeCapture** - traditional file upload field input with camera support. Features Real-time scanning**. Detect codes from live camera stream. Multiple formats**. Support for QR codes and various barcode standards. Visual feedback**. Customizable canvas based tracking of detected codes. Cross-browser**. Works across modern browsers with a $2 if needed. Camera selection**. Choose between front/rear cameras. Torch control**. Control device flashlight where supported. Responsive**. Components adapt to fill available space. Error handling**. Comprehensive error handling for camera/detection issues. Usage Example import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .scanner { width: 100%; max-width: 600px; aspect-ratio: 4/3; } Browser Support The components rely primarily on the $2 and $2, with fallbacks where possible. While the core scanning functionality uses the native BarcodeDetector where available, it falls back to a $2 to ensure consistent behavior across browsers. For a detailed compatibility overview, check each component's documentation."
+ "content": "Barqode provides a set of Svelte components for detecting and decoding QR codes and various other barcode formats right in the browser. It's a comprehensive solution that supports both camera streams and static image processing. Barqode started out as a port of $2. Components BarqodeStream** - continuously scans frames from a camera stream. BarqodeDropzone** - drag & drop image files or web images. BarqodeCapture** - traditional file upload field input with camera support. Features Real-time scanning**. Detect codes from live camera stream. Multiple formats**. Support for QR codes and various barcode standards. Visual feedback**. Customizable canvas based tracking of detected codes. Cross-browser**. Works across modern browsers with a $2 if needed. Camera selection**. Choose between front/rear cameras. Torch control**. Control device flashlight where supported. Responsive**. Components adapt to fill available space. Error handling**. Comprehensive error handling for camera/detection issues. Usage Example import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .scanner { width: 100%; max-width: 600px; aspect-ratio: 4/3; } Browser Support The components rely primarily on the $2 and $2, with fallbacks where possible. While the core scanning functionality uses the native BarcodeDetector where available, it falls back to a $2 to ensure consistent behavior across browsers. For a detailed compatibility overview, check each component's documentation."
},
{
"title": "BarqodeCapture",
@@ -18,10 +18,10 @@
"content": " import Demo from '$lib/components/demos/barqode-capture.svelte'; The BarqodeCapture component is a simple file input with the capture attribute set to environment which allows users to take a picture with their camera. Demo Props formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2, one callback per image uploaded. If not barcode is detected, the array will be empty. Other props The BarqodeCapture component accepts all attributes that a standard input element accepts. By default, the following attributes are set: type=\"file\". This is required to make the input a file input. You should not change this. name=\"image\". This is the name of the file input. accept=\"image/*\". This restricts the file types that can be uploaded to images. capture=\"environment\". This tells the browser to open the camera when the input is clicked on mobile devices. You can choose between user and environment, which opens the front and back camera respectively. You can also disable this functionality by setting it to null. multiple. This allows the user to upload multiple files at once. You can disable this by settings this to false. Usage import { BarqodeCapture, type DetectedBarcode } from \"barqode\"; let result = $state(\"\"); function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCodes.map((detectedCode) => detectedCode.rawValue).join(\", \"); } Last detected: {result} .result { margin-top: 1.25rem; } Browser Support This component depends on the $2 which is widely supported in modern browsers."
},
{
- "title": "BarqodeDropZone",
- "href": "/docs/components/BarqodeDropZone",
+ "title": "BarqodeDropzone",
+ "href": "/docs/components/BarqodeDropzone",
"description": "File input with camera support on mobile.",
- "content": " import Demo from '$lib/components/demos/barqode-drop-zone.svelte'; You can drag-and-drop image files from your desktop or images embedded into other web pages anywhere in the area the component occupies. The images are directly scanned and positive results are indicated by the onDetect callback. Demo Props formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2, one callback per image dropped. If not barcode is detected, the array will be empty. onDragover Type: (isDraggingOver: boolean) => void Callback function that is called when a file is dragged over the drop zone. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. Usage import { BarqodeDropZone, type DetectedBarcode } from \"barqode\"; import { DemoContainer } from \"@svecodocs/kit\"; let result = $state(\"\"); let dragover = $state(false); function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCodes.map((detectedCode) => detectedCode.rawValue).join(\", \"); } function onDragover(isDraggingOver: boolean) { dragover = isDraggingOver; } Drop an image here to detect QR-codes Last detected: {result} .dropzone { width: 100%; height: 200px; border: 2px solid #2563eb; display: flex; justify-content: center; align-items: center; } .dragover { border-color: white; } .result { margin-top: 1.25rem; } Browser Support This component depends on the $2 which is widely supported in modern browsers."
+ "content": " import Demo from '$lib/components/demos/barqode-drop-zone.svelte'; You can drag-and-drop image files from your desktop or images embedded into other web pages anywhere in the area the component occupies. The images are directly scanned and positive results are indicated by the onDetect callback. Demo Props formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2, one callback per image dropped. If not barcode is detected, the array will be empty. onDragover Type: (isDraggingOver: boolean) => void Callback function that is called when a file is dragged over the drop zone. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. Usage import { BarqodeDropzone, type DetectedBarcode } from \"barqode\"; import { DemoContainer } from \"@svecodocs/kit\"; let result = $state(\"\"); let dragover = $state(false); function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCodes.map((detectedCode) => detectedCode.rawValue).join(\", \"); } function onDragover(isDraggingOver: boolean) { dragover = isDraggingOver; } Drop an image here to detect QR-codes Last detected: {result} .dropzone { width: 100%; height: 200px; border: 2px solid #2563eb; display: flex; justify-content: center; align-items: center; } .dragover { border-color: white; } .result { margin-top: 1.25rem; } Browser Support This component depends on the $2 which is widely supported in modern browsers."
},
{
"title": "BarqodeStream",
diff --git a/packages/barqode/src/lib/components/barqode-capture.svelte b/packages/barqode/src/lib/components/barqode-capture.svelte
deleted file mode 100644
index f1449c1..0000000
--- a/packages/barqode/src/lib/components/barqode-capture.svelte
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
diff --git a/packages/barqode/src/lib/components/barqode-dropzone.svelte b/packages/barqode/src/lib/components/barqode-dropzone.svelte
index 2e3b241..c08b78e 100644
--- a/packages/barqode/src/lib/components/barqode-dropzone.svelte
+++ b/packages/barqode/src/lib/components/barqode-dropzone.svelte
@@ -8,8 +8,11 @@
onDragover,
onError,
children,
+ ...restProps
}: DropzoneProps = $props();
+ let input: HTMLInputElement = $state()!;
+
async function onDetectFile(promise: Promise) {
try {
const detectedCodes = await promise;
@@ -62,15 +65,58 @@
e.preventDefault();
e.stopPropagation();
}
+
+ async function onChangeInput(event: Event) {
+ if (!(event.target instanceof HTMLInputElement) || !event.target.files) return;
+
+ for (const file of Array.from(event.target.files)) {
+ const detectedCodes = await processFile(file, formats);
+ onDetect?.(detectedCodes);
+ }
+ }
+
+ function onClick() {
+ input.click();
+ }
+
+
{@render children?.()}
+
+
diff --git a/packages/barqode/src/lib/components/types.ts b/packages/barqode/src/lib/components/types.ts
index 5ac26da..9e65526 100644
--- a/packages/barqode/src/lib/components/types.ts
+++ b/packages/barqode/src/lib/components/types.ts
@@ -4,24 +4,6 @@ import type { HTMLInputAttributes } from "svelte/elements";
export type { DetectedBarcode, BarcodeFormat, Point2D };
-export type CaptureProps = {
- /**
- * The formats of the barcodes to detect.
- *
- * @default ['qr_code']
- *
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Barcode_Detection_API#supported_barcode_formats
- */
- formats?: BarcodeFormat[];
-
- /**
- * A callback function called a detection is made.
- *
- * @param codes - The detected barcodes.
- */
- onDetect?: (detectedCodes: DetectedBarcode[]) => void;
-} & HTMLInputAttributes;
-
export type DropzoneProps = {
/**
* The formats of the barcodes to detect.
@@ -57,7 +39,7 @@ export type DropzoneProps = {
* Optional prop for content to be overlayed on top of the drop zone.
*/
children?: Snippet;
-};
+} & HTMLInputAttributes;
export type StreamProps = {
/**
diff --git a/packages/barqode/src/lib/index.ts b/packages/barqode/src/lib/index.ts
index 86f4074..cde52bc 100644
--- a/packages/barqode/src/lib/index.ts
+++ b/packages/barqode/src/lib/index.ts
@@ -1,12 +1,9 @@
-export { default as BarqodeCapture } from "./components/barqode-capture.svelte";
export { default as BarqodeDropzone } from "./components/barqode-dropzone.svelte";
export { default as BarqodeStream } from "./components/barqode-stream.svelte";
export type {
DetectedBarcode,
BarcodeFormat,
- Point2D,
- CaptureProps,
DropzoneProps,
StreamProps,
} from "./components/types.js";
diff --git a/packages/barqode/src/lib/internal/scanner.ts b/packages/barqode/src/lib/internal/scanner.ts
index 1f9c7ed..a4b5cec 100644
--- a/packages/barqode/src/lib/internal/scanner.ts
+++ b/packages/barqode/src/lib/internal/scanner.ts
@@ -17,7 +17,7 @@ declare global {
* instances can seamlessly be replaced in the middle of the scanning process, if the
* `formats` prop of `BarqodeStream` is changed.
*
- * This instance is not used by `BarqodeCapture` and `BarqodeDropZone`, because it may not
+ * This instance is not used by `BarqodeCapture` and `BarqodeDropzone`, because it may not
* have the right `formats` configured. For these components we create one-off `BarcodeDetector`
* instances because it does not happen so frequently anyway (see: `processFile`/`processUrl`).
*/
From 35c169d9264f2a0a9406779631bc801fff479749 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Olle=20M=C3=A5nsson?=
<31876997+ollema@users.noreply.github.com>
Date: Thu, 5 Dec 2024 16:34:27 +0100
Subject: [PATCH 17/25] attempt to upgrade oackages
---
docs/package.json | 10 +-
docs/src/routes/api/search.json/search.json | 33 +-
package.json | 6 +-
packages/barqode/package.json | 10 +-
pnpm-lock.yaml | 660 +++++++-------------
5 files changed, 228 insertions(+), 491 deletions(-)
diff --git a/docs/package.json b/docs/package.json
index 5bc2949..9d2af0e 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -14,21 +14,21 @@
"check:watch": "pnpm build:content && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
},
"devDependencies": {
- "@svecodocs/kit": "^0.0.5",
+ "@svecodocs/kit": "^0.1.1",
"@sveltejs/adapter-cloudflare": "^4.8.0",
"@sveltejs/kit": "^2.9.0",
- "@sveltejs/vite-plugin-svelte": "^4.0.2",
+ "@sveltejs/vite-plugin-svelte": "^5.0.1",
"@tailwindcss/vite": "4.0.0-beta.4",
"barqode": "workspace:^",
"mdsx": "^0.0.6",
"phosphor-svelte": "^3.0.0",
- "svelte": "^5.4.0",
- "svelte-check": "^4.1.0",
+ "svelte": "^5.7.0",
+ "svelte-check": "^4.1.1",
"svelte-preprocess": "^6.0.3",
"tailwindcss": "4.0.0-beta.4",
"typescript": "^5.7.2",
"velite": "^0.2.1",
- "vite": "^5.4.11"
+ "vite": "^6.0.3"
},
"private": true
}
diff --git a/docs/src/routes/api/search.json/search.json b/docs/src/routes/api/search.json/search.json
index 48c5b4a..2a2ee8f 100644
--- a/docs/src/routes/api/search.json/search.json
+++ b/docs/src/routes/api/search.json/search.json
@@ -1,32 +1 @@
-[
- {
- "title": "Getting Started",
- "href": "/docs/getting-started",
- "description": "A quick guide to get started using barqode",
- "content": "The following guide will walk you through installing and setting up the barqode components in your Svelte project. Installation Install the package using your preferred package manager: npm install barqode or pnpm add barqode or yarn add barqode Basic Usage The simplest way to use the library is with the BarqodeStream component for live scanning: import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .scanner { width: 100%; max-width: 600px; aspect-ratio: 4/3; } For detailed information about each component's capabilities and options, refer to their respective API documentation pages."
- },
- {
- "title": "Introduction",
- "href": "/docs/index",
- "description": "What is Barqode?",
- "content": "Barqode provides a set of Svelte components for detecting and decoding QR codes and various other barcode formats right in the browser. It's a comprehensive solution that supports both camera streams and static image processing. Barqode started out as a port of $2. Components BarqodeStream** - continuously scans frames from a camera stream. BarqodeDropzone** - drag & drop image files or web images. BarqodeCapture** - traditional file upload field input with camera support. Features Real-time scanning**. Detect codes from live camera stream. Multiple formats**. Support for QR codes and various barcode standards. Visual feedback**. Customizable canvas based tracking of detected codes. Cross-browser**. Works across modern browsers with a $2 if needed. Camera selection**. Choose between front/rear cameras. Torch control**. Control device flashlight where supported. Responsive**. Components adapt to fill available space. Error handling**. Comprehensive error handling for camera/detection issues. Usage Example import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .scanner { width: 100%; max-width: 600px; aspect-ratio: 4/3; } Browser Support The components rely primarily on the $2 and $2, with fallbacks where possible. While the core scanning functionality uses the native BarcodeDetector where available, it falls back to a $2 to ensure consistent behavior across browsers. For a detailed compatibility overview, check each component's documentation."
- },
- {
- "title": "BarqodeCapture",
- "href": "/docs/components/BarqodeCapture",
- "description": "File input with camera support on mobile.",
- "content": " import Demo from '$lib/components/demos/barqode-capture.svelte'; The BarqodeCapture component is a simple file input with the capture attribute set to environment which allows users to take a picture with their camera. Demo Props formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2, one callback per image uploaded. If not barcode is detected, the array will be empty. Other props The BarqodeCapture component accepts all attributes that a standard input element accepts. By default, the following attributes are set: type=\"file\". This is required to make the input a file input. You should not change this. name=\"image\". This is the name of the file input. accept=\"image/*\". This restricts the file types that can be uploaded to images. capture=\"environment\". This tells the browser to open the camera when the input is clicked on mobile devices. You can choose between user and environment, which opens the front and back camera respectively. You can also disable this functionality by setting it to null. multiple. This allows the user to upload multiple files at once. You can disable this by settings this to false. Usage import { BarqodeCapture, type DetectedBarcode } from \"barqode\"; let result = $state(\"\"); function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCodes.map((detectedCode) => detectedCode.rawValue).join(\", \"); } Last detected: {result} .result { margin-top: 1.25rem; } Browser Support This component depends on the $2 which is widely supported in modern browsers."
- },
- {
- "title": "BarqodeDropzone",
- "href": "/docs/components/BarqodeDropzone",
- "description": "File input with camera support on mobile.",
- "content": " import Demo from '$lib/components/demos/barqode-drop-zone.svelte'; You can drag-and-drop image files from your desktop or images embedded into other web pages anywhere in the area the component occupies. The images are directly scanned and positive results are indicated by the onDetect callback. Demo Props formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2, one callback per image dropped. If not barcode is detected, the array will be empty. onDragover Type: (isDraggingOver: boolean) => void Callback function that is called when a file is dragged over the drop zone. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. Usage import { BarqodeDropzone, type DetectedBarcode } from \"barqode\"; import { DemoContainer } from \"@svecodocs/kit\"; let result = $state(\"\"); let dragover = $state(false); function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCodes.map((detectedCode) => detectedCode.rawValue).join(\", \"); } function onDragover(isDraggingOver: boolean) { dragover = isDraggingOver; } Drop an image here to detect QR-codes Last detected: {result} .dropzone { width: 100%; height: 200px; border: 2px solid #2563eb; display: flex; justify-content: center; align-items: center; } .dragover { border-color: white; } .result { margin-top: 1.25rem; } Browser Support This component depends on the $2 which is widely supported in modern browsers."
- },
- {
- "title": "BarqodeStream",
- "href": "/docs/components/BarqodeStream",
- "description": "Continuously scans frames from a camera stream.",
- "content": " import Demo from '$lib/components/demos/barqode-stream.svelte'; import { Callout } from '@svecodocs/kit'; The BarqodeStream component continuously scans frames from a camera stream and detects barcodes in real-time. Demo Props constraints Type: $2 Default: { video: { facingMode: \"environment\" } } Configure the the various camera options, for example whether to use front or rear camera. The object must be of type MediaTrackConstraints. The object is passed as-is to getUserMedia, which is the API call for requesting a camera stream: navigator.mediaDevices.getUserMedia({ audio: false, video: the_constraint_object_you_provide, }); When constraints is updated, a new camera stream is requested which triggers the onCameraOn callback again. You can catch errors with the onError callback. An error can occur when you try to use the front camera on a device that doesn't have one for example. formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Don't select more barcode formats than needed. Scanning becomes more expensive the more formats you select. Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. paused Type: boolean (bindable) Default: false Whether the camera stream is or should be paused. Bindable, which means that you can pause/unpause the stream from outside the component. Pausing the stream by setting paused to true is useful if you want to show some microinteraction after successful scans. When the you set it to false, the camera stream will be restarted and the onCameraOn callback function will be triggered again. torch Type: boolean Default: false Turn the camera flashlight on or off. This is not consistently supported by all devices and browsers. Support can even vary on the same device with the same browser. For example the rear camera often has a flashlight but the front camera does not. We can only tell if flashlight control is supported once the camera is loaded and the onCameraOn callback has been called. At the moment, enabling the torch may silently fail on unsupported devices, but in the onCameraOn callback payload you can access the MediaTrackCapabilities object, from which you can determine if the torch is supported. The camera stream must be reloaded when turning the torch on or off. That means the onCameraOn event will be emitted again. track Type: (detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) => void Callback function that can be used to visually highlight detected barcodes. A transparent canvas is overlaid on top of the camera stream. The track function is used to draw on this canvas. It receives an array of $2 and a $2 as the second argument. Note that when track is set the scanning frequency has to be increased. So if you want to go easy on your target device you might not want to enable tracking. The track function is called for every frame. It is important to keep the function as performant as possible. This can lead to performance issues on low-end devices and memory leaks if not handled correctly. onCameraOn Type: (capabilities: MediaTrackCapabilities) => void Callback function that is called when the camera stream is successfully loaded. It might take a while before the component is ready and the scanning process starts. The user has to be asked for camera access permission first and the camera stream has to be loaded. If you want to show a loading indicator, you can wait for this callback to be called. It is called as soon as the camera start streaming. The callback receives the a promise which resolves with the cameras $2 when everything is ready. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. onCameraOff Type: () => void Callback function that is called when the camera stream is stopped. This can happen when the camera constraints are modified, for example when switching between front and rear camera or when turning the torch on or off. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2. If you scan the same barcode multiple times in a row, onDetect is still only called once. When you hold a barcode in the camera, frames are actually decoded multiple times a second but you don't want to be flooded with callbacks that often. That's why the last decoded QR code is always cached and only new results are propagated. However, changing the value of paused resets this internal cache. Usage import { BarqodeStream, type DetectedBarcode } from \"barqode\"; let loading = $state(true); let result: string | null = $state(null); function onCameraOn() { loading = false; } function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCode.map((code) => detectedCode.rawValue).join(\", \"); } function track(detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) { for (const detectedCode of detectedCodes) { const [firstPoint, ...otherPoints] = detectedCode.cornerPoints; ctx.strokeStyle = \"#2563eb\"; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(firstPoint.x, firstPoint.y); for (const { x, y } of otherPoints) { ctx.lineTo(x, y); } ctx.lineTo(firstPoint.x, firstPoint.y); ctx.closePath(); ctx.stroke(); } } {#if loading} Loading... {/if} Last detected: {result} .scanner { width: 100%; aspect-ratio: 4 / 3; } .loading-indicator { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; font-weight: bold; font-size: 2rem; } .result { margin-top: 1.25rem; } Browser Support This component depends on the $2 which is widely supported in modern browsers."
- }
-]
+[{"title":"Getting Started","href":"/docs/getting-started","description":"A quick guide to get started using barqode","content":"The following guide will walk you through installing and setting up the barqode components in your Svelte project. Installation Install the package using your preferred package manager: npm install barqode Basic Usage The simplest way to use the library is with the BarqodeStream component for live scanning: import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .barqode { width: 100%; max-width: 600px; aspect-ratio: 4/3; } For detailed information about each component's capabilities and options, refer to their respective API documentation pages."},{"title":"Introduction","href":"/docs/index","description":"What is Barqode?","content":"Barqode provides a set of Svelte components for detecting and decoding QR codes and various other barcode formats right in the browser. It's a comprehensive solution that supports both camera streams and static image processing. Barqode started out as a port of $2. Components BarqodeStream** - continuously scans frames from a camera stream. BarqodeDropzone** - drag & drop, click to upload or capture images from camera. Features Real-time scanning**. Detect codes from live camera stream. Multiple formats**. Support for QR codes and various barcode standards. Visual feedback**. Customizable canvas based tracking of detected codes. Cross-browser**. Works across modern browsers with a $2 if needed. Camera selection**. Choose between front/rear cameras. Torch control**. Control device flashlight where supported. Responsive**. Components adapt to fill available space. Error handling**. Comprehensive error handling for camera/detection issues. Usage Example import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .barqode { width: 100%; max-width: 600px; aspect-ratio: 4/3; } Browser Support The components rely primarily on the $2 and $2, with fallbacks where possible. While the core scanning functionality uses the native BarcodeDetector where available, it falls back to a $2 to ensure consistent behavior across browsers. For a detailed compatibility overview, check each component's documentation."},{"title":"BarqodeDropzone","href":"/docs/components/barqode-dropzone","description":"Click to upload images, drag & drop or use your camera to scan.","content":" import Demo from '$lib/components/demos/barqode-dropzone.svelte'; This component functions as a file input with the capture attribute set to environment which allows users to take a picture with their camera. You can also drag-and-drop image files from your desktop or images embedded into other web pages anywhere in the area the component occupies. The images are directly scanned and positive results are indicated by the onDetect callback. Demo Usage import { BarqodeDropzone, type DetectedBarcode } from \"barqode\"; let result = $state(\"\"); let dragover = $state(false); function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCodes.map((detectedCode) => detectedCode.rawValue).join(\", \"); } function onDragover(isDraggingOver: boolean) { dragover = isDraggingOver; } Click to upload or drop an image here Last detected: {result} .barqode { width: 100%; aspect-ratio: 4 / 3; border: 2px solid #2563eb; } .dragover { border-color: white; } .instructions { height: 100%; width: 100%; display: flex; justify-content: center; align-items: center; } Props formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2, one callback per image. If not barcode is detected, the array will be empty. onDragover Type: (isDraggingOver: boolean) => void Callback function that is called when a file is dragged over the drop zone. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. Other props The BarqodeDropzone component accepts all attributes that a standard input element accepts. By default, the following attributes are set: type=\"file\". This is required to make the input a file input. You should not change this. name=\"image\". This is the name of the file input. accept=\"image/*\". This restricts the file types that can be uploaded to images. capture=\"environment\". This tells the browser to open the camera when the input is clicked on mobile devices. You can choose between user and environment, which opens the front and back camera respectively. You can also disable this functionality by setting it to null. multiple. This allows the user to upload multiple files at once. You can disable this by settings this to false. Browser Support This component depends on the $2 which is widely supported in modern browsers."},{"title":"BarqodeStream","href":"/docs/components/barqode-stream","description":"Continuously scans frames from a camera stream.","content":" import Demo from '$lib/components/demos/barqode-stream.svelte'; import { Callout } from '@svecodocs/kit'; The BarqodeStream component continuously scans frames from a camera stream and detects barcodes in real-time. Demo Usage import { BarqodeStream, type DetectedBarcode } from \"barqode\"; let loading = $state(true); let result: string | null = $state(null); function onCameraOn() { loading = false; } function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCode.map((code) => detectedCode.rawValue).join(\", \"); } function track(detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) { for (const detectedCode of detectedCodes) { const [firstPoint, ...otherPoints] = detectedCode.cornerPoints; ctx.strokeStyle = \"#2563eb\"; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(firstPoint.x, firstPoint.y); for (const { x, y } of otherPoints) { ctx.lineTo(x, y); } ctx.lineTo(firstPoint.x, firstPoint.y); ctx.closePath(); ctx.stroke(); } } {#if loading} Loading... {/if} Last detected: {result} .barqode { width: 100%; aspect-ratio: 4 / 3; } .loading-indicator { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; font-weight: bold; font-size: 2rem; } Props constraints Type: $2 Default: { video: { facingMode: \"environment\" } } Configure the the various camera options, for example whether to use front or rear camera. The object must be of type MediaTrackConstraints. The object is passed as-is to getUserMedia, which is the API call for requesting a camera stream: navigator.mediaDevices.getUserMedia({ audio: false, video: the_constraint_object_you_provide, }); When constraints is updated, a new camera stream is requested which triggers the onCameraOn callback again. You can catch errors with the onError callback. An error can occur when you try to use the front camera on a device that doesn't have one for example. formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Don't select more barcode formats than needed. Scanning becomes more expensive the more formats you select. Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. paused Type: boolean (bindable) Default: false Whether the camera stream is or should be paused. Bindable, which means that you can pause/unpause the stream from outside the component. Pausing the stream by setting paused to true is useful if you want to show some microinteraction after successful scans. When the you set it to false, the camera stream will be restarted and the onCameraOn callback function will be triggered again. torch Type: boolean Default: false Turn the camera flashlight on or off. This is not consistently supported by all devices and browsers. Support can even vary on the same device with the same browser. For example the rear camera often has a flashlight but the front camera does not. We can only tell if flashlight control is supported once the camera is loaded and the onCameraOn callback has been called. At the moment, enabling the torch may silently fail on unsupported devices, but in the onCameraOn callback payload you can access the MediaTrackCapabilities object, from which you can determine if the torch is supported. The camera stream must be reloaded when turning the torch on or off. That means the onCameraOn event will be emitted again. track Type: (detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) => void Callback function that can be used to visually highlight detected barcodes. A transparent canvas is overlaid on top of the camera stream. The track function is used to draw on this canvas. It receives an array of $2 and a $2 as the second argument. Note that when track is set the scanning frequency has to be increased. So if you want to go easy on your target device you might not want to enable tracking. The track function is called for every frame. It is important to keep the function as performant as possible. This can lead to performance issues on low-end devices and memory leaks if not handled correctly. onCameraOn Type: (capabilities: MediaTrackCapabilities) => void Callback function that is called when the camera stream is successfully loaded. It might take a while before the component is ready and the scanning process starts. The user has to be asked for camera access permission first and the camera stream has to be loaded. If you want to show a loading indicator, you can wait for this callback to be called. It is called as soon as the camera start streaming. The callback receives the a promise which resolves with the cameras $2 when everything is ready. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. onCameraOff Type: () => void Callback function that is called when the camera stream is stopped. This can happen when the camera constraints are modified, for example when switching between front and rear camera or when turning the torch on or off. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2. If you scan the same barcode multiple times in a row, onDetect is still only called once. When you hold a barcode in the camera, frames are actually decoded multiple times a second but you don't want to be flooded with callbacks that often. That's why the last decoded QR code is always cached and only new results are propagated. However, changing the value of paused resets this internal cache. Browser Support This component depends on the $2 which is widely supported in modern browsers."}]
\ No newline at end of file
diff --git a/package.json b/package.json
index 5f062f9..782df21 100644
--- a/package.json
+++ b/package.json
@@ -34,13 +34,13 @@
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-svelte": "^2.46.1",
"globals": "^15.13.0",
- "prettier": "^3.4.1",
+ "prettier": "^3.4.2",
"prettier-plugin-svelte": "^3.3.2",
"prettier-plugin-tailwindcss": "^0.6.9",
- "svelte": "^5.4.0",
+ "svelte": "^5.7.0",
"svelte-eslint-parser": "^0.43.0",
"typescript": "^5.7.2",
"typescript-eslint": "^8.17.0",
- "wrangler": "^3.91.0"
+ "wrangler": "^3.92.0"
}
}
diff --git a/packages/barqode/package.json b/packages/barqode/package.json
index 30afe5c..5d3c0da 100644
--- a/packages/barqode/package.json
+++ b/packages/barqode/package.json
@@ -41,12 +41,12 @@
"@sveltejs/adapter-auto": "^3.3.1",
"@sveltejs/kit": "^2.9.0",
"@sveltejs/package": "^2.3.7",
- "@sveltejs/vite-plugin-svelte": "^4.0.2",
+ "@sveltejs/vite-plugin-svelte": "^5.0.1",
"publint": "^0.2.12",
- "svelte": "^5.4.0",
- "svelte-check": "^4.1.0",
+ "svelte": "^5.7.0",
+ "svelte-check": "^4.1.1",
"typescript": "^5.7.2",
- "vite": "^5.4.11"
+ "vite": "^6.0.3"
},
"license": "MIT",
"contributors": [
@@ -61,7 +61,7 @@
],
"dependencies": {
"barcode-detector": "^2.3.1",
- "runed": "^0.16.1",
+ "runed": "^0.16.2",
"webrtc-adapter": "^9.0.1"
}
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 4bfe73b..19ed131 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -37,25 +37,25 @@ importers:
version: 9.1.0(eslint@9.16.0(jiti@2.4.1))
eslint-plugin-svelte:
specifier: ^2.46.1
- version: 2.46.1(eslint@9.16.0(jiti@2.4.1))(svelte@5.4.0)
+ version: 2.46.1(eslint@9.16.0(jiti@2.4.1))(svelte@5.7.0)
globals:
specifier: ^15.13.0
version: 15.13.0
prettier:
- specifier: ^3.4.1
- version: 3.4.1
+ specifier: ^3.4.2
+ version: 3.4.2
prettier-plugin-svelte:
specifier: ^3.3.2
- version: 3.3.2(prettier@3.4.1)(svelte@5.4.0)
+ version: 3.3.2(prettier@3.4.2)(svelte@5.7.0)
prettier-plugin-tailwindcss:
specifier: ^0.6.9
- version: 0.6.9(prettier-plugin-svelte@3.3.2(prettier@3.4.1)(svelte@5.4.0))(prettier@3.4.1)
+ version: 0.6.9(prettier-plugin-svelte@3.3.2(prettier@3.4.2)(svelte@5.7.0))(prettier@3.4.2)
svelte:
- specifier: ^5.4.0
- version: 5.4.0
+ specifier: ^5.7.0
+ version: 5.7.0
svelte-eslint-parser:
specifier: ^0.43.0
- version: 0.43.0(svelte@5.4.0)
+ version: 0.43.0(svelte@5.7.0)
typescript:
specifier: ^5.7.2
version: 5.7.2
@@ -63,44 +63,44 @@ importers:
specifier: ^8.17.0
version: 8.17.0(eslint@9.16.0(jiti@2.4.1))(typescript@5.7.2)
wrangler:
- specifier: ^3.91.0
- version: 3.91.0(@cloudflare/workers-types@4.20241202.0)
+ specifier: ^3.92.0
+ version: 3.92.0(@cloudflare/workers-types@4.20241202.0)
docs:
devDependencies:
'@svecodocs/kit':
- specifier: ^0.0.5
- version: 0.0.5(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(bits-ui@1.0.0-next.65(svelte@5.4.0))(svelte@5.4.0)(tailwindcss@4.0.0-beta.4)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
+ specifier: ^0.1.1
+ version: 0.1.1(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(bits-ui@1.0.0-next.65(svelte@5.7.0))(svelte@5.7.0)(tailwindcss@4.0.0-beta.4)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
'@sveltejs/adapter-cloudflare':
specifier: ^4.8.0
- version: 4.8.0(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(wrangler@3.91.0(@cloudflare/workers-types@4.20241202.0))
+ version: 4.8.0(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(wrangler@3.92.0(@cloudflare/workers-types@4.20241202.0))
'@sveltejs/kit':
specifier: ^2.9.0
- version: 2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
+ version: 2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
'@sveltejs/vite-plugin-svelte':
- specifier: ^4.0.2
- version: 4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
+ specifier: ^5.0.1
+ version: 5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
'@tailwindcss/vite':
specifier: 4.0.0-beta.4
- version: 4.0.0-beta.4(postcss-load-config@3.1.4(postcss@8.4.49))(postcss@8.4.49)(svelte@5.4.0)(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
+ version: 4.0.0-beta.4(postcss-load-config@3.1.4(postcss@8.4.49))(postcss@8.4.49)(svelte@5.7.0)(typescript@5.7.2)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
barqode:
specifier: workspace:^
version: link:../packages/barqode
mdsx:
specifier: ^0.0.6
- version: 0.0.6(svelte@5.4.0)
+ version: 0.0.6(svelte@5.7.0)
phosphor-svelte:
specifier: ^3.0.0
- version: 3.0.0(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
+ version: 3.0.0(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
svelte:
- specifier: ^5.4.0
- version: 5.4.0
+ specifier: ^5.7.0
+ version: 5.7.0
svelte-check:
- specifier: ^4.1.0
- version: 4.1.0(svelte@5.4.0)(typescript@5.7.2)
+ specifier: ^4.1.1
+ version: 4.1.1(svelte@5.7.0)(typescript@5.7.2)
svelte-preprocess:
specifier: ^6.0.3
- version: 6.0.3(postcss-load-config@3.1.4(postcss@8.4.49))(postcss@8.4.49)(svelte@5.4.0)(typescript@5.7.2)
+ version: 6.0.3(postcss-load-config@3.1.4(postcss@8.4.49))(postcss@8.4.49)(svelte@5.7.0)(typescript@5.7.2)
tailwindcss:
specifier: 4.0.0-beta.4
version: 4.0.0-beta.4
@@ -111,8 +111,8 @@ importers:
specifier: ^0.2.1
version: 0.2.1(acorn@8.14.0)
vite:
- specifier: ^5.4.11
- version: 5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)
+ specifier: ^6.0.3
+ version: 6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)
packages/barqode:
dependencies:
@@ -120,39 +120,39 @@ importers:
specifier: ^2.3.1
version: 2.3.1
runed:
- specifier: ^0.16.1
- version: 0.16.1(svelte@5.4.0)
+ specifier: ^0.16.2
+ version: 0.16.2(svelte@5.7.0)
webrtc-adapter:
specifier: ^9.0.1
version: 9.0.1
devDependencies:
'@sveltejs/adapter-auto':
specifier: ^3.3.1
- version: 3.3.1(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))
+ version: 3.3.1(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))
'@sveltejs/kit':
specifier: ^2.9.0
- version: 2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
+ version: 2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
'@sveltejs/package':
specifier: ^2.3.7
- version: 2.3.7(svelte@5.4.0)(typescript@5.7.2)
+ version: 2.3.7(svelte@5.7.0)(typescript@5.7.2)
'@sveltejs/vite-plugin-svelte':
- specifier: ^4.0.2
- version: 4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
+ specifier: ^5.0.1
+ version: 5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
publint:
specifier: ^0.2.12
version: 0.2.12
svelte:
- specifier: ^5.4.0
- version: 5.4.0
+ specifier: ^5.7.0
+ version: 5.7.0
svelte-check:
- specifier: ^4.1.0
- version: 4.1.0(svelte@5.4.0)(typescript@5.7.2)
+ specifier: ^4.1.1
+ version: 4.1.1(svelte@5.7.0)(typescript@5.7.2)
typescript:
specifier: ^5.7.2
version: 5.7.2
vite:
- specifier: ^5.4.11
- version: 5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)
+ specifier: ^6.0.3
+ version: 6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)
packages:
@@ -226,38 +226,38 @@ packages:
resolution: {integrity: sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==}
engines: {node: '>=16.13'}
- '@cloudflare/workerd-darwin-64@1.20241106.1':
- resolution: {integrity: sha512-zxvaToi1m0qzAScrxFt7UvFVqU8DxrCO2CinM1yQkv5no7pA1HolpIrwZ0xOhR3ny64Is2s/J6BrRjpO5dM9Zw==}
+ '@cloudflare/workerd-darwin-64@1.20241106.2':
+ resolution: {integrity: sha512-p3PzgiMBp9xKo4dMINM1RkrC+miUtz65IuuMCEdCa5QZTM0eyEGcBj1A9/lmS3wW72oMfRTo6CxCkqPteFJeBA==}
engines: {node: '>=16'}
cpu: [x64]
os: [darwin]
- '@cloudflare/workerd-darwin-arm64@1.20241106.1':
- resolution: {integrity: sha512-j3dg/42D/bPgfNP3cRUBxF+4waCKO/5YKwXNj+lnVOwHxDu+ne5pFw9TIkKYcWTcwn0ZUkbNZNM5rhJqRn4xbg==}
+ '@cloudflare/workerd-darwin-arm64@1.20241106.2':
+ resolution: {integrity: sha512-AZQTAKG6bP9z0SKSXQGlXR2K2MQnDMtKC78NGjN0NOcjALTsFlLFhczaLvmuJjsT16k9yJUq2Gl+NG4ao/qgvg==}
engines: {node: '>=16'}
cpu: [arm64]
os: [darwin]
- '@cloudflare/workerd-linux-64@1.20241106.1':
- resolution: {integrity: sha512-Ih+Ye8E1DMBXcKrJktGfGztFqHKaX1CeByqshmTbODnWKHt6O65ax3oTecUwyC0+abuyraOpAtdhHNpFMhUkmw==}
+ '@cloudflare/workerd-linux-64@1.20241106.2':
+ resolution: {integrity: sha512-TWIcVdUzU7w7YP2OEIgTDtNl9jyzjxOptjRDw7jhSUsQy/02IjBLP+ZnNpgB5CUJ1tCbcOp1L2IGhZmayd7OEQ==}
engines: {node: '>=16'}
cpu: [x64]
os: [linux]
- '@cloudflare/workerd-linux-arm64@1.20241106.1':
- resolution: {integrity: sha512-mdQFPk4+14Yywn7n1xIzI+6olWM8Ybz10R7H3h+rk0XulMumCWUCy1CzIDauOx6GyIcSgKIibYMssVHZR30ObA==}
+ '@cloudflare/workerd-linux-arm64@1.20241106.2':
+ resolution: {integrity: sha512-f5Mn9IzfLs9yGjB2UCcKh+I7Ahiw6xqiQ9f/FGsHjsgLELjJ8JCKBwXmc9WdfNmVPae5jNCg2N5qVfDoWBKbCA==}
engines: {node: '>=16'}
cpu: [arm64]
os: [linux]
- '@cloudflare/workerd-windows-64@1.20241106.1':
- resolution: {integrity: sha512-4rtcss31E/Rb/PeFocZfr+B9i1MdrkhsTBWizh8siNR4KMmkslU2xs2wPaH1z8+ErxkOsHrKRa5EPLh5rIiFeg==}
+ '@cloudflare/workerd-windows-64@1.20241106.2':
+ resolution: {integrity: sha512-kdLExN3rktax23iHUKP7AHQP0HT0yGHik58fMP4kExjsMnwxw92TLI3n4HlmEqsbtMtwr9rhTJVaMBRUXq0aXw==}
engines: {node: '>=16'}
cpu: [x64]
os: [win32]
- '@cloudflare/workers-shared@0.9.0':
- resolution: {integrity: sha512-eP6Ir45uPbKnpADVzUCtkRUYxYxjB1Ew6n/whTJvHu8H4m93USHAceCMm736VBZdlxuhXXUjEP3fCUxKPn+cfw==}
+ '@cloudflare/workers-shared@0.9.1':
+ resolution: {integrity: sha512-56w4pL5D6ODw7+SieMgdwrwNyyT7tY8H4UPD4/95TSBVjqDcMPq0Dr+D4rJ+nHK+290o4ZnSiOOiKqRMqy6tPg==}
engines: {node: '>=16.7.0'}
'@cloudflare/workers-types@4.20241202.0':
@@ -280,12 +280,6 @@ packages:
peerDependencies:
esbuild: '*'
- '@esbuild/aix-ppc64@0.21.5':
- resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==}
- engines: {node: '>=12'}
- cpu: [ppc64]
- os: [aix]
-
'@esbuild/aix-ppc64@0.24.0':
resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==}
engines: {node: '>=18'}
@@ -298,12 +292,6 @@ packages:
cpu: [arm64]
os: [android]
- '@esbuild/android-arm64@0.21.5':
- resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [android]
-
'@esbuild/android-arm64@0.24.0':
resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==}
engines: {node: '>=18'}
@@ -316,12 +304,6 @@ packages:
cpu: [arm]
os: [android]
- '@esbuild/android-arm@0.21.5':
- resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==}
- engines: {node: '>=12'}
- cpu: [arm]
- os: [android]
-
'@esbuild/android-arm@0.24.0':
resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==}
engines: {node: '>=18'}
@@ -334,12 +316,6 @@ packages:
cpu: [x64]
os: [android]
- '@esbuild/android-x64@0.21.5':
- resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [android]
-
'@esbuild/android-x64@0.24.0':
resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==}
engines: {node: '>=18'}
@@ -352,12 +328,6 @@ packages:
cpu: [arm64]
os: [darwin]
- '@esbuild/darwin-arm64@0.21.5':
- resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [darwin]
-
'@esbuild/darwin-arm64@0.24.0':
resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==}
engines: {node: '>=18'}
@@ -370,12 +340,6 @@ packages:
cpu: [x64]
os: [darwin]
- '@esbuild/darwin-x64@0.21.5':
- resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [darwin]
-
'@esbuild/darwin-x64@0.24.0':
resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==}
engines: {node: '>=18'}
@@ -388,12 +352,6 @@ packages:
cpu: [arm64]
os: [freebsd]
- '@esbuild/freebsd-arm64@0.21.5':
- resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [freebsd]
-
'@esbuild/freebsd-arm64@0.24.0':
resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==}
engines: {node: '>=18'}
@@ -406,12 +364,6 @@ packages:
cpu: [x64]
os: [freebsd]
- '@esbuild/freebsd-x64@0.21.5':
- resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [freebsd]
-
'@esbuild/freebsd-x64@0.24.0':
resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==}
engines: {node: '>=18'}
@@ -424,12 +376,6 @@ packages:
cpu: [arm64]
os: [linux]
- '@esbuild/linux-arm64@0.21.5':
- resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [linux]
-
'@esbuild/linux-arm64@0.24.0':
resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==}
engines: {node: '>=18'}
@@ -442,12 +388,6 @@ packages:
cpu: [arm]
os: [linux]
- '@esbuild/linux-arm@0.21.5':
- resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==}
- engines: {node: '>=12'}
- cpu: [arm]
- os: [linux]
-
'@esbuild/linux-arm@0.24.0':
resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==}
engines: {node: '>=18'}
@@ -460,12 +400,6 @@ packages:
cpu: [ia32]
os: [linux]
- '@esbuild/linux-ia32@0.21.5':
- resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==}
- engines: {node: '>=12'}
- cpu: [ia32]
- os: [linux]
-
'@esbuild/linux-ia32@0.24.0':
resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==}
engines: {node: '>=18'}
@@ -478,12 +412,6 @@ packages:
cpu: [loong64]
os: [linux]
- '@esbuild/linux-loong64@0.21.5':
- resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==}
- engines: {node: '>=12'}
- cpu: [loong64]
- os: [linux]
-
'@esbuild/linux-loong64@0.24.0':
resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==}
engines: {node: '>=18'}
@@ -496,12 +424,6 @@ packages:
cpu: [mips64el]
os: [linux]
- '@esbuild/linux-mips64el@0.21.5':
- resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==}
- engines: {node: '>=12'}
- cpu: [mips64el]
- os: [linux]
-
'@esbuild/linux-mips64el@0.24.0':
resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==}
engines: {node: '>=18'}
@@ -514,12 +436,6 @@ packages:
cpu: [ppc64]
os: [linux]
- '@esbuild/linux-ppc64@0.21.5':
- resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==}
- engines: {node: '>=12'}
- cpu: [ppc64]
- os: [linux]
-
'@esbuild/linux-ppc64@0.24.0':
resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==}
engines: {node: '>=18'}
@@ -532,12 +448,6 @@ packages:
cpu: [riscv64]
os: [linux]
- '@esbuild/linux-riscv64@0.21.5':
- resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==}
- engines: {node: '>=12'}
- cpu: [riscv64]
- os: [linux]
-
'@esbuild/linux-riscv64@0.24.0':
resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==}
engines: {node: '>=18'}
@@ -550,12 +460,6 @@ packages:
cpu: [s390x]
os: [linux]
- '@esbuild/linux-s390x@0.21.5':
- resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==}
- engines: {node: '>=12'}
- cpu: [s390x]
- os: [linux]
-
'@esbuild/linux-s390x@0.24.0':
resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==}
engines: {node: '>=18'}
@@ -568,12 +472,6 @@ packages:
cpu: [x64]
os: [linux]
- '@esbuild/linux-x64@0.21.5':
- resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [linux]
-
'@esbuild/linux-x64@0.24.0':
resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==}
engines: {node: '>=18'}
@@ -586,12 +484,6 @@ packages:
cpu: [x64]
os: [netbsd]
- '@esbuild/netbsd-x64@0.21.5':
- resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [netbsd]
-
'@esbuild/netbsd-x64@0.24.0':
resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==}
engines: {node: '>=18'}
@@ -610,12 +502,6 @@ packages:
cpu: [x64]
os: [openbsd]
- '@esbuild/openbsd-x64@0.21.5':
- resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [openbsd]
-
'@esbuild/openbsd-x64@0.24.0':
resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==}
engines: {node: '>=18'}
@@ -628,12 +514,6 @@ packages:
cpu: [x64]
os: [sunos]
- '@esbuild/sunos-x64@0.21.5':
- resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [sunos]
-
'@esbuild/sunos-x64@0.24.0':
resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==}
engines: {node: '>=18'}
@@ -646,12 +526,6 @@ packages:
cpu: [arm64]
os: [win32]
- '@esbuild/win32-arm64@0.21.5':
- resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [win32]
-
'@esbuild/win32-arm64@0.24.0':
resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==}
engines: {node: '>=18'}
@@ -664,12 +538,6 @@ packages:
cpu: [ia32]
os: [win32]
- '@esbuild/win32-ia32@0.21.5':
- resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==}
- engines: {node: '>=12'}
- cpu: [ia32]
- os: [win32]
-
'@esbuild/win32-ia32@0.24.0':
resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==}
engines: {node: '>=18'}
@@ -682,12 +550,6 @@ packages:
cpu: [x64]
os: [win32]
- '@esbuild/win32-x64@0.21.5':
- resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [win32]
-
'@esbuild/win32-x64@0.24.0':
resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==}
engines: {node: '>=18'}
@@ -704,12 +566,12 @@ packages:
resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==}
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
- '@eslint/config-array@0.19.0':
- resolution: {integrity: sha512-zdHg2FPIFNKPdcHWtiNT+jEFCHYVplAXRDlQDyqy0zGx/q2parwh7brGJSiTxRk/TSMkbM//zt/f5CHgyTyaSQ==}
+ '@eslint/config-array@0.19.1':
+ resolution: {integrity: sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@eslint/core@0.9.0':
- resolution: {integrity: sha512-7ATR9F0e4W85D/0w7cU0SNj7qkAexMG+bAHEZOjo9akvGuhHE2m7umzWzfnpa0XAg5Kxc1BWmtPMV67jJ+9VUg==}
+ '@eslint/core@0.9.1':
+ resolution: {integrity: sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@eslint/eslintrc@3.2.0':
@@ -720,12 +582,12 @@ packages:
resolution: {integrity: sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@eslint/object-schema@2.1.4':
- resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==}
+ '@eslint/object-schema@2.1.5':
+ resolution: {integrity: sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@eslint/plugin-kit@0.2.3':
- resolution: {integrity: sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==}
+ '@eslint/plugin-kit@0.2.4':
+ resolution: {integrity: sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@fastify/busboy@2.1.1':
@@ -1022,8 +884,8 @@ packages:
'@shikijs/vscode-textmate@9.3.0':
resolution: {integrity: sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA==}
- '@svecodocs/kit@0.0.5':
- resolution: {integrity: sha512-DrwREJDQBDZTm6UOHg27CqpObFMUBcgYH9P94PSVsdJtaYOAv5GF33cjxwxvwNgczKgcpeZs4xWu3/HdFI5JKA==}
+ '@svecodocs/kit@0.1.1':
+ resolution: {integrity: sha512-VOaN+twbkStWo67QAk7DO88+CxVeTNzC49E4g7Ru0aJnBxzyXChr2dXUCJNyyONQ2LrvMnnjEQxkh69RuScEzA==}
peerDependencies:
'@sveltejs/kit': ^2.0.0
bits-ui: 1.0.0-next.65
@@ -1056,20 +918,20 @@ packages:
peerDependencies:
svelte: ^3.44.0 || ^4.0.0 || ^5.0.0-next.1
- '@sveltejs/vite-plugin-svelte-inspector@3.0.1':
- resolution: {integrity: sha512-2CKypmj1sM4GE7HjllT7UKmo4Q6L5xFRd7VMGEWhYnZ+wc6AUVU01IBd7yUi6WnFndEwWoMNOd6e8UjoN0nbvQ==}
+ '@sveltejs/vite-plugin-svelte-inspector@4.0.1':
+ resolution: {integrity: sha512-J/Nmb2Q2y7mck2hyCX4ckVHcR5tu2J+MtBEQqpDrrgELZ2uvraQcK/ioCV61AqkdXFgriksOKIceDcQmqnGhVw==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22}
peerDependencies:
- '@sveltejs/vite-plugin-svelte': ^4.0.0-next.0||^4.0.0
- svelte: ^5.0.0-next.96 || ^5.0.0
- vite: ^5.0.0
+ '@sveltejs/vite-plugin-svelte': ^5.0.0
+ svelte: ^5.0.0
+ vite: ^6.0.0
- '@sveltejs/vite-plugin-svelte@4.0.2':
- resolution: {integrity: sha512-Y9r/fWy539XlAC7+5wfNJ4zH6TygUYoQ0Eegzp0zDDqhJ54+92gOyOX1l4MO1cJSx0O+Gp13YePT5XEa3+kX0w==}
+ '@sveltejs/vite-plugin-svelte@5.0.1':
+ resolution: {integrity: sha512-D5l5+STmywGoLST07T9mrqqFFU+xgv5fqyTWM+VbxTvQ6jujNn4h3lQNCvlwVYs4Erov8i0K5Rwr3LQtmBYmBw==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22}
peerDependencies:
- svelte: ^5.0.0-next.96 || ^5.0.0
- vite: ^5.0.0
+ svelte: ^5.0.0
+ vite: ^6.0.0
'@svitejs/changesets-changelog-github-compact@1.2.0':
resolution: {integrity: sha512-08eKiDAjj4zLug1taXSIJ0kGL5cawjVCyJkBb6EWSg5fEPX6L+Wtr0CH2If4j5KYylz85iaZiFlUItvgJvll5g==}
@@ -1511,8 +1373,8 @@ packages:
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
engines: {node: '>=8'}
- dotenv@16.4.6:
- resolution: {integrity: sha512-JhcR/+KIjkkjiU8yEpaB/USlzVi3i5whwOjpIRNGi9svKEXZSe+Qp6IWAjFjv+2GViAoDRCUv/QLNziQxsLqDg==}
+ dotenv@16.4.7:
+ resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==}
engines: {node: '>=12'}
emoji-regex-xs@1.0.0:
@@ -1541,11 +1403,6 @@ packages:
engines: {node: '>=12'}
hasBin: true
- esbuild@0.21.5:
- resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==}
- engines: {node: '>=12'}
- hasBin: true
-
esbuild@0.24.0:
resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==}
engines: {node: '>=18'}
@@ -2243,8 +2100,8 @@ packages:
engines: {node: '>=10.0.0'}
hasBin: true
- miniflare@3.20241106.1:
- resolution: {integrity: sha512-dM3RBlJE8rUFxnqlPCaFCq0E7qQqEQvKbYX7W/APGCK+rLcyLmEBzC4GQR/niXdNM/oV6gdg9AA50ghnn2ALuw==}
+ miniflare@3.20241106.2:
+ resolution: {integrity: sha512-40JAPtNFMFrSW41CSxPgDykX4CgDokDfTZgDYYL8dsODb7pdAlj/dvlDPnaonkyXjRO7svyDwAavQT6IdagMwA==}
engines: {node: '>=16.13'}
hasBin: true
@@ -2364,8 +2221,8 @@ packages:
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
engines: {node: '>=6'}
- package-manager-detector@0.2.6:
- resolution: {integrity: sha512-9vPH3qooBlYRJdmdYP00nvjZOulm40r5dhtal8st18ctf+6S1k7pi5yIHLvI4w5D70x0Y+xdVD9qITH0QO/A8A==}
+ package-manager-detector@0.2.7:
+ resolution: {integrity: sha512-g4+387DXDKlZzHkP+9FLt8yKj8+/3tOkPv7DVTJGGRm00RkEWgqbFstX1mXJ4M0VDYhUqsTOiISqNOJnhAu3PQ==}
parent-module@1.0.1:
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
@@ -2526,8 +2383,8 @@ packages:
engines: {node: '>=10.13.0'}
hasBin: true
- prettier@3.4.1:
- resolution: {integrity: sha512-G+YdqtITVZmOJje6QkXQWzl3fSfMxFwm1tjTyo9exhkmWSqC4Yhd1+lug++IlR2mvRVAxEDDWYkQdeSztajqgg==}
+ prettier@3.4.2:
+ resolution: {integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==}
engines: {node: '>=14'}
hasBin: true
@@ -2632,10 +2489,6 @@ packages:
resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
engines: {node: '>=8'}
- resolve.exports@2.0.3:
- resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==}
- engines: {node: '>=10'}
-
resolve@1.22.8:
resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
hasBin: true
@@ -2667,8 +2520,8 @@ packages:
peerDependencies:
svelte: ^5.0.0-next.1
- runed@0.16.1:
- resolution: {integrity: sha512-k9ylt7sfEQiqOo2FmuilkLSk92pDzMSeVHFb8aPJGFPQPG9ErUxhfcHQwnmUhT03F8oQeO6bKB/TDoPKhdXbTA==}
+ runed@0.16.2:
+ resolution: {integrity: sha512-zA6NrXp+QGRMB2vC03hAqYshbkWI5N3sCm45X+fnr5oIWZcZw7sm3Gn6orqopy9IOvzRX6nvdD6xOMg+4GIuhg==}
peerDependencies:
svelte: ^5.0.0-next.1
@@ -2788,8 +2641,8 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
- svelte-check@4.1.0:
- resolution: {integrity: sha512-AflEZYqI578KuDZcpcorPSf597LStxlkN7XqXi38u09zlHODVKd7c+7OuubGzbhgGRUqNTdQCZ+Ga96iRXEf2g==}
+ svelte-check@4.1.1:
+ resolution: {integrity: sha512-NfaX+6Qtc8W/CyVGS/F7/XdiSSyXz+WGYA9ZWV3z8tso14V2vzjfXviKaTFEzB7g8TqfgO2FOzP6XT4ApSTUTw==}
engines: {node: '>= 18.0.0'}
hasBin: true
peerDependencies:
@@ -2848,14 +2701,14 @@ packages:
peerDependencies:
svelte: ^5.0.0-next.126
- svelte2tsx@0.7.28:
- resolution: {integrity: sha512-TJjA+kU8AnkyoprZPgQACMfTX8N0MA5NsIL//h9IuHOxmmaCLluqhcZU+fCkWipi5c/pooHLFOMpqjhq4v7JLQ==}
+ svelte2tsx@0.7.30:
+ resolution: {integrity: sha512-sHXK/vw/sVJmFuPSq6zeKrtuZKvo0jJyEi8ybN0dfrqSYVvHu8zFbO0zQKAL8y/fYackYojH41EJGe6v8rd5fw==}
peerDependencies:
svelte: ^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0
typescript: ^4.9.4 || ^5.0.0
- svelte@5.4.0:
- resolution: {integrity: sha512-2I/mjD8cXDpKfdfUK+T6yo/OzugMXIm8lhyJUFM5F/gICMYnkl3C/+4cOSpia8TqpDsi6Qfm5+fdmBNMNmaf2g==}
+ svelte@5.7.0:
+ resolution: {integrity: sha512-npaSigW2579iHv2wZrNyrlQQ8SQvTlBEN0rnxRQ7XVAcxhKHgGJYVYsErjPUKoyhAcjM6MZMnaE20KuXfzy8ug==}
engines: {node: '>=18'}
tailwind-merge@2.5.5:
@@ -2883,8 +2736,8 @@ packages:
resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==}
engines: {node: '>=8'}
- terser@5.36.0:
- resolution: {integrity: sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==}
+ terser@5.37.0:
+ resolution: {integrity: sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==}
engines: {node: '>=10'}
hasBin: true
@@ -2998,22 +2851,27 @@ packages:
vfile@6.0.3:
resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
- vite@5.4.11:
- resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==}
- engines: {node: ^18.0.0 || >=20.0.0}
+ vite@6.0.3:
+ resolution: {integrity: sha512-Cmuo5P0ENTN6HxLSo6IHsjCLn/81Vgrp81oaiFFMRa8gGDj5xEjIcEpf2ZymZtZR8oU0P2JX5WuUp/rlXcHkAw==}
+ engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
hasBin: true
peerDependencies:
- '@types/node': ^18.0.0 || >=20.0.0
+ '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
+ jiti: '>=1.21.0'
less: '*'
lightningcss: ^1.21.0
sass: '*'
sass-embedded: '*'
stylus: '*'
sugarss: '*'
- terser: ^5.4.0
+ terser: ^5.16.0
+ tsx: ^4.8.1
+ yaml: ^2.4.2
peerDependenciesMeta:
'@types/node':
optional: true
+ jiti:
+ optional: true
less:
optional: true
lightningcss:
@@ -3028,6 +2886,10 @@ packages:
optional: true
terser:
optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
vitefu@1.0.4:
resolution: {integrity: sha512-y6zEE3PQf6uu/Mt6DTJ9ih+kyJLr4XcSgHR2zUkM8SWDhuixEJxfJ6CZGMHh1Ec3vPLoEA0IHU5oWzVqw8ulow==}
@@ -3059,8 +2921,8 @@ packages:
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
engines: {node: '>=0.10.0'}
- workerd@1.20241106.1:
- resolution: {integrity: sha512-1GdKl0kDw8rrirr/ThcK66Kbl4/jd4h8uHx5g7YHBrnenY5SX1UPuop2cnCzYUxlg55kPjzIqqYslz1muRFgFw==}
+ workerd@1.20241106.2:
+ resolution: {integrity: sha512-Xw2hVIXA9MvDSHx3IX55ouGRPsQUzG0oadRVeQRs5xwgmiKshR0ompyYDO1JUvozJazfjcCSdgV8jyLcPqNIDA==}
engines: {node: '>=16'}
hasBin: true
@@ -3068,8 +2930,8 @@ packages:
resolution: {integrity: sha512-+TvsA6VAVoMC3XDKR5MoC/qlLqDixEfOBysDEKnPIPou/NvoPWCAuXHXMsswwlvmEuvX56lQjvELLyLuzTKvRw==}
engines: {node: '>=12'}
- wrangler@3.91.0:
- resolution: {integrity: sha512-Hdzn6wbY9cz5kL85ZUvWLwLIH7nPaEVRblfms40jhRf4qQO/Zf74aFlku8rQFbe8/2aVZFaxJVfBd6JQMeMSBQ==}
+ wrangler@3.92.0:
+ resolution: {integrity: sha512-MC+s+stSYQKXEn7ucENhzrw+RyMc5bSIRQ2EVcjCtqjAtO82uKQBatW2YXK5hkQOZg9Kfcdqgkcnpf/Bn94FiA==}
engines: {node: '>=16.17.0'}
hasBin: true
peerDependencies:
@@ -3188,7 +3050,7 @@ snapshots:
fs-extra: 7.0.1
mri: 1.2.0
p-limit: 2.3.0
- package-manager-detector: 0.2.6
+ package-manager-detector: 0.2.7
picocolors: 1.1.1
resolve-from: 5.0.0
semver: 7.6.3
@@ -3288,22 +3150,22 @@ snapshots:
dependencies:
mime: 3.0.0
- '@cloudflare/workerd-darwin-64@1.20241106.1':
+ '@cloudflare/workerd-darwin-64@1.20241106.2':
optional: true
- '@cloudflare/workerd-darwin-arm64@1.20241106.1':
+ '@cloudflare/workerd-darwin-arm64@1.20241106.2':
optional: true
- '@cloudflare/workerd-linux-64@1.20241106.1':
+ '@cloudflare/workerd-linux-64@1.20241106.2':
optional: true
- '@cloudflare/workerd-linux-arm64@1.20241106.1':
+ '@cloudflare/workerd-linux-arm64@1.20241106.2':
optional: true
- '@cloudflare/workerd-windows-64@1.20241106.1':
+ '@cloudflare/workerd-windows-64@1.20241106.2':
optional: true
- '@cloudflare/workers-shared@0.9.0':
+ '@cloudflare/workers-shared@0.9.1':
dependencies:
mime: 3.0.0
zod: 3.23.8
@@ -3329,162 +3191,108 @@ snapshots:
escape-string-regexp: 4.0.0
rollup-plugin-node-polyfills: 0.2.1
- '@esbuild/aix-ppc64@0.21.5':
- optional: true
-
'@esbuild/aix-ppc64@0.24.0':
optional: true
'@esbuild/android-arm64@0.17.19':
optional: true
- '@esbuild/android-arm64@0.21.5':
- optional: true
-
'@esbuild/android-arm64@0.24.0':
optional: true
'@esbuild/android-arm@0.17.19':
optional: true
- '@esbuild/android-arm@0.21.5':
- optional: true
-
'@esbuild/android-arm@0.24.0':
optional: true
'@esbuild/android-x64@0.17.19':
optional: true
- '@esbuild/android-x64@0.21.5':
- optional: true
-
'@esbuild/android-x64@0.24.0':
optional: true
'@esbuild/darwin-arm64@0.17.19':
optional: true
- '@esbuild/darwin-arm64@0.21.5':
- optional: true
-
'@esbuild/darwin-arm64@0.24.0':
optional: true
'@esbuild/darwin-x64@0.17.19':
optional: true
- '@esbuild/darwin-x64@0.21.5':
- optional: true
-
'@esbuild/darwin-x64@0.24.0':
optional: true
'@esbuild/freebsd-arm64@0.17.19':
optional: true
- '@esbuild/freebsd-arm64@0.21.5':
- optional: true
-
'@esbuild/freebsd-arm64@0.24.0':
optional: true
'@esbuild/freebsd-x64@0.17.19':
optional: true
- '@esbuild/freebsd-x64@0.21.5':
- optional: true
-
'@esbuild/freebsd-x64@0.24.0':
optional: true
'@esbuild/linux-arm64@0.17.19':
optional: true
- '@esbuild/linux-arm64@0.21.5':
- optional: true
-
'@esbuild/linux-arm64@0.24.0':
optional: true
'@esbuild/linux-arm@0.17.19':
optional: true
- '@esbuild/linux-arm@0.21.5':
- optional: true
-
'@esbuild/linux-arm@0.24.0':
optional: true
'@esbuild/linux-ia32@0.17.19':
optional: true
- '@esbuild/linux-ia32@0.21.5':
- optional: true
-
'@esbuild/linux-ia32@0.24.0':
optional: true
'@esbuild/linux-loong64@0.17.19':
optional: true
- '@esbuild/linux-loong64@0.21.5':
- optional: true
-
'@esbuild/linux-loong64@0.24.0':
optional: true
'@esbuild/linux-mips64el@0.17.19':
optional: true
- '@esbuild/linux-mips64el@0.21.5':
- optional: true
-
'@esbuild/linux-mips64el@0.24.0':
optional: true
'@esbuild/linux-ppc64@0.17.19':
optional: true
- '@esbuild/linux-ppc64@0.21.5':
- optional: true
-
'@esbuild/linux-ppc64@0.24.0':
optional: true
'@esbuild/linux-riscv64@0.17.19':
optional: true
- '@esbuild/linux-riscv64@0.21.5':
- optional: true
-
'@esbuild/linux-riscv64@0.24.0':
optional: true
'@esbuild/linux-s390x@0.17.19':
optional: true
- '@esbuild/linux-s390x@0.21.5':
- optional: true
-
'@esbuild/linux-s390x@0.24.0':
optional: true
'@esbuild/linux-x64@0.17.19':
optional: true
- '@esbuild/linux-x64@0.21.5':
- optional: true
-
'@esbuild/linux-x64@0.24.0':
optional: true
'@esbuild/netbsd-x64@0.17.19':
optional: true
- '@esbuild/netbsd-x64@0.21.5':
- optional: true
-
'@esbuild/netbsd-x64@0.24.0':
optional: true
@@ -3494,45 +3302,30 @@ snapshots:
'@esbuild/openbsd-x64@0.17.19':
optional: true
- '@esbuild/openbsd-x64@0.21.5':
- optional: true
-
'@esbuild/openbsd-x64@0.24.0':
optional: true
'@esbuild/sunos-x64@0.17.19':
optional: true
- '@esbuild/sunos-x64@0.21.5':
- optional: true
-
'@esbuild/sunos-x64@0.24.0':
optional: true
'@esbuild/win32-arm64@0.17.19':
optional: true
- '@esbuild/win32-arm64@0.21.5':
- optional: true
-
'@esbuild/win32-arm64@0.24.0':
optional: true
'@esbuild/win32-ia32@0.17.19':
optional: true
- '@esbuild/win32-ia32@0.21.5':
- optional: true
-
'@esbuild/win32-ia32@0.24.0':
optional: true
'@esbuild/win32-x64@0.17.19':
optional: true
- '@esbuild/win32-x64@0.21.5':
- optional: true
-
'@esbuild/win32-x64@0.24.0':
optional: true
@@ -3543,15 +3336,17 @@ snapshots:
'@eslint-community/regexpp@4.12.1': {}
- '@eslint/config-array@0.19.0':
+ '@eslint/config-array@0.19.1':
dependencies:
- '@eslint/object-schema': 2.1.4
+ '@eslint/object-schema': 2.1.5
debug: 4.3.7
minimatch: 3.1.2
transitivePeerDependencies:
- supports-color
- '@eslint/core@0.9.0': {}
+ '@eslint/core@0.9.1':
+ dependencies:
+ '@types/json-schema': 7.0.15
'@eslint/eslintrc@3.2.0':
dependencies:
@@ -3569,9 +3364,9 @@ snapshots:
'@eslint/js@9.16.0': {}
- '@eslint/object-schema@2.1.4': {}
+ '@eslint/object-schema@2.1.5': {}
- '@eslint/plugin-kit@0.2.3':
+ '@eslint/plugin-kit@0.2.4':
dependencies:
levn: 0.4.1
@@ -3848,22 +3643,22 @@ snapshots:
'@shikijs/vscode-textmate@9.3.0': {}
- '@svecodocs/kit@0.0.5(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(bits-ui@1.0.0-next.65(svelte@5.4.0))(svelte@5.4.0)(tailwindcss@4.0.0-beta.4)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))':
+ '@svecodocs/kit@0.1.1(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(bits-ui@1.0.0-next.65(svelte@5.7.0))(svelte@5.7.0)(tailwindcss@4.0.0-beta.4)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))':
dependencies:
- '@sveltejs/kit': 2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
- bits-ui: 1.0.0-next.65(svelte@5.4.0)
+ '@sveltejs/kit': 2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
+ bits-ui: 1.0.0-next.65(svelte@5.7.0)
clsx: 2.1.1
flexsearch: 0.7.43
- mode-watcher: 0.5.0(svelte@5.4.0)
- phosphor-svelte: 3.0.0(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
+ mode-watcher: 0.5.0(svelte@5.7.0)
+ phosphor-svelte: 3.0.0(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
rehype-autolink-headings: 7.1.0
rehype-pretty-code: 0.14.0(shiki@1.24.0)
rehype-slug: 6.0.0
remark-gfm: 4.0.0
remove-markdown: 0.5.5
shiki: 1.24.0
- svelte: 5.4.0
- svelte-toolbelt: 0.4.6(svelte@5.4.0)
+ svelte: 5.7.0
+ svelte-toolbelt: 0.4.6(svelte@5.7.0)
tailwind-merge: 2.5.5
tailwind-variants: 0.3.0(tailwindcss@4.0.0-beta.4)
tailwindcss-animate: 1.0.7(tailwindcss@4.0.0-beta.4)
@@ -3873,22 +3668,22 @@ snapshots:
- tailwindcss
- vite
- '@sveltejs/adapter-auto@3.3.1(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))':
+ '@sveltejs/adapter-auto@3.3.1(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))':
dependencies:
- '@sveltejs/kit': 2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
+ '@sveltejs/kit': 2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
import-meta-resolve: 4.1.0
- '@sveltejs/adapter-cloudflare@4.8.0(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(wrangler@3.91.0(@cloudflare/workers-types@4.20241202.0))':
+ '@sveltejs/adapter-cloudflare@4.8.0(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(wrangler@3.92.0(@cloudflare/workers-types@4.20241202.0))':
dependencies:
'@cloudflare/workers-types': 4.20241202.0
- '@sveltejs/kit': 2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
+ '@sveltejs/kit': 2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
esbuild: 0.24.0
worktop: 0.8.0-next.18
- wrangler: 3.91.0(@cloudflare/workers-types@4.20241202.0)
+ wrangler: 3.92.0(@cloudflare/workers-types@4.20241202.0)
- '@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))':
+ '@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))':
dependencies:
- '@sveltejs/vite-plugin-svelte': 4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
+ '@sveltejs/vite-plugin-svelte': 5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
'@types/cookie': 0.6.0
cookie: 0.6.0
devalue: 5.1.1
@@ -3900,47 +3695,47 @@ snapshots:
sade: 1.8.1
set-cookie-parser: 2.7.1
sirv: 3.0.0
- svelte: 5.4.0
+ svelte: 5.7.0
tiny-glob: 0.2.9
- vite: 5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)
+ vite: 6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)
- '@sveltejs/package@2.3.7(svelte@5.4.0)(typescript@5.7.2)':
+ '@sveltejs/package@2.3.7(svelte@5.7.0)(typescript@5.7.2)':
dependencies:
chokidar: 4.0.1
kleur: 4.1.5
sade: 1.8.1
semver: 7.6.3
- svelte: 5.4.0
- svelte2tsx: 0.7.28(svelte@5.4.0)(typescript@5.7.2)
+ svelte: 5.7.0
+ svelte2tsx: 0.7.30(svelte@5.7.0)(typescript@5.7.2)
transitivePeerDependencies:
- typescript
- '@sveltejs/vite-plugin-svelte-inspector@3.0.1(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))':
+ '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))':
dependencies:
- '@sveltejs/vite-plugin-svelte': 4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
+ '@sveltejs/vite-plugin-svelte': 5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
debug: 4.3.7
- svelte: 5.4.0
- vite: 5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)
+ svelte: 5.7.0
+ vite: 6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)
transitivePeerDependencies:
- supports-color
- '@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))':
+ '@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))':
dependencies:
- '@sveltejs/vite-plugin-svelte-inspector': 3.0.1(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
+ '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
debug: 4.3.7
deepmerge: 4.3.1
kleur: 4.1.5
magic-string: 0.30.14
- svelte: 5.4.0
- vite: 5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)
- vitefu: 1.0.4(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
+ svelte: 5.7.0
+ vite: 6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)
+ vitefu: 1.0.4(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
transitivePeerDependencies:
- supports-color
'@svitejs/changesets-changelog-github-compact@1.2.0':
dependencies:
'@changesets/get-github-info': 0.6.0
- dotenv: 16.4.6
+ dotenv: 16.4.7
transitivePeerDependencies:
- encoding
@@ -4001,14 +3796,14 @@ snapshots:
'@tailwindcss/oxide-win32-arm64-msvc': 4.0.0-beta.4
'@tailwindcss/oxide-win32-x64-msvc': 4.0.0-beta.4
- '@tailwindcss/vite@4.0.0-beta.4(postcss-load-config@3.1.4(postcss@8.4.49))(postcss@8.4.49)(svelte@5.4.0)(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))':
+ '@tailwindcss/vite@4.0.0-beta.4(postcss-load-config@3.1.4(postcss@8.4.49))(postcss@8.4.49)(svelte@5.7.0)(typescript@5.7.2)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))':
dependencies:
'@tailwindcss/node': 4.0.0-beta.4
'@tailwindcss/oxide': 4.0.0-beta.4
lightningcss: 1.28.2
- svelte-preprocess: 6.0.3(postcss-load-config@3.1.4(postcss@8.4.49))(postcss@8.4.49)(svelte@5.4.0)(typescript@5.7.2)
+ svelte-preprocess: 6.0.3(postcss-load-config@3.1.4(postcss@8.4.49))(postcss@8.4.49)(svelte@5.7.0)(typescript@5.7.2)
tailwindcss: 4.0.0-beta.4
- vite: 5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)
+ vite: 6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)
transitivePeerDependencies:
- '@babel/core'
- coffeescript
@@ -4214,15 +4009,15 @@ snapshots:
dependencies:
is-windows: 1.0.2
- bits-ui@1.0.0-next.65(svelte@5.4.0):
+ bits-ui@1.0.0-next.65(svelte@5.7.0):
dependencies:
'@floating-ui/core': 1.6.8
'@floating-ui/dom': 1.6.12
'@internationalized/date': 3.6.0
esm-env: 1.2.1
- runed: 0.15.4(svelte@5.4.0)
- svelte: 5.4.0
- svelte-toolbelt: 0.4.6(svelte@5.4.0)
+ runed: 0.15.4(svelte@5.7.0)
+ svelte: 5.7.0
+ svelte-toolbelt: 0.4.6(svelte@5.7.0)
blake3-wasm@2.1.5: {}
@@ -4351,7 +4146,7 @@ snapshots:
dependencies:
path-type: 4.0.0
- dotenv@16.4.6: {}
+ dotenv@16.4.7: {}
emoji-regex-xs@1.0.0: {}
@@ -4406,32 +4201,6 @@ snapshots:
'@esbuild/win32-ia32': 0.17.19
'@esbuild/win32-x64': 0.17.19
- esbuild@0.21.5:
- optionalDependencies:
- '@esbuild/aix-ppc64': 0.21.5
- '@esbuild/android-arm': 0.21.5
- '@esbuild/android-arm64': 0.21.5
- '@esbuild/android-x64': 0.21.5
- '@esbuild/darwin-arm64': 0.21.5
- '@esbuild/darwin-x64': 0.21.5
- '@esbuild/freebsd-arm64': 0.21.5
- '@esbuild/freebsd-x64': 0.21.5
- '@esbuild/linux-arm': 0.21.5
- '@esbuild/linux-arm64': 0.21.5
- '@esbuild/linux-ia32': 0.21.5
- '@esbuild/linux-loong64': 0.21.5
- '@esbuild/linux-mips64el': 0.21.5
- '@esbuild/linux-ppc64': 0.21.5
- '@esbuild/linux-riscv64': 0.21.5
- '@esbuild/linux-s390x': 0.21.5
- '@esbuild/linux-x64': 0.21.5
- '@esbuild/netbsd-x64': 0.21.5
- '@esbuild/openbsd-x64': 0.21.5
- '@esbuild/sunos-x64': 0.21.5
- '@esbuild/win32-arm64': 0.21.5
- '@esbuild/win32-ia32': 0.21.5
- '@esbuild/win32-x64': 0.21.5
-
esbuild@0.24.0:
optionalDependencies:
'@esbuild/aix-ppc64': 0.24.0
@@ -4472,7 +4241,7 @@ snapshots:
dependencies:
eslint: 9.16.0(jiti@2.4.1)
- eslint-plugin-svelte@2.46.1(eslint@9.16.0(jiti@2.4.1))(svelte@5.4.0):
+ eslint-plugin-svelte@2.46.1(eslint@9.16.0(jiti@2.4.1))(svelte@5.7.0):
dependencies:
'@eslint-community/eslint-utils': 4.4.1(eslint@9.16.0(jiti@2.4.1))
'@jridgewell/sourcemap-codec': 1.5.0
@@ -4485,9 +4254,9 @@ snapshots:
postcss-safe-parser: 6.0.0(postcss@8.4.49)
postcss-selector-parser: 6.1.2
semver: 7.6.3
- svelte-eslint-parser: 0.43.0(svelte@5.4.0)
+ svelte-eslint-parser: 0.43.0(svelte@5.7.0)
optionalDependencies:
- svelte: 5.4.0
+ svelte: 5.7.0
transitivePeerDependencies:
- ts-node
@@ -4509,11 +4278,11 @@ snapshots:
dependencies:
'@eslint-community/eslint-utils': 4.4.1(eslint@9.16.0(jiti@2.4.1))
'@eslint-community/regexpp': 4.12.1
- '@eslint/config-array': 0.19.0
- '@eslint/core': 0.9.0
+ '@eslint/config-array': 0.19.1
+ '@eslint/core': 0.9.1
'@eslint/eslintrc': 3.2.0
'@eslint/js': 9.16.0
- '@eslint/plugin-kit': 0.2.3
+ '@eslint/plugin-kit': 0.2.4
'@humanfs/node': 0.16.6
'@humanwhocodes/module-importer': 1.0.1
'@humanwhocodes/retry': 0.4.1
@@ -5198,7 +4967,7 @@ snapshots:
dependencies:
'@types/mdast': 4.0.4
- mdsx@0.0.6(svelte@5.4.0):
+ mdsx@0.0.6(svelte@5.7.0):
dependencies:
esrap: 1.2.3
hast-util-to-html: 9.0.3
@@ -5207,7 +4976,7 @@ snapshots:
rehype-stringify: 10.0.1
remark-parse: 11.0.0
remark-rehype: 11.1.1
- svelte: 5.4.0
+ svelte: 5.7.0
unified: 11.0.5
unist-util-visit: 5.0.0
vfile: 6.0.3
@@ -5491,7 +5260,7 @@ snapshots:
mime@3.0.0: {}
- miniflare@3.20241106.1:
+ miniflare@3.20241106.2:
dependencies:
'@cspotcode/source-map-support': 0.8.1
acorn: 8.14.0
@@ -5501,7 +5270,7 @@ snapshots:
glob-to-regexp: 0.4.1
stoppable: 1.1.0
undici: 5.28.4
- workerd: 1.20241106.1
+ workerd: 1.20241106.2
ws: 8.18.0
youch: 3.3.4
zod: 3.23.8
@@ -5522,9 +5291,9 @@ snapshots:
dependencies:
brace-expansion: 2.0.1
- mode-watcher@0.5.0(svelte@5.4.0):
+ mode-watcher@0.5.0(svelte@5.7.0):
dependencies:
- svelte: 5.4.0
+ svelte: 5.7.0
mri@1.2.0: {}
@@ -5611,7 +5380,7 @@ snapshots:
p-try@2.2.0: {}
- package-manager-detector@0.2.6: {}
+ package-manager-detector@0.2.7: {}
parent-module@1.0.1:
dependencies:
@@ -5651,13 +5420,13 @@ snapshots:
pathe@1.1.2: {}
- phosphor-svelte@3.0.0(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)):
+ phosphor-svelte@3.0.0(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)):
dependencies:
estree-walker: 3.0.3
magic-string: 0.30.14
- svelte: 5.4.0
+ svelte: 5.7.0
optionalDependencies:
- vite: 5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)
+ vite: 6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)
picocolors@1.1.1: {}
@@ -5693,20 +5462,20 @@ snapshots:
prelude-ls@1.2.1: {}
- prettier-plugin-svelte@3.3.2(prettier@3.4.1)(svelte@5.4.0):
+ prettier-plugin-svelte@3.3.2(prettier@3.4.2)(svelte@5.7.0):
dependencies:
- prettier: 3.4.1
- svelte: 5.4.0
+ prettier: 3.4.2
+ svelte: 5.7.0
- prettier-plugin-tailwindcss@0.6.9(prettier-plugin-svelte@3.3.2(prettier@3.4.1)(svelte@5.4.0))(prettier@3.4.1):
+ prettier-plugin-tailwindcss@0.6.9(prettier-plugin-svelte@3.3.2(prettier@3.4.2)(svelte@5.7.0))(prettier@3.4.2):
dependencies:
- prettier: 3.4.1
+ prettier: 3.4.2
optionalDependencies:
- prettier-plugin-svelte: 3.3.2(prettier@3.4.1)(svelte@5.4.0)
+ prettier-plugin-svelte: 3.3.2(prettier@3.4.2)(svelte@5.7.0)
prettier@2.8.8: {}
- prettier@3.4.1: {}
+ prettier@3.4.2: {}
printable-characters@1.0.42: {}
@@ -5869,8 +5638,6 @@ snapshots:
resolve-from@5.0.0: {}
- resolve.exports@2.0.3: {}
-
resolve@1.22.8:
dependencies:
is-core-module: 2.15.1
@@ -5921,15 +5688,15 @@ snapshots:
dependencies:
queue-microtask: 1.2.3
- runed@0.15.4(svelte@5.4.0):
+ runed@0.15.4(svelte@5.7.0):
dependencies:
esm-env: 1.2.1
- svelte: 5.4.0
+ svelte: 5.7.0
- runed@0.16.1(svelte@5.4.0):
+ runed@0.16.2(svelte@5.7.0):
dependencies:
esm-env: 1.2.1
- svelte: 5.4.0
+ svelte: 5.7.0
sade@1.8.1:
dependencies:
@@ -6059,19 +5826,19 @@ snapshots:
supports-preserve-symlinks-flag@1.0.0: {}
- svelte-check@4.1.0(svelte@5.4.0)(typescript@5.7.2):
+ svelte-check@4.1.1(svelte@5.7.0)(typescript@5.7.2):
dependencies:
'@jridgewell/trace-mapping': 0.3.25
chokidar: 4.0.1
fdir: 6.4.2
picocolors: 1.1.1
sade: 1.8.1
- svelte: 5.4.0
+ svelte: 5.7.0
typescript: 5.7.2
transitivePeerDependencies:
- picomatch
- svelte-eslint-parser@0.43.0(svelte@5.4.0):
+ svelte-eslint-parser@0.43.0(svelte@5.7.0):
dependencies:
eslint-scope: 7.2.2
eslint-visitor-keys: 3.4.3
@@ -6079,30 +5846,30 @@ snapshots:
postcss: 8.4.49
postcss-scss: 4.0.9(postcss@8.4.49)
optionalDependencies:
- svelte: 5.4.0
+ svelte: 5.7.0
- svelte-preprocess@6.0.3(postcss-load-config@3.1.4(postcss@8.4.49))(postcss@8.4.49)(svelte@5.4.0)(typescript@5.7.2):
+ svelte-preprocess@6.0.3(postcss-load-config@3.1.4(postcss@8.4.49))(postcss@8.4.49)(svelte@5.7.0)(typescript@5.7.2):
dependencies:
- svelte: 5.4.0
+ svelte: 5.7.0
optionalDependencies:
postcss: 8.4.49
postcss-load-config: 3.1.4(postcss@8.4.49)
typescript: 5.7.2
- svelte-toolbelt@0.4.6(svelte@5.4.0):
+ svelte-toolbelt@0.4.6(svelte@5.7.0):
dependencies:
clsx: 2.1.1
style-to-object: 1.0.8
- svelte: 5.4.0
+ svelte: 5.7.0
- svelte2tsx@0.7.28(svelte@5.4.0)(typescript@5.7.2):
+ svelte2tsx@0.7.30(svelte@5.7.0)(typescript@5.7.2):
dependencies:
dedent-js: 1.0.1
pascal-case: 3.1.2
- svelte: 5.4.0
+ svelte: 5.7.0
typescript: 5.7.2
- svelte@5.4.0:
+ svelte@5.7.0:
dependencies:
'@ampproject/remapping': 2.3.0
'@jridgewell/sourcemap-codec': 1.5.0
@@ -6135,7 +5902,7 @@ snapshots:
term-size@2.2.1: {}
- terser@5.36.0:
+ terser@5.37.0:
dependencies:
'@jridgewell/source-map': 0.3.6
acorn: 8.14.0
@@ -6251,7 +6018,7 @@ snapshots:
'@mdx-js/mdx': 3.1.0(acorn@8.14.0)
esbuild: 0.24.0
sharp: 0.33.5
- terser: 5.36.0
+ terser: 5.37.0
transitivePeerDependencies:
- acorn
- supports-color
@@ -6271,20 +6038,22 @@ snapshots:
'@types/unist': 3.0.3
vfile-message: 4.0.2
- vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0):
+ vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1):
dependencies:
- esbuild: 0.21.5
+ esbuild: 0.24.0
postcss: 8.4.49
rollup: 4.28.0
optionalDependencies:
'@types/node': 22.10.1
fsevents: 2.3.3
+ jiti: 2.4.1
lightningcss: 1.28.2
- terser: 5.36.0
+ terser: 5.37.0
+ yaml: 2.6.1
- vitefu@1.0.4(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)):
+ vitefu@1.0.4(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)):
optionalDependencies:
- vite: 5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)
+ vite: 6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)
web-namespaces@2.0.1: {}
@@ -6305,23 +6074,23 @@ snapshots:
word-wrap@1.2.5: {}
- workerd@1.20241106.1:
+ workerd@1.20241106.2:
optionalDependencies:
- '@cloudflare/workerd-darwin-64': 1.20241106.1
- '@cloudflare/workerd-darwin-arm64': 1.20241106.1
- '@cloudflare/workerd-linux-64': 1.20241106.1
- '@cloudflare/workerd-linux-arm64': 1.20241106.1
- '@cloudflare/workerd-windows-64': 1.20241106.1
+ '@cloudflare/workerd-darwin-64': 1.20241106.2
+ '@cloudflare/workerd-darwin-arm64': 1.20241106.2
+ '@cloudflare/workerd-linux-64': 1.20241106.2
+ '@cloudflare/workerd-linux-arm64': 1.20241106.2
+ '@cloudflare/workerd-windows-64': 1.20241106.2
worktop@0.8.0-next.18:
dependencies:
mrmime: 2.0.0
regexparam: 3.0.0
- wrangler@3.91.0(@cloudflare/workers-types@4.20241202.0):
+ wrangler@3.92.0(@cloudflare/workers-types@4.20241202.0):
dependencies:
'@cloudflare/kv-asset-handler': 0.3.4
- '@cloudflare/workers-shared': 0.9.0
+ '@cloudflare/workers-shared': 0.9.1
'@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19)
'@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19)
blake3-wasm: 2.1.5
@@ -6329,15 +6098,14 @@ snapshots:
date-fns: 4.1.0
esbuild: 0.17.19
itty-time: 1.0.6
- miniflare: 3.20241106.1
+ miniflare: 3.20241106.2
nanoid: 3.3.8
path-to-regexp: 6.3.0
resolve: 1.22.8
- resolve.exports: 2.0.3
selfsigned: 2.4.1
source-map: 0.6.1
unenv: unenv-nightly@2.0.0-20241121-161142-806b5c0
- workerd: 1.20241106.1
+ workerd: 1.20241106.2
xxhash-wasm: 1.1.0
optionalDependencies:
'@cloudflare/workers-types': 4.20241202.0
From ce7371f23c2377442df9d312bee7d6a3c5ccb4c6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Olle=20M=C3=A5nsson?=
<31876997+ollema@users.noreply.github.com>
Date: Thu, 5 Dec 2024 16:39:21 +0100
Subject: [PATCH 18/25] format
---
docs/src/routes/api/search.json/search.json | 27 ++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/docs/src/routes/api/search.json/search.json b/docs/src/routes/api/search.json/search.json
index 2a2ee8f..c089dde 100644
--- a/docs/src/routes/api/search.json/search.json
+++ b/docs/src/routes/api/search.json/search.json
@@ -1 +1,26 @@
-[{"title":"Getting Started","href":"/docs/getting-started","description":"A quick guide to get started using barqode","content":"The following guide will walk you through installing and setting up the barqode components in your Svelte project. Installation Install the package using your preferred package manager: npm install barqode Basic Usage The simplest way to use the library is with the BarqodeStream component for live scanning: import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .barqode { width: 100%; max-width: 600px; aspect-ratio: 4/3; } For detailed information about each component's capabilities and options, refer to their respective API documentation pages."},{"title":"Introduction","href":"/docs/index","description":"What is Barqode?","content":"Barqode provides a set of Svelte components for detecting and decoding QR codes and various other barcode formats right in the browser. It's a comprehensive solution that supports both camera streams and static image processing. Barqode started out as a port of $2. Components BarqodeStream** - continuously scans frames from a camera stream. BarqodeDropzone** - drag & drop, click to upload or capture images from camera. Features Real-time scanning**. Detect codes from live camera stream. Multiple formats**. Support for QR codes and various barcode standards. Visual feedback**. Customizable canvas based tracking of detected codes. Cross-browser**. Works across modern browsers with a $2 if needed. Camera selection**. Choose between front/rear cameras. Torch control**. Control device flashlight where supported. Responsive**. Components adapt to fill available space. Error handling**. Comprehensive error handling for camera/detection issues. Usage Example import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .barqode { width: 100%; max-width: 600px; aspect-ratio: 4/3; } Browser Support The components rely primarily on the $2 and $2, with fallbacks where possible. While the core scanning functionality uses the native BarcodeDetector where available, it falls back to a $2 to ensure consistent behavior across browsers. For a detailed compatibility overview, check each component's documentation."},{"title":"BarqodeDropzone","href":"/docs/components/barqode-dropzone","description":"Click to upload images, drag & drop or use your camera to scan.","content":" import Demo from '$lib/components/demos/barqode-dropzone.svelte'; This component functions as a file input with the capture attribute set to environment which allows users to take a picture with their camera. You can also drag-and-drop image files from your desktop or images embedded into other web pages anywhere in the area the component occupies. The images are directly scanned and positive results are indicated by the onDetect callback. Demo Usage import { BarqodeDropzone, type DetectedBarcode } from \"barqode\"; let result = $state(\"\"); let dragover = $state(false); function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCodes.map((detectedCode) => detectedCode.rawValue).join(\", \"); } function onDragover(isDraggingOver: boolean) { dragover = isDraggingOver; } Click to upload or drop an image here Last detected: {result} .barqode { width: 100%; aspect-ratio: 4 / 3; border: 2px solid #2563eb; } .dragover { border-color: white; } .instructions { height: 100%; width: 100%; display: flex; justify-content: center; align-items: center; } Props formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2, one callback per image. If not barcode is detected, the array will be empty. onDragover Type: (isDraggingOver: boolean) => void Callback function that is called when a file is dragged over the drop zone. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. Other props The BarqodeDropzone component accepts all attributes that a standard input element accepts. By default, the following attributes are set: type=\"file\". This is required to make the input a file input. You should not change this. name=\"image\". This is the name of the file input. accept=\"image/*\". This restricts the file types that can be uploaded to images. capture=\"environment\". This tells the browser to open the camera when the input is clicked on mobile devices. You can choose between user and environment, which opens the front and back camera respectively. You can also disable this functionality by setting it to null. multiple. This allows the user to upload multiple files at once. You can disable this by settings this to false. Browser Support This component depends on the $2 which is widely supported in modern browsers."},{"title":"BarqodeStream","href":"/docs/components/barqode-stream","description":"Continuously scans frames from a camera stream.","content":" import Demo from '$lib/components/demos/barqode-stream.svelte'; import { Callout } from '@svecodocs/kit'; The BarqodeStream component continuously scans frames from a camera stream and detects barcodes in real-time. Demo Usage import { BarqodeStream, type DetectedBarcode } from \"barqode\"; let loading = $state(true); let result: string | null = $state(null); function onCameraOn() { loading = false; } function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCode.map((code) => detectedCode.rawValue).join(\", \"); } function track(detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) { for (const detectedCode of detectedCodes) { const [firstPoint, ...otherPoints] = detectedCode.cornerPoints; ctx.strokeStyle = \"#2563eb\"; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(firstPoint.x, firstPoint.y); for (const { x, y } of otherPoints) { ctx.lineTo(x, y); } ctx.lineTo(firstPoint.x, firstPoint.y); ctx.closePath(); ctx.stroke(); } } {#if loading} Loading... {/if} Last detected: {result} .barqode { width: 100%; aspect-ratio: 4 / 3; } .loading-indicator { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; font-weight: bold; font-size: 2rem; } Props constraints Type: $2 Default: { video: { facingMode: \"environment\" } } Configure the the various camera options, for example whether to use front or rear camera. The object must be of type MediaTrackConstraints. The object is passed as-is to getUserMedia, which is the API call for requesting a camera stream: navigator.mediaDevices.getUserMedia({ audio: false, video: the_constraint_object_you_provide, }); When constraints is updated, a new camera stream is requested which triggers the onCameraOn callback again. You can catch errors with the onError callback. An error can occur when you try to use the front camera on a device that doesn't have one for example. formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Don't select more barcode formats than needed. Scanning becomes more expensive the more formats you select. Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. paused Type: boolean (bindable) Default: false Whether the camera stream is or should be paused. Bindable, which means that you can pause/unpause the stream from outside the component. Pausing the stream by setting paused to true is useful if you want to show some microinteraction after successful scans. When the you set it to false, the camera stream will be restarted and the onCameraOn callback function will be triggered again. torch Type: boolean Default: false Turn the camera flashlight on or off. This is not consistently supported by all devices and browsers. Support can even vary on the same device with the same browser. For example the rear camera often has a flashlight but the front camera does not. We can only tell if flashlight control is supported once the camera is loaded and the onCameraOn callback has been called. At the moment, enabling the torch may silently fail on unsupported devices, but in the onCameraOn callback payload you can access the MediaTrackCapabilities object, from which you can determine if the torch is supported. The camera stream must be reloaded when turning the torch on or off. That means the onCameraOn event will be emitted again. track Type: (detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) => void Callback function that can be used to visually highlight detected barcodes. A transparent canvas is overlaid on top of the camera stream. The track function is used to draw on this canvas. It receives an array of $2 and a $2 as the second argument. Note that when track is set the scanning frequency has to be increased. So if you want to go easy on your target device you might not want to enable tracking. The track function is called for every frame. It is important to keep the function as performant as possible. This can lead to performance issues on low-end devices and memory leaks if not handled correctly. onCameraOn Type: (capabilities: MediaTrackCapabilities) => void Callback function that is called when the camera stream is successfully loaded. It might take a while before the component is ready and the scanning process starts. The user has to be asked for camera access permission first and the camera stream has to be loaded. If you want to show a loading indicator, you can wait for this callback to be called. It is called as soon as the camera start streaming. The callback receives the a promise which resolves with the cameras $2 when everything is ready. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. onCameraOff Type: () => void Callback function that is called when the camera stream is stopped. This can happen when the camera constraints are modified, for example when switching between front and rear camera or when turning the torch on or off. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2. If you scan the same barcode multiple times in a row, onDetect is still only called once. When you hold a barcode in the camera, frames are actually decoded multiple times a second but you don't want to be flooded with callbacks that often. That's why the last decoded QR code is always cached and only new results are propagated. However, changing the value of paused resets this internal cache. Browser Support This component depends on the $2 which is widely supported in modern browsers."}]
\ No newline at end of file
+[
+ {
+ "title": "Getting Started",
+ "href": "/docs/getting-started",
+ "description": "A quick guide to get started using barqode",
+ "content": "The following guide will walk you through installing and setting up the barqode components in your Svelte project. Installation Install the package using your preferred package manager: npm install barqode Basic Usage The simplest way to use the library is with the BarqodeStream component for live scanning: import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .barqode { width: 100%; max-width: 600px; aspect-ratio: 4/3; } For detailed information about each component's capabilities and options, refer to their respective API documentation pages."
+ },
+ {
+ "title": "Introduction",
+ "href": "/docs/index",
+ "description": "What is Barqode?",
+ "content": "Barqode provides a set of Svelte components for detecting and decoding QR codes and various other barcode formats right in the browser. It's a comprehensive solution that supports both camera streams and static image processing. Barqode started out as a port of $2. Components BarqodeStream** - continuously scans frames from a camera stream. BarqodeDropzone** - drag & drop, click to upload or capture images from camera. Features Real-time scanning**. Detect codes from live camera stream. Multiple formats**. Support for QR codes and various barcode standards. Visual feedback**. Customizable canvas based tracking of detected codes. Cross-browser**. Works across modern browsers with a $2 if needed. Camera selection**. Choose between front/rear cameras. Torch control**. Control device flashlight where supported. Responsive**. Components adapt to fill available space. Error handling**. Comprehensive error handling for camera/detection issues. Usage Example import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .barqode { width: 100%; max-width: 600px; aspect-ratio: 4/3; } Browser Support The components rely primarily on the $2 and $2, with fallbacks where possible. While the core scanning functionality uses the native BarcodeDetector where available, it falls back to a $2 to ensure consistent behavior across browsers. For a detailed compatibility overview, check each component's documentation."
+ },
+ {
+ "title": "BarqodeDropzone",
+ "href": "/docs/components/barqode-dropzone",
+ "description": "Click to upload images, drag & drop or use your camera to scan.",
+ "content": " import Demo from '$lib/components/demos/barqode-dropzone.svelte'; This component functions as a file input with the capture attribute set to environment which allows users to take a picture with their camera. You can also drag-and-drop image files from your desktop or images embedded into other web pages anywhere in the area the component occupies. The images are directly scanned and positive results are indicated by the onDetect callback. Demo Usage import { BarqodeDropzone, type DetectedBarcode } from \"barqode\"; let result = $state(\"\"); let dragover = $state(false); function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCodes.map((detectedCode) => detectedCode.rawValue).join(\", \"); } function onDragover(isDraggingOver: boolean) { dragover = isDraggingOver; } Click to upload or drop an image here Last detected: {result} .barqode { width: 100%; aspect-ratio: 4 / 3; border: 2px solid #2563eb; } .dragover { border-color: white; } .instructions { height: 100%; width: 100%; display: flex; justify-content: center; align-items: center; } Props formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2, one callback per image. If not barcode is detected, the array will be empty. onDragover Type: (isDraggingOver: boolean) => void Callback function that is called when a file is dragged over the drop zone. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. Other props The BarqodeDropzone component accepts all attributes that a standard input element accepts. By default, the following attributes are set: type=\"file\". This is required to make the input a file input. You should not change this. name=\"image\". This is the name of the file input. accept=\"image/*\". This restricts the file types that can be uploaded to images. capture=\"environment\". This tells the browser to open the camera when the input is clicked on mobile devices. You can choose between user and environment, which opens the front and back camera respectively. You can also disable this functionality by setting it to null. multiple. This allows the user to upload multiple files at once. You can disable this by settings this to false. Browser Support This component depends on the $2 which is widely supported in modern browsers."
+ },
+ {
+ "title": "BarqodeStream",
+ "href": "/docs/components/barqode-stream",
+ "description": "Continuously scans frames from a camera stream.",
+ "content": " import Demo from '$lib/components/demos/barqode-stream.svelte'; import { Callout } from '@svecodocs/kit'; The BarqodeStream component continuously scans frames from a camera stream and detects barcodes in real-time. Demo Usage import { BarqodeStream, type DetectedBarcode } from \"barqode\"; let loading = $state(true); let result: string | null = $state(null); function onCameraOn() { loading = false; } function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCode.map((code) => detectedCode.rawValue).join(\", \"); } function track(detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) { for (const detectedCode of detectedCodes) { const [firstPoint, ...otherPoints] = detectedCode.cornerPoints; ctx.strokeStyle = \"#2563eb\"; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(firstPoint.x, firstPoint.y); for (const { x, y } of otherPoints) { ctx.lineTo(x, y); } ctx.lineTo(firstPoint.x, firstPoint.y); ctx.closePath(); ctx.stroke(); } } {#if loading} Loading... {/if} Last detected: {result} .barqode { width: 100%; aspect-ratio: 4 / 3; } .loading-indicator { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; font-weight: bold; font-size: 2rem; } Props constraints Type: $2 Default: { video: { facingMode: \"environment\" } } Configure the the various camera options, for example whether to use front or rear camera. The object must be of type MediaTrackConstraints. The object is passed as-is to getUserMedia, which is the API call for requesting a camera stream: navigator.mediaDevices.getUserMedia({ audio: false, video: the_constraint_object_you_provide, }); When constraints is updated, a new camera stream is requested which triggers the onCameraOn callback again. You can catch errors with the onError callback. An error can occur when you try to use the front camera on a device that doesn't have one for example. formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Don't select more barcode formats than needed. Scanning becomes more expensive the more formats you select. Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. paused Type: boolean (bindable) Default: false Whether the camera stream is or should be paused. Bindable, which means that you can pause/unpause the stream from outside the component. Pausing the stream by setting paused to true is useful if you want to show some microinteraction after successful scans. When the you set it to false, the camera stream will be restarted and the onCameraOn callback function will be triggered again. torch Type: boolean Default: false Turn the camera flashlight on or off. This is not consistently supported by all devices and browsers. Support can even vary on the same device with the same browser. For example the rear camera often has a flashlight but the front camera does not. We can only tell if flashlight control is supported once the camera is loaded and the onCameraOn callback has been called. At the moment, enabling the torch may silently fail on unsupported devices, but in the onCameraOn callback payload you can access the MediaTrackCapabilities object, from which you can determine if the torch is supported. The camera stream must be reloaded when turning the torch on or off. That means the onCameraOn event will be emitted again. track Type: (detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) => void Callback function that can be used to visually highlight detected barcodes. A transparent canvas is overlaid on top of the camera stream. The track function is used to draw on this canvas. It receives an array of $2 and a $2 as the second argument. Note that when track is set the scanning frequency has to be increased. So if you want to go easy on your target device you might not want to enable tracking. The track function is called for every frame. It is important to keep the function as performant as possible. This can lead to performance issues on low-end devices and memory leaks if not handled correctly. onCameraOn Type: (capabilities: MediaTrackCapabilities) => void Callback function that is called when the camera stream is successfully loaded. It might take a while before the component is ready and the scanning process starts. The user has to be asked for camera access permission first and the camera stream has to be loaded. If you want to show a loading indicator, you can wait for this callback to be called. It is called as soon as the camera start streaming. The callback receives the a promise which resolves with the cameras $2 when everything is ready. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. onCameraOff Type: () => void Callback function that is called when the camera stream is stopped. This can happen when the camera constraints are modified, for example when switching between front and rear camera or when turning the torch on or off. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2. If you scan the same barcode multiple times in a row, onDetect is still only called once. When you hold a barcode in the camera, frames are actually decoded multiple times a second but you don't want to be flooded with callbacks that often. That's why the last decoded QR code is always cached and only new results are propagated. However, changing the value of paused resets this internal cache. Browser Support This component depends on the $2 which is widely supported in modern browsers."
+ }
+]
From f2e0c4cc88bc539b4bf20209bac6eaaf69ecf60c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Olle=20M=C3=A5nsson?=
<31876997+ollema@users.noreply.github.com>
Date: Thu, 5 Dec 2024 22:10:17 +0100
Subject: [PATCH 19/25] revert prev two commits
---
docs/package.json | 10 +-
docs/src/routes/api/search.json/search.json | 20 +-
package.json | 6 +-
packages/barqode/package.json | 10 +-
pnpm-lock.yaml | 660 +++++++++++++-------
5 files changed, 472 insertions(+), 234 deletions(-)
diff --git a/docs/package.json b/docs/package.json
index 9d2af0e..5bc2949 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -14,21 +14,21 @@
"check:watch": "pnpm build:content && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
},
"devDependencies": {
- "@svecodocs/kit": "^0.1.1",
+ "@svecodocs/kit": "^0.0.5",
"@sveltejs/adapter-cloudflare": "^4.8.0",
"@sveltejs/kit": "^2.9.0",
- "@sveltejs/vite-plugin-svelte": "^5.0.1",
+ "@sveltejs/vite-plugin-svelte": "^4.0.2",
"@tailwindcss/vite": "4.0.0-beta.4",
"barqode": "workspace:^",
"mdsx": "^0.0.6",
"phosphor-svelte": "^3.0.0",
- "svelte": "^5.7.0",
- "svelte-check": "^4.1.1",
+ "svelte": "^5.4.0",
+ "svelte-check": "^4.1.0",
"svelte-preprocess": "^6.0.3",
"tailwindcss": "4.0.0-beta.4",
"typescript": "^5.7.2",
"velite": "^0.2.1",
- "vite": "^6.0.3"
+ "vite": "^5.4.11"
},
"private": true
}
diff --git a/docs/src/routes/api/search.json/search.json b/docs/src/routes/api/search.json/search.json
index c089dde..48c5b4a 100644
--- a/docs/src/routes/api/search.json/search.json
+++ b/docs/src/routes/api/search.json/search.json
@@ -3,24 +3,30 @@
"title": "Getting Started",
"href": "/docs/getting-started",
"description": "A quick guide to get started using barqode",
- "content": "The following guide will walk you through installing and setting up the barqode components in your Svelte project. Installation Install the package using your preferred package manager: npm install barqode Basic Usage The simplest way to use the library is with the BarqodeStream component for live scanning: import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .barqode { width: 100%; max-width: 600px; aspect-ratio: 4/3; } For detailed information about each component's capabilities and options, refer to their respective API documentation pages."
+ "content": "The following guide will walk you through installing and setting up the barqode components in your Svelte project. Installation Install the package using your preferred package manager: npm install barqode or pnpm add barqode or yarn add barqode Basic Usage The simplest way to use the library is with the BarqodeStream component for live scanning: import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .scanner { width: 100%; max-width: 600px; aspect-ratio: 4/3; } For detailed information about each component's capabilities and options, refer to their respective API documentation pages."
},
{
"title": "Introduction",
"href": "/docs/index",
"description": "What is Barqode?",
- "content": "Barqode provides a set of Svelte components for detecting and decoding QR codes and various other barcode formats right in the browser. It's a comprehensive solution that supports both camera streams and static image processing. Barqode started out as a port of $2. Components BarqodeStream** - continuously scans frames from a camera stream. BarqodeDropzone** - drag & drop, click to upload or capture images from camera. Features Real-time scanning**. Detect codes from live camera stream. Multiple formats**. Support for QR codes and various barcode standards. Visual feedback**. Customizable canvas based tracking of detected codes. Cross-browser**. Works across modern browsers with a $2 if needed. Camera selection**. Choose between front/rear cameras. Torch control**. Control device flashlight where supported. Responsive**. Components adapt to fill available space. Error handling**. Comprehensive error handling for camera/detection issues. Usage Example import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .barqode { width: 100%; max-width: 600px; aspect-ratio: 4/3; } Browser Support The components rely primarily on the $2 and $2, with fallbacks where possible. While the core scanning functionality uses the native BarcodeDetector where available, it falls back to a $2 to ensure consistent behavior across browsers. For a detailed compatibility overview, check each component's documentation."
+ "content": "Barqode provides a set of Svelte components for detecting and decoding QR codes and various other barcode formats right in the browser. It's a comprehensive solution that supports both camera streams and static image processing. Barqode started out as a port of $2. Components BarqodeStream** - continuously scans frames from a camera stream. BarqodeDropzone** - drag & drop image files or web images. BarqodeCapture** - traditional file upload field input with camera support. Features Real-time scanning**. Detect codes from live camera stream. Multiple formats**. Support for QR codes and various barcode standards. Visual feedback**. Customizable canvas based tracking of detected codes. Cross-browser**. Works across modern browsers with a $2 if needed. Camera selection**. Choose between front/rear cameras. Torch control**. Control device flashlight where supported. Responsive**. Components adapt to fill available space. Error handling**. Comprehensive error handling for camera/detection issues. Usage Example import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .scanner { width: 100%; max-width: 600px; aspect-ratio: 4/3; } Browser Support The components rely primarily on the $2 and $2, with fallbacks where possible. While the core scanning functionality uses the native BarcodeDetector where available, it falls back to a $2 to ensure consistent behavior across browsers. For a detailed compatibility overview, check each component's documentation."
+ },
+ {
+ "title": "BarqodeCapture",
+ "href": "/docs/components/BarqodeCapture",
+ "description": "File input with camera support on mobile.",
+ "content": " import Demo from '$lib/components/demos/barqode-capture.svelte'; The BarqodeCapture component is a simple file input with the capture attribute set to environment which allows users to take a picture with their camera. Demo Props formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2, one callback per image uploaded. If not barcode is detected, the array will be empty. Other props The BarqodeCapture component accepts all attributes that a standard input element accepts. By default, the following attributes are set: type=\"file\". This is required to make the input a file input. You should not change this. name=\"image\". This is the name of the file input. accept=\"image/*\". This restricts the file types that can be uploaded to images. capture=\"environment\". This tells the browser to open the camera when the input is clicked on mobile devices. You can choose between user and environment, which opens the front and back camera respectively. You can also disable this functionality by setting it to null. multiple. This allows the user to upload multiple files at once. You can disable this by settings this to false. Usage import { BarqodeCapture, type DetectedBarcode } from \"barqode\"; let result = $state(\"\"); function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCodes.map((detectedCode) => detectedCode.rawValue).join(\", \"); } Last detected: {result} .result { margin-top: 1.25rem; } Browser Support This component depends on the $2 which is widely supported in modern browsers."
},
{
"title": "BarqodeDropzone",
- "href": "/docs/components/barqode-dropzone",
- "description": "Click to upload images, drag & drop or use your camera to scan.",
- "content": " import Demo from '$lib/components/demos/barqode-dropzone.svelte'; This component functions as a file input with the capture attribute set to environment which allows users to take a picture with their camera. You can also drag-and-drop image files from your desktop or images embedded into other web pages anywhere in the area the component occupies. The images are directly scanned and positive results are indicated by the onDetect callback. Demo Usage import { BarqodeDropzone, type DetectedBarcode } from \"barqode\"; let result = $state(\"\"); let dragover = $state(false); function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCodes.map((detectedCode) => detectedCode.rawValue).join(\", \"); } function onDragover(isDraggingOver: boolean) { dragover = isDraggingOver; } Click to upload or drop an image here Last detected: {result} .barqode { width: 100%; aspect-ratio: 4 / 3; border: 2px solid #2563eb; } .dragover { border-color: white; } .instructions { height: 100%; width: 100%; display: flex; justify-content: center; align-items: center; } Props formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2, one callback per image. If not barcode is detected, the array will be empty. onDragover Type: (isDraggingOver: boolean) => void Callback function that is called when a file is dragged over the drop zone. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. Other props The BarqodeDropzone component accepts all attributes that a standard input element accepts. By default, the following attributes are set: type=\"file\". This is required to make the input a file input. You should not change this. name=\"image\". This is the name of the file input. accept=\"image/*\". This restricts the file types that can be uploaded to images. capture=\"environment\". This tells the browser to open the camera when the input is clicked on mobile devices. You can choose between user and environment, which opens the front and back camera respectively. You can also disable this functionality by setting it to null. multiple. This allows the user to upload multiple files at once. You can disable this by settings this to false. Browser Support This component depends on the $2 which is widely supported in modern browsers."
+ "href": "/docs/components/BarqodeDropzone",
+ "description": "File input with camera support on mobile.",
+ "content": " import Demo from '$lib/components/demos/barqode-drop-zone.svelte'; You can drag-and-drop image files from your desktop or images embedded into other web pages anywhere in the area the component occupies. The images are directly scanned and positive results are indicated by the onDetect callback. Demo Props formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2, one callback per image dropped. If not barcode is detected, the array will be empty. onDragover Type: (isDraggingOver: boolean) => void Callback function that is called when a file is dragged over the drop zone. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. Usage import { BarqodeDropzone, type DetectedBarcode } from \"barqode\"; import { DemoContainer } from \"@svecodocs/kit\"; let result = $state(\"\"); let dragover = $state(false); function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCodes.map((detectedCode) => detectedCode.rawValue).join(\", \"); } function onDragover(isDraggingOver: boolean) { dragover = isDraggingOver; } Drop an image here to detect QR-codes Last detected: {result} .dropzone { width: 100%; height: 200px; border: 2px solid #2563eb; display: flex; justify-content: center; align-items: center; } .dragover { border-color: white; } .result { margin-top: 1.25rem; } Browser Support This component depends on the $2 which is widely supported in modern browsers."
},
{
"title": "BarqodeStream",
- "href": "/docs/components/barqode-stream",
+ "href": "/docs/components/BarqodeStream",
"description": "Continuously scans frames from a camera stream.",
- "content": " import Demo from '$lib/components/demos/barqode-stream.svelte'; import { Callout } from '@svecodocs/kit'; The BarqodeStream component continuously scans frames from a camera stream and detects barcodes in real-time. Demo Usage import { BarqodeStream, type DetectedBarcode } from \"barqode\"; let loading = $state(true); let result: string | null = $state(null); function onCameraOn() { loading = false; } function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCode.map((code) => detectedCode.rawValue).join(\", \"); } function track(detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) { for (const detectedCode of detectedCodes) { const [firstPoint, ...otherPoints] = detectedCode.cornerPoints; ctx.strokeStyle = \"#2563eb\"; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(firstPoint.x, firstPoint.y); for (const { x, y } of otherPoints) { ctx.lineTo(x, y); } ctx.lineTo(firstPoint.x, firstPoint.y); ctx.closePath(); ctx.stroke(); } } {#if loading} Loading... {/if} Last detected: {result} .barqode { width: 100%; aspect-ratio: 4 / 3; } .loading-indicator { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; font-weight: bold; font-size: 2rem; } Props constraints Type: $2 Default: { video: { facingMode: \"environment\" } } Configure the the various camera options, for example whether to use front or rear camera. The object must be of type MediaTrackConstraints. The object is passed as-is to getUserMedia, which is the API call for requesting a camera stream: navigator.mediaDevices.getUserMedia({ audio: false, video: the_constraint_object_you_provide, }); When constraints is updated, a new camera stream is requested which triggers the onCameraOn callback again. You can catch errors with the onError callback. An error can occur when you try to use the front camera on a device that doesn't have one for example. formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Don't select more barcode formats than needed. Scanning becomes more expensive the more formats you select. Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. paused Type: boolean (bindable) Default: false Whether the camera stream is or should be paused. Bindable, which means that you can pause/unpause the stream from outside the component. Pausing the stream by setting paused to true is useful if you want to show some microinteraction after successful scans. When the you set it to false, the camera stream will be restarted and the onCameraOn callback function will be triggered again. torch Type: boolean Default: false Turn the camera flashlight on or off. This is not consistently supported by all devices and browsers. Support can even vary on the same device with the same browser. For example the rear camera often has a flashlight but the front camera does not. We can only tell if flashlight control is supported once the camera is loaded and the onCameraOn callback has been called. At the moment, enabling the torch may silently fail on unsupported devices, but in the onCameraOn callback payload you can access the MediaTrackCapabilities object, from which you can determine if the torch is supported. The camera stream must be reloaded when turning the torch on or off. That means the onCameraOn event will be emitted again. track Type: (detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) => void Callback function that can be used to visually highlight detected barcodes. A transparent canvas is overlaid on top of the camera stream. The track function is used to draw on this canvas. It receives an array of $2 and a $2 as the second argument. Note that when track is set the scanning frequency has to be increased. So if you want to go easy on your target device you might not want to enable tracking. The track function is called for every frame. It is important to keep the function as performant as possible. This can lead to performance issues on low-end devices and memory leaks if not handled correctly. onCameraOn Type: (capabilities: MediaTrackCapabilities) => void Callback function that is called when the camera stream is successfully loaded. It might take a while before the component is ready and the scanning process starts. The user has to be asked for camera access permission first and the camera stream has to be loaded. If you want to show a loading indicator, you can wait for this callback to be called. It is called as soon as the camera start streaming. The callback receives the a promise which resolves with the cameras $2 when everything is ready. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. onCameraOff Type: () => void Callback function that is called when the camera stream is stopped. This can happen when the camera constraints are modified, for example when switching between front and rear camera or when turning the torch on or off. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2. If you scan the same barcode multiple times in a row, onDetect is still only called once. When you hold a barcode in the camera, frames are actually decoded multiple times a second but you don't want to be flooded with callbacks that often. That's why the last decoded QR code is always cached and only new results are propagated. However, changing the value of paused resets this internal cache. Browser Support This component depends on the $2 which is widely supported in modern browsers."
+ "content": " import Demo from '$lib/components/demos/barqode-stream.svelte'; import { Callout } from '@svecodocs/kit'; The BarqodeStream component continuously scans frames from a camera stream and detects barcodes in real-time. Demo Props constraints Type: $2 Default: { video: { facingMode: \"environment\" } } Configure the the various camera options, for example whether to use front or rear camera. The object must be of type MediaTrackConstraints. The object is passed as-is to getUserMedia, which is the API call for requesting a camera stream: navigator.mediaDevices.getUserMedia({ audio: false, video: the_constraint_object_you_provide, }); When constraints is updated, a new camera stream is requested which triggers the onCameraOn callback again. You can catch errors with the onError callback. An error can occur when you try to use the front camera on a device that doesn't have one for example. formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Don't select more barcode formats than needed. Scanning becomes more expensive the more formats you select. Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. paused Type: boolean (bindable) Default: false Whether the camera stream is or should be paused. Bindable, which means that you can pause/unpause the stream from outside the component. Pausing the stream by setting paused to true is useful if you want to show some microinteraction after successful scans. When the you set it to false, the camera stream will be restarted and the onCameraOn callback function will be triggered again. torch Type: boolean Default: false Turn the camera flashlight on or off. This is not consistently supported by all devices and browsers. Support can even vary on the same device with the same browser. For example the rear camera often has a flashlight but the front camera does not. We can only tell if flashlight control is supported once the camera is loaded and the onCameraOn callback has been called. At the moment, enabling the torch may silently fail on unsupported devices, but in the onCameraOn callback payload you can access the MediaTrackCapabilities object, from which you can determine if the torch is supported. The camera stream must be reloaded when turning the torch on or off. That means the onCameraOn event will be emitted again. track Type: (detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) => void Callback function that can be used to visually highlight detected barcodes. A transparent canvas is overlaid on top of the camera stream. The track function is used to draw on this canvas. It receives an array of $2 and a $2 as the second argument. Note that when track is set the scanning frequency has to be increased. So if you want to go easy on your target device you might not want to enable tracking. The track function is called for every frame. It is important to keep the function as performant as possible. This can lead to performance issues on low-end devices and memory leaks if not handled correctly. onCameraOn Type: (capabilities: MediaTrackCapabilities) => void Callback function that is called when the camera stream is successfully loaded. It might take a while before the component is ready and the scanning process starts. The user has to be asked for camera access permission first and the camera stream has to be loaded. If you want to show a loading indicator, you can wait for this callback to be called. It is called as soon as the camera start streaming. The callback receives the a promise which resolves with the cameras $2 when everything is ready. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. onCameraOff Type: () => void Callback function that is called when the camera stream is stopped. This can happen when the camera constraints are modified, for example when switching between front and rear camera or when turning the torch on or off. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2. If you scan the same barcode multiple times in a row, onDetect is still only called once. When you hold a barcode in the camera, frames are actually decoded multiple times a second but you don't want to be flooded with callbacks that often. That's why the last decoded QR code is always cached and only new results are propagated. However, changing the value of paused resets this internal cache. Usage import { BarqodeStream, type DetectedBarcode } from \"barqode\"; let loading = $state(true); let result: string | null = $state(null); function onCameraOn() { loading = false; } function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCode.map((code) => detectedCode.rawValue).join(\", \"); } function track(detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) { for (const detectedCode of detectedCodes) { const [firstPoint, ...otherPoints] = detectedCode.cornerPoints; ctx.strokeStyle = \"#2563eb\"; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(firstPoint.x, firstPoint.y); for (const { x, y } of otherPoints) { ctx.lineTo(x, y); } ctx.lineTo(firstPoint.x, firstPoint.y); ctx.closePath(); ctx.stroke(); } } {#if loading} Loading... {/if} Last detected: {result} .scanner { width: 100%; aspect-ratio: 4 / 3; } .loading-indicator { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; font-weight: bold; font-size: 2rem; } .result { margin-top: 1.25rem; } Browser Support This component depends on the $2 which is widely supported in modern browsers."
}
]
diff --git a/package.json b/package.json
index 782df21..5f062f9 100644
--- a/package.json
+++ b/package.json
@@ -34,13 +34,13 @@
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-svelte": "^2.46.1",
"globals": "^15.13.0",
- "prettier": "^3.4.2",
+ "prettier": "^3.4.1",
"prettier-plugin-svelte": "^3.3.2",
"prettier-plugin-tailwindcss": "^0.6.9",
- "svelte": "^5.7.0",
+ "svelte": "^5.4.0",
"svelte-eslint-parser": "^0.43.0",
"typescript": "^5.7.2",
"typescript-eslint": "^8.17.0",
- "wrangler": "^3.92.0"
+ "wrangler": "^3.91.0"
}
}
diff --git a/packages/barqode/package.json b/packages/barqode/package.json
index 5d3c0da..30afe5c 100644
--- a/packages/barqode/package.json
+++ b/packages/barqode/package.json
@@ -41,12 +41,12 @@
"@sveltejs/adapter-auto": "^3.3.1",
"@sveltejs/kit": "^2.9.0",
"@sveltejs/package": "^2.3.7",
- "@sveltejs/vite-plugin-svelte": "^5.0.1",
+ "@sveltejs/vite-plugin-svelte": "^4.0.2",
"publint": "^0.2.12",
- "svelte": "^5.7.0",
- "svelte-check": "^4.1.1",
+ "svelte": "^5.4.0",
+ "svelte-check": "^4.1.0",
"typescript": "^5.7.2",
- "vite": "^6.0.3"
+ "vite": "^5.4.11"
},
"license": "MIT",
"contributors": [
@@ -61,7 +61,7 @@
],
"dependencies": {
"barcode-detector": "^2.3.1",
- "runed": "^0.16.2",
+ "runed": "^0.16.1",
"webrtc-adapter": "^9.0.1"
}
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 19ed131..4bfe73b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -37,25 +37,25 @@ importers:
version: 9.1.0(eslint@9.16.0(jiti@2.4.1))
eslint-plugin-svelte:
specifier: ^2.46.1
- version: 2.46.1(eslint@9.16.0(jiti@2.4.1))(svelte@5.7.0)
+ version: 2.46.1(eslint@9.16.0(jiti@2.4.1))(svelte@5.4.0)
globals:
specifier: ^15.13.0
version: 15.13.0
prettier:
- specifier: ^3.4.2
- version: 3.4.2
+ specifier: ^3.4.1
+ version: 3.4.1
prettier-plugin-svelte:
specifier: ^3.3.2
- version: 3.3.2(prettier@3.4.2)(svelte@5.7.0)
+ version: 3.3.2(prettier@3.4.1)(svelte@5.4.0)
prettier-plugin-tailwindcss:
specifier: ^0.6.9
- version: 0.6.9(prettier-plugin-svelte@3.3.2(prettier@3.4.2)(svelte@5.7.0))(prettier@3.4.2)
+ version: 0.6.9(prettier-plugin-svelte@3.3.2(prettier@3.4.1)(svelte@5.4.0))(prettier@3.4.1)
svelte:
- specifier: ^5.7.0
- version: 5.7.0
+ specifier: ^5.4.0
+ version: 5.4.0
svelte-eslint-parser:
specifier: ^0.43.0
- version: 0.43.0(svelte@5.7.0)
+ version: 0.43.0(svelte@5.4.0)
typescript:
specifier: ^5.7.2
version: 5.7.2
@@ -63,44 +63,44 @@ importers:
specifier: ^8.17.0
version: 8.17.0(eslint@9.16.0(jiti@2.4.1))(typescript@5.7.2)
wrangler:
- specifier: ^3.92.0
- version: 3.92.0(@cloudflare/workers-types@4.20241202.0)
+ specifier: ^3.91.0
+ version: 3.91.0(@cloudflare/workers-types@4.20241202.0)
docs:
devDependencies:
'@svecodocs/kit':
- specifier: ^0.1.1
- version: 0.1.1(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(bits-ui@1.0.0-next.65(svelte@5.7.0))(svelte@5.7.0)(tailwindcss@4.0.0-beta.4)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
+ specifier: ^0.0.5
+ version: 0.0.5(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(bits-ui@1.0.0-next.65(svelte@5.4.0))(svelte@5.4.0)(tailwindcss@4.0.0-beta.4)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
'@sveltejs/adapter-cloudflare':
specifier: ^4.8.0
- version: 4.8.0(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(wrangler@3.92.0(@cloudflare/workers-types@4.20241202.0))
+ version: 4.8.0(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(wrangler@3.91.0(@cloudflare/workers-types@4.20241202.0))
'@sveltejs/kit':
specifier: ^2.9.0
- version: 2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
+ version: 2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
'@sveltejs/vite-plugin-svelte':
- specifier: ^5.0.1
- version: 5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
+ specifier: ^4.0.2
+ version: 4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
'@tailwindcss/vite':
specifier: 4.0.0-beta.4
- version: 4.0.0-beta.4(postcss-load-config@3.1.4(postcss@8.4.49))(postcss@8.4.49)(svelte@5.7.0)(typescript@5.7.2)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
+ version: 4.0.0-beta.4(postcss-load-config@3.1.4(postcss@8.4.49))(postcss@8.4.49)(svelte@5.4.0)(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
barqode:
specifier: workspace:^
version: link:../packages/barqode
mdsx:
specifier: ^0.0.6
- version: 0.0.6(svelte@5.7.0)
+ version: 0.0.6(svelte@5.4.0)
phosphor-svelte:
specifier: ^3.0.0
- version: 3.0.0(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
+ version: 3.0.0(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
svelte:
- specifier: ^5.7.0
- version: 5.7.0
+ specifier: ^5.4.0
+ version: 5.4.0
svelte-check:
- specifier: ^4.1.1
- version: 4.1.1(svelte@5.7.0)(typescript@5.7.2)
+ specifier: ^4.1.0
+ version: 4.1.0(svelte@5.4.0)(typescript@5.7.2)
svelte-preprocess:
specifier: ^6.0.3
- version: 6.0.3(postcss-load-config@3.1.4(postcss@8.4.49))(postcss@8.4.49)(svelte@5.7.0)(typescript@5.7.2)
+ version: 6.0.3(postcss-load-config@3.1.4(postcss@8.4.49))(postcss@8.4.49)(svelte@5.4.0)(typescript@5.7.2)
tailwindcss:
specifier: 4.0.0-beta.4
version: 4.0.0-beta.4
@@ -111,8 +111,8 @@ importers:
specifier: ^0.2.1
version: 0.2.1(acorn@8.14.0)
vite:
- specifier: ^6.0.3
- version: 6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)
+ specifier: ^5.4.11
+ version: 5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)
packages/barqode:
dependencies:
@@ -120,39 +120,39 @@ importers:
specifier: ^2.3.1
version: 2.3.1
runed:
- specifier: ^0.16.2
- version: 0.16.2(svelte@5.7.0)
+ specifier: ^0.16.1
+ version: 0.16.1(svelte@5.4.0)
webrtc-adapter:
specifier: ^9.0.1
version: 9.0.1
devDependencies:
'@sveltejs/adapter-auto':
specifier: ^3.3.1
- version: 3.3.1(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))
+ version: 3.3.1(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))
'@sveltejs/kit':
specifier: ^2.9.0
- version: 2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
+ version: 2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
'@sveltejs/package':
specifier: ^2.3.7
- version: 2.3.7(svelte@5.7.0)(typescript@5.7.2)
+ version: 2.3.7(svelte@5.4.0)(typescript@5.7.2)
'@sveltejs/vite-plugin-svelte':
- specifier: ^5.0.1
- version: 5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
+ specifier: ^4.0.2
+ version: 4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
publint:
specifier: ^0.2.12
version: 0.2.12
svelte:
- specifier: ^5.7.0
- version: 5.7.0
+ specifier: ^5.4.0
+ version: 5.4.0
svelte-check:
- specifier: ^4.1.1
- version: 4.1.1(svelte@5.7.0)(typescript@5.7.2)
+ specifier: ^4.1.0
+ version: 4.1.0(svelte@5.4.0)(typescript@5.7.2)
typescript:
specifier: ^5.7.2
version: 5.7.2
vite:
- specifier: ^6.0.3
- version: 6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)
+ specifier: ^5.4.11
+ version: 5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)
packages:
@@ -226,38 +226,38 @@ packages:
resolution: {integrity: sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==}
engines: {node: '>=16.13'}
- '@cloudflare/workerd-darwin-64@1.20241106.2':
- resolution: {integrity: sha512-p3PzgiMBp9xKo4dMINM1RkrC+miUtz65IuuMCEdCa5QZTM0eyEGcBj1A9/lmS3wW72oMfRTo6CxCkqPteFJeBA==}
+ '@cloudflare/workerd-darwin-64@1.20241106.1':
+ resolution: {integrity: sha512-zxvaToi1m0qzAScrxFt7UvFVqU8DxrCO2CinM1yQkv5no7pA1HolpIrwZ0xOhR3ny64Is2s/J6BrRjpO5dM9Zw==}
engines: {node: '>=16'}
cpu: [x64]
os: [darwin]
- '@cloudflare/workerd-darwin-arm64@1.20241106.2':
- resolution: {integrity: sha512-AZQTAKG6bP9z0SKSXQGlXR2K2MQnDMtKC78NGjN0NOcjALTsFlLFhczaLvmuJjsT16k9yJUq2Gl+NG4ao/qgvg==}
+ '@cloudflare/workerd-darwin-arm64@1.20241106.1':
+ resolution: {integrity: sha512-j3dg/42D/bPgfNP3cRUBxF+4waCKO/5YKwXNj+lnVOwHxDu+ne5pFw9TIkKYcWTcwn0ZUkbNZNM5rhJqRn4xbg==}
engines: {node: '>=16'}
cpu: [arm64]
os: [darwin]
- '@cloudflare/workerd-linux-64@1.20241106.2':
- resolution: {integrity: sha512-TWIcVdUzU7w7YP2OEIgTDtNl9jyzjxOptjRDw7jhSUsQy/02IjBLP+ZnNpgB5CUJ1tCbcOp1L2IGhZmayd7OEQ==}
+ '@cloudflare/workerd-linux-64@1.20241106.1':
+ resolution: {integrity: sha512-Ih+Ye8E1DMBXcKrJktGfGztFqHKaX1CeByqshmTbODnWKHt6O65ax3oTecUwyC0+abuyraOpAtdhHNpFMhUkmw==}
engines: {node: '>=16'}
cpu: [x64]
os: [linux]
- '@cloudflare/workerd-linux-arm64@1.20241106.2':
- resolution: {integrity: sha512-f5Mn9IzfLs9yGjB2UCcKh+I7Ahiw6xqiQ9f/FGsHjsgLELjJ8JCKBwXmc9WdfNmVPae5jNCg2N5qVfDoWBKbCA==}
+ '@cloudflare/workerd-linux-arm64@1.20241106.1':
+ resolution: {integrity: sha512-mdQFPk4+14Yywn7n1xIzI+6olWM8Ybz10R7H3h+rk0XulMumCWUCy1CzIDauOx6GyIcSgKIibYMssVHZR30ObA==}
engines: {node: '>=16'}
cpu: [arm64]
os: [linux]
- '@cloudflare/workerd-windows-64@1.20241106.2':
- resolution: {integrity: sha512-kdLExN3rktax23iHUKP7AHQP0HT0yGHik58fMP4kExjsMnwxw92TLI3n4HlmEqsbtMtwr9rhTJVaMBRUXq0aXw==}
+ '@cloudflare/workerd-windows-64@1.20241106.1':
+ resolution: {integrity: sha512-4rtcss31E/Rb/PeFocZfr+B9i1MdrkhsTBWizh8siNR4KMmkslU2xs2wPaH1z8+ErxkOsHrKRa5EPLh5rIiFeg==}
engines: {node: '>=16'}
cpu: [x64]
os: [win32]
- '@cloudflare/workers-shared@0.9.1':
- resolution: {integrity: sha512-56w4pL5D6ODw7+SieMgdwrwNyyT7tY8H4UPD4/95TSBVjqDcMPq0Dr+D4rJ+nHK+290o4ZnSiOOiKqRMqy6tPg==}
+ '@cloudflare/workers-shared@0.9.0':
+ resolution: {integrity: sha512-eP6Ir45uPbKnpADVzUCtkRUYxYxjB1Ew6n/whTJvHu8H4m93USHAceCMm736VBZdlxuhXXUjEP3fCUxKPn+cfw==}
engines: {node: '>=16.7.0'}
'@cloudflare/workers-types@4.20241202.0':
@@ -280,6 +280,12 @@ packages:
peerDependencies:
esbuild: '*'
+ '@esbuild/aix-ppc64@0.21.5':
+ resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [aix]
+
'@esbuild/aix-ppc64@0.24.0':
resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==}
engines: {node: '>=18'}
@@ -292,6 +298,12 @@ packages:
cpu: [arm64]
os: [android]
+ '@esbuild/android-arm64@0.21.5':
+ resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [android]
+
'@esbuild/android-arm64@0.24.0':
resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==}
engines: {node: '>=18'}
@@ -304,6 +316,12 @@ packages:
cpu: [arm]
os: [android]
+ '@esbuild/android-arm@0.21.5':
+ resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [android]
+
'@esbuild/android-arm@0.24.0':
resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==}
engines: {node: '>=18'}
@@ -316,6 +334,12 @@ packages:
cpu: [x64]
os: [android]
+ '@esbuild/android-x64@0.21.5':
+ resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [android]
+
'@esbuild/android-x64@0.24.0':
resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==}
engines: {node: '>=18'}
@@ -328,6 +352,12 @@ packages:
cpu: [arm64]
os: [darwin]
+ '@esbuild/darwin-arm64@0.21.5':
+ resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [darwin]
+
'@esbuild/darwin-arm64@0.24.0':
resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==}
engines: {node: '>=18'}
@@ -340,6 +370,12 @@ packages:
cpu: [x64]
os: [darwin]
+ '@esbuild/darwin-x64@0.21.5':
+ resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [darwin]
+
'@esbuild/darwin-x64@0.24.0':
resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==}
engines: {node: '>=18'}
@@ -352,6 +388,12 @@ packages:
cpu: [arm64]
os: [freebsd]
+ '@esbuild/freebsd-arm64@0.21.5':
+ resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [freebsd]
+
'@esbuild/freebsd-arm64@0.24.0':
resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==}
engines: {node: '>=18'}
@@ -364,6 +406,12 @@ packages:
cpu: [x64]
os: [freebsd]
+ '@esbuild/freebsd-x64@0.21.5':
+ resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [freebsd]
+
'@esbuild/freebsd-x64@0.24.0':
resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==}
engines: {node: '>=18'}
@@ -376,6 +424,12 @@ packages:
cpu: [arm64]
os: [linux]
+ '@esbuild/linux-arm64@0.21.5':
+ resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [linux]
+
'@esbuild/linux-arm64@0.24.0':
resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==}
engines: {node: '>=18'}
@@ -388,6 +442,12 @@ packages:
cpu: [arm]
os: [linux]
+ '@esbuild/linux-arm@0.21.5':
+ resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [linux]
+
'@esbuild/linux-arm@0.24.0':
resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==}
engines: {node: '>=18'}
@@ -400,6 +460,12 @@ packages:
cpu: [ia32]
os: [linux]
+ '@esbuild/linux-ia32@0.21.5':
+ resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [linux]
+
'@esbuild/linux-ia32@0.24.0':
resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==}
engines: {node: '>=18'}
@@ -412,6 +478,12 @@ packages:
cpu: [loong64]
os: [linux]
+ '@esbuild/linux-loong64@0.21.5':
+ resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==}
+ engines: {node: '>=12'}
+ cpu: [loong64]
+ os: [linux]
+
'@esbuild/linux-loong64@0.24.0':
resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==}
engines: {node: '>=18'}
@@ -424,6 +496,12 @@ packages:
cpu: [mips64el]
os: [linux]
+ '@esbuild/linux-mips64el@0.21.5':
+ resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==}
+ engines: {node: '>=12'}
+ cpu: [mips64el]
+ os: [linux]
+
'@esbuild/linux-mips64el@0.24.0':
resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==}
engines: {node: '>=18'}
@@ -436,6 +514,12 @@ packages:
cpu: [ppc64]
os: [linux]
+ '@esbuild/linux-ppc64@0.21.5':
+ resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [linux]
+
'@esbuild/linux-ppc64@0.24.0':
resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==}
engines: {node: '>=18'}
@@ -448,6 +532,12 @@ packages:
cpu: [riscv64]
os: [linux]
+ '@esbuild/linux-riscv64@0.21.5':
+ resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==}
+ engines: {node: '>=12'}
+ cpu: [riscv64]
+ os: [linux]
+
'@esbuild/linux-riscv64@0.24.0':
resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==}
engines: {node: '>=18'}
@@ -460,6 +550,12 @@ packages:
cpu: [s390x]
os: [linux]
+ '@esbuild/linux-s390x@0.21.5':
+ resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==}
+ engines: {node: '>=12'}
+ cpu: [s390x]
+ os: [linux]
+
'@esbuild/linux-s390x@0.24.0':
resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==}
engines: {node: '>=18'}
@@ -472,6 +568,12 @@ packages:
cpu: [x64]
os: [linux]
+ '@esbuild/linux-x64@0.21.5':
+ resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [linux]
+
'@esbuild/linux-x64@0.24.0':
resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==}
engines: {node: '>=18'}
@@ -484,6 +586,12 @@ packages:
cpu: [x64]
os: [netbsd]
+ '@esbuild/netbsd-x64@0.21.5':
+ resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [netbsd]
+
'@esbuild/netbsd-x64@0.24.0':
resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==}
engines: {node: '>=18'}
@@ -502,6 +610,12 @@ packages:
cpu: [x64]
os: [openbsd]
+ '@esbuild/openbsd-x64@0.21.5':
+ resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [openbsd]
+
'@esbuild/openbsd-x64@0.24.0':
resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==}
engines: {node: '>=18'}
@@ -514,6 +628,12 @@ packages:
cpu: [x64]
os: [sunos]
+ '@esbuild/sunos-x64@0.21.5':
+ resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [sunos]
+
'@esbuild/sunos-x64@0.24.0':
resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==}
engines: {node: '>=18'}
@@ -526,6 +646,12 @@ packages:
cpu: [arm64]
os: [win32]
+ '@esbuild/win32-arm64@0.21.5':
+ resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [win32]
+
'@esbuild/win32-arm64@0.24.0':
resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==}
engines: {node: '>=18'}
@@ -538,6 +664,12 @@ packages:
cpu: [ia32]
os: [win32]
+ '@esbuild/win32-ia32@0.21.5':
+ resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [win32]
+
'@esbuild/win32-ia32@0.24.0':
resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==}
engines: {node: '>=18'}
@@ -550,6 +682,12 @@ packages:
cpu: [x64]
os: [win32]
+ '@esbuild/win32-x64@0.21.5':
+ resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [win32]
+
'@esbuild/win32-x64@0.24.0':
resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==}
engines: {node: '>=18'}
@@ -566,12 +704,12 @@ packages:
resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==}
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
- '@eslint/config-array@0.19.1':
- resolution: {integrity: sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==}
+ '@eslint/config-array@0.19.0':
+ resolution: {integrity: sha512-zdHg2FPIFNKPdcHWtiNT+jEFCHYVplAXRDlQDyqy0zGx/q2parwh7brGJSiTxRk/TSMkbM//zt/f5CHgyTyaSQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@eslint/core@0.9.1':
- resolution: {integrity: sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==}
+ '@eslint/core@0.9.0':
+ resolution: {integrity: sha512-7ATR9F0e4W85D/0w7cU0SNj7qkAexMG+bAHEZOjo9akvGuhHE2m7umzWzfnpa0XAg5Kxc1BWmtPMV67jJ+9VUg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@eslint/eslintrc@3.2.0':
@@ -582,12 +720,12 @@ packages:
resolution: {integrity: sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@eslint/object-schema@2.1.5':
- resolution: {integrity: sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==}
+ '@eslint/object-schema@2.1.4':
+ resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@eslint/plugin-kit@0.2.4':
- resolution: {integrity: sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==}
+ '@eslint/plugin-kit@0.2.3':
+ resolution: {integrity: sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@fastify/busboy@2.1.1':
@@ -884,8 +1022,8 @@ packages:
'@shikijs/vscode-textmate@9.3.0':
resolution: {integrity: sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA==}
- '@svecodocs/kit@0.1.1':
- resolution: {integrity: sha512-VOaN+twbkStWo67QAk7DO88+CxVeTNzC49E4g7Ru0aJnBxzyXChr2dXUCJNyyONQ2LrvMnnjEQxkh69RuScEzA==}
+ '@svecodocs/kit@0.0.5':
+ resolution: {integrity: sha512-DrwREJDQBDZTm6UOHg27CqpObFMUBcgYH9P94PSVsdJtaYOAv5GF33cjxwxvwNgczKgcpeZs4xWu3/HdFI5JKA==}
peerDependencies:
'@sveltejs/kit': ^2.0.0
bits-ui: 1.0.0-next.65
@@ -918,20 +1056,20 @@ packages:
peerDependencies:
svelte: ^3.44.0 || ^4.0.0 || ^5.0.0-next.1
- '@sveltejs/vite-plugin-svelte-inspector@4.0.1':
- resolution: {integrity: sha512-J/Nmb2Q2y7mck2hyCX4ckVHcR5tu2J+MtBEQqpDrrgELZ2uvraQcK/ioCV61AqkdXFgriksOKIceDcQmqnGhVw==}
+ '@sveltejs/vite-plugin-svelte-inspector@3.0.1':
+ resolution: {integrity: sha512-2CKypmj1sM4GE7HjllT7UKmo4Q6L5xFRd7VMGEWhYnZ+wc6AUVU01IBd7yUi6WnFndEwWoMNOd6e8UjoN0nbvQ==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22}
peerDependencies:
- '@sveltejs/vite-plugin-svelte': ^5.0.0
- svelte: ^5.0.0
- vite: ^6.0.0
+ '@sveltejs/vite-plugin-svelte': ^4.0.0-next.0||^4.0.0
+ svelte: ^5.0.0-next.96 || ^5.0.0
+ vite: ^5.0.0
- '@sveltejs/vite-plugin-svelte@5.0.1':
- resolution: {integrity: sha512-D5l5+STmywGoLST07T9mrqqFFU+xgv5fqyTWM+VbxTvQ6jujNn4h3lQNCvlwVYs4Erov8i0K5Rwr3LQtmBYmBw==}
+ '@sveltejs/vite-plugin-svelte@4.0.2':
+ resolution: {integrity: sha512-Y9r/fWy539XlAC7+5wfNJ4zH6TygUYoQ0Eegzp0zDDqhJ54+92gOyOX1l4MO1cJSx0O+Gp13YePT5XEa3+kX0w==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22}
peerDependencies:
- svelte: ^5.0.0
- vite: ^6.0.0
+ svelte: ^5.0.0-next.96 || ^5.0.0
+ vite: ^5.0.0
'@svitejs/changesets-changelog-github-compact@1.2.0':
resolution: {integrity: sha512-08eKiDAjj4zLug1taXSIJ0kGL5cawjVCyJkBb6EWSg5fEPX6L+Wtr0CH2If4j5KYylz85iaZiFlUItvgJvll5g==}
@@ -1373,8 +1511,8 @@ packages:
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
engines: {node: '>=8'}
- dotenv@16.4.7:
- resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==}
+ dotenv@16.4.6:
+ resolution: {integrity: sha512-JhcR/+KIjkkjiU8yEpaB/USlzVi3i5whwOjpIRNGi9svKEXZSe+Qp6IWAjFjv+2GViAoDRCUv/QLNziQxsLqDg==}
engines: {node: '>=12'}
emoji-regex-xs@1.0.0:
@@ -1403,6 +1541,11 @@ packages:
engines: {node: '>=12'}
hasBin: true
+ esbuild@0.21.5:
+ resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==}
+ engines: {node: '>=12'}
+ hasBin: true
+
esbuild@0.24.0:
resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==}
engines: {node: '>=18'}
@@ -2100,8 +2243,8 @@ packages:
engines: {node: '>=10.0.0'}
hasBin: true
- miniflare@3.20241106.2:
- resolution: {integrity: sha512-40JAPtNFMFrSW41CSxPgDykX4CgDokDfTZgDYYL8dsODb7pdAlj/dvlDPnaonkyXjRO7svyDwAavQT6IdagMwA==}
+ miniflare@3.20241106.1:
+ resolution: {integrity: sha512-dM3RBlJE8rUFxnqlPCaFCq0E7qQqEQvKbYX7W/APGCK+rLcyLmEBzC4GQR/niXdNM/oV6gdg9AA50ghnn2ALuw==}
engines: {node: '>=16.13'}
hasBin: true
@@ -2221,8 +2364,8 @@ packages:
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
engines: {node: '>=6'}
- package-manager-detector@0.2.7:
- resolution: {integrity: sha512-g4+387DXDKlZzHkP+9FLt8yKj8+/3tOkPv7DVTJGGRm00RkEWgqbFstX1mXJ4M0VDYhUqsTOiISqNOJnhAu3PQ==}
+ package-manager-detector@0.2.6:
+ resolution: {integrity: sha512-9vPH3qooBlYRJdmdYP00nvjZOulm40r5dhtal8st18ctf+6S1k7pi5yIHLvI4w5D70x0Y+xdVD9qITH0QO/A8A==}
parent-module@1.0.1:
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
@@ -2383,8 +2526,8 @@ packages:
engines: {node: '>=10.13.0'}
hasBin: true
- prettier@3.4.2:
- resolution: {integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==}
+ prettier@3.4.1:
+ resolution: {integrity: sha512-G+YdqtITVZmOJje6QkXQWzl3fSfMxFwm1tjTyo9exhkmWSqC4Yhd1+lug++IlR2mvRVAxEDDWYkQdeSztajqgg==}
engines: {node: '>=14'}
hasBin: true
@@ -2489,6 +2632,10 @@ packages:
resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
engines: {node: '>=8'}
+ resolve.exports@2.0.3:
+ resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==}
+ engines: {node: '>=10'}
+
resolve@1.22.8:
resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
hasBin: true
@@ -2520,8 +2667,8 @@ packages:
peerDependencies:
svelte: ^5.0.0-next.1
- runed@0.16.2:
- resolution: {integrity: sha512-zA6NrXp+QGRMB2vC03hAqYshbkWI5N3sCm45X+fnr5oIWZcZw7sm3Gn6orqopy9IOvzRX6nvdD6xOMg+4GIuhg==}
+ runed@0.16.1:
+ resolution: {integrity: sha512-k9ylt7sfEQiqOo2FmuilkLSk92pDzMSeVHFb8aPJGFPQPG9ErUxhfcHQwnmUhT03F8oQeO6bKB/TDoPKhdXbTA==}
peerDependencies:
svelte: ^5.0.0-next.1
@@ -2641,8 +2788,8 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
- svelte-check@4.1.1:
- resolution: {integrity: sha512-NfaX+6Qtc8W/CyVGS/F7/XdiSSyXz+WGYA9ZWV3z8tso14V2vzjfXviKaTFEzB7g8TqfgO2FOzP6XT4ApSTUTw==}
+ svelte-check@4.1.0:
+ resolution: {integrity: sha512-AflEZYqI578KuDZcpcorPSf597LStxlkN7XqXi38u09zlHODVKd7c+7OuubGzbhgGRUqNTdQCZ+Ga96iRXEf2g==}
engines: {node: '>= 18.0.0'}
hasBin: true
peerDependencies:
@@ -2701,14 +2848,14 @@ packages:
peerDependencies:
svelte: ^5.0.0-next.126
- svelte2tsx@0.7.30:
- resolution: {integrity: sha512-sHXK/vw/sVJmFuPSq6zeKrtuZKvo0jJyEi8ybN0dfrqSYVvHu8zFbO0zQKAL8y/fYackYojH41EJGe6v8rd5fw==}
+ svelte2tsx@0.7.28:
+ resolution: {integrity: sha512-TJjA+kU8AnkyoprZPgQACMfTX8N0MA5NsIL//h9IuHOxmmaCLluqhcZU+fCkWipi5c/pooHLFOMpqjhq4v7JLQ==}
peerDependencies:
svelte: ^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0
typescript: ^4.9.4 || ^5.0.0
- svelte@5.7.0:
- resolution: {integrity: sha512-npaSigW2579iHv2wZrNyrlQQ8SQvTlBEN0rnxRQ7XVAcxhKHgGJYVYsErjPUKoyhAcjM6MZMnaE20KuXfzy8ug==}
+ svelte@5.4.0:
+ resolution: {integrity: sha512-2I/mjD8cXDpKfdfUK+T6yo/OzugMXIm8lhyJUFM5F/gICMYnkl3C/+4cOSpia8TqpDsi6Qfm5+fdmBNMNmaf2g==}
engines: {node: '>=18'}
tailwind-merge@2.5.5:
@@ -2736,8 +2883,8 @@ packages:
resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==}
engines: {node: '>=8'}
- terser@5.37.0:
- resolution: {integrity: sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==}
+ terser@5.36.0:
+ resolution: {integrity: sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==}
engines: {node: '>=10'}
hasBin: true
@@ -2851,27 +2998,22 @@ packages:
vfile@6.0.3:
resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
- vite@6.0.3:
- resolution: {integrity: sha512-Cmuo5P0ENTN6HxLSo6IHsjCLn/81Vgrp81oaiFFMRa8gGDj5xEjIcEpf2ZymZtZR8oU0P2JX5WuUp/rlXcHkAw==}
- engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
+ vite@5.4.11:
+ resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==}
+ engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
peerDependencies:
- '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
- jiti: '>=1.21.0'
+ '@types/node': ^18.0.0 || >=20.0.0
less: '*'
lightningcss: ^1.21.0
sass: '*'
sass-embedded: '*'
stylus: '*'
sugarss: '*'
- terser: ^5.16.0
- tsx: ^4.8.1
- yaml: ^2.4.2
+ terser: ^5.4.0
peerDependenciesMeta:
'@types/node':
optional: true
- jiti:
- optional: true
less:
optional: true
lightningcss:
@@ -2886,10 +3028,6 @@ packages:
optional: true
terser:
optional: true
- tsx:
- optional: true
- yaml:
- optional: true
vitefu@1.0.4:
resolution: {integrity: sha512-y6zEE3PQf6uu/Mt6DTJ9ih+kyJLr4XcSgHR2zUkM8SWDhuixEJxfJ6CZGMHh1Ec3vPLoEA0IHU5oWzVqw8ulow==}
@@ -2921,8 +3059,8 @@ packages:
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
engines: {node: '>=0.10.0'}
- workerd@1.20241106.2:
- resolution: {integrity: sha512-Xw2hVIXA9MvDSHx3IX55ouGRPsQUzG0oadRVeQRs5xwgmiKshR0ompyYDO1JUvozJazfjcCSdgV8jyLcPqNIDA==}
+ workerd@1.20241106.1:
+ resolution: {integrity: sha512-1GdKl0kDw8rrirr/ThcK66Kbl4/jd4h8uHx5g7YHBrnenY5SX1UPuop2cnCzYUxlg55kPjzIqqYslz1muRFgFw==}
engines: {node: '>=16'}
hasBin: true
@@ -2930,8 +3068,8 @@ packages:
resolution: {integrity: sha512-+TvsA6VAVoMC3XDKR5MoC/qlLqDixEfOBysDEKnPIPou/NvoPWCAuXHXMsswwlvmEuvX56lQjvELLyLuzTKvRw==}
engines: {node: '>=12'}
- wrangler@3.92.0:
- resolution: {integrity: sha512-MC+s+stSYQKXEn7ucENhzrw+RyMc5bSIRQ2EVcjCtqjAtO82uKQBatW2YXK5hkQOZg9Kfcdqgkcnpf/Bn94FiA==}
+ wrangler@3.91.0:
+ resolution: {integrity: sha512-Hdzn6wbY9cz5kL85ZUvWLwLIH7nPaEVRblfms40jhRf4qQO/Zf74aFlku8rQFbe8/2aVZFaxJVfBd6JQMeMSBQ==}
engines: {node: '>=16.17.0'}
hasBin: true
peerDependencies:
@@ -3050,7 +3188,7 @@ snapshots:
fs-extra: 7.0.1
mri: 1.2.0
p-limit: 2.3.0
- package-manager-detector: 0.2.7
+ package-manager-detector: 0.2.6
picocolors: 1.1.1
resolve-from: 5.0.0
semver: 7.6.3
@@ -3150,22 +3288,22 @@ snapshots:
dependencies:
mime: 3.0.0
- '@cloudflare/workerd-darwin-64@1.20241106.2':
+ '@cloudflare/workerd-darwin-64@1.20241106.1':
optional: true
- '@cloudflare/workerd-darwin-arm64@1.20241106.2':
+ '@cloudflare/workerd-darwin-arm64@1.20241106.1':
optional: true
- '@cloudflare/workerd-linux-64@1.20241106.2':
+ '@cloudflare/workerd-linux-64@1.20241106.1':
optional: true
- '@cloudflare/workerd-linux-arm64@1.20241106.2':
+ '@cloudflare/workerd-linux-arm64@1.20241106.1':
optional: true
- '@cloudflare/workerd-windows-64@1.20241106.2':
+ '@cloudflare/workerd-windows-64@1.20241106.1':
optional: true
- '@cloudflare/workers-shared@0.9.1':
+ '@cloudflare/workers-shared@0.9.0':
dependencies:
mime: 3.0.0
zod: 3.23.8
@@ -3191,108 +3329,162 @@ snapshots:
escape-string-regexp: 4.0.0
rollup-plugin-node-polyfills: 0.2.1
+ '@esbuild/aix-ppc64@0.21.5':
+ optional: true
+
'@esbuild/aix-ppc64@0.24.0':
optional: true
'@esbuild/android-arm64@0.17.19':
optional: true
+ '@esbuild/android-arm64@0.21.5':
+ optional: true
+
'@esbuild/android-arm64@0.24.0':
optional: true
'@esbuild/android-arm@0.17.19':
optional: true
+ '@esbuild/android-arm@0.21.5':
+ optional: true
+
'@esbuild/android-arm@0.24.0':
optional: true
'@esbuild/android-x64@0.17.19':
optional: true
+ '@esbuild/android-x64@0.21.5':
+ optional: true
+
'@esbuild/android-x64@0.24.0':
optional: true
'@esbuild/darwin-arm64@0.17.19':
optional: true
+ '@esbuild/darwin-arm64@0.21.5':
+ optional: true
+
'@esbuild/darwin-arm64@0.24.0':
optional: true
'@esbuild/darwin-x64@0.17.19':
optional: true
+ '@esbuild/darwin-x64@0.21.5':
+ optional: true
+
'@esbuild/darwin-x64@0.24.0':
optional: true
'@esbuild/freebsd-arm64@0.17.19':
optional: true
+ '@esbuild/freebsd-arm64@0.21.5':
+ optional: true
+
'@esbuild/freebsd-arm64@0.24.0':
optional: true
'@esbuild/freebsd-x64@0.17.19':
optional: true
+ '@esbuild/freebsd-x64@0.21.5':
+ optional: true
+
'@esbuild/freebsd-x64@0.24.0':
optional: true
'@esbuild/linux-arm64@0.17.19':
optional: true
+ '@esbuild/linux-arm64@0.21.5':
+ optional: true
+
'@esbuild/linux-arm64@0.24.0':
optional: true
'@esbuild/linux-arm@0.17.19':
optional: true
+ '@esbuild/linux-arm@0.21.5':
+ optional: true
+
'@esbuild/linux-arm@0.24.0':
optional: true
'@esbuild/linux-ia32@0.17.19':
optional: true
+ '@esbuild/linux-ia32@0.21.5':
+ optional: true
+
'@esbuild/linux-ia32@0.24.0':
optional: true
'@esbuild/linux-loong64@0.17.19':
optional: true
+ '@esbuild/linux-loong64@0.21.5':
+ optional: true
+
'@esbuild/linux-loong64@0.24.0':
optional: true
'@esbuild/linux-mips64el@0.17.19':
optional: true
+ '@esbuild/linux-mips64el@0.21.5':
+ optional: true
+
'@esbuild/linux-mips64el@0.24.0':
optional: true
'@esbuild/linux-ppc64@0.17.19':
optional: true
+ '@esbuild/linux-ppc64@0.21.5':
+ optional: true
+
'@esbuild/linux-ppc64@0.24.0':
optional: true
'@esbuild/linux-riscv64@0.17.19':
optional: true
+ '@esbuild/linux-riscv64@0.21.5':
+ optional: true
+
'@esbuild/linux-riscv64@0.24.0':
optional: true
'@esbuild/linux-s390x@0.17.19':
optional: true
+ '@esbuild/linux-s390x@0.21.5':
+ optional: true
+
'@esbuild/linux-s390x@0.24.0':
optional: true
'@esbuild/linux-x64@0.17.19':
optional: true
+ '@esbuild/linux-x64@0.21.5':
+ optional: true
+
'@esbuild/linux-x64@0.24.0':
optional: true
'@esbuild/netbsd-x64@0.17.19':
optional: true
+ '@esbuild/netbsd-x64@0.21.5':
+ optional: true
+
'@esbuild/netbsd-x64@0.24.0':
optional: true
@@ -3302,30 +3494,45 @@ snapshots:
'@esbuild/openbsd-x64@0.17.19':
optional: true
+ '@esbuild/openbsd-x64@0.21.5':
+ optional: true
+
'@esbuild/openbsd-x64@0.24.0':
optional: true
'@esbuild/sunos-x64@0.17.19':
optional: true
+ '@esbuild/sunos-x64@0.21.5':
+ optional: true
+
'@esbuild/sunos-x64@0.24.0':
optional: true
'@esbuild/win32-arm64@0.17.19':
optional: true
+ '@esbuild/win32-arm64@0.21.5':
+ optional: true
+
'@esbuild/win32-arm64@0.24.0':
optional: true
'@esbuild/win32-ia32@0.17.19':
optional: true
+ '@esbuild/win32-ia32@0.21.5':
+ optional: true
+
'@esbuild/win32-ia32@0.24.0':
optional: true
'@esbuild/win32-x64@0.17.19':
optional: true
+ '@esbuild/win32-x64@0.21.5':
+ optional: true
+
'@esbuild/win32-x64@0.24.0':
optional: true
@@ -3336,17 +3543,15 @@ snapshots:
'@eslint-community/regexpp@4.12.1': {}
- '@eslint/config-array@0.19.1':
+ '@eslint/config-array@0.19.0':
dependencies:
- '@eslint/object-schema': 2.1.5
+ '@eslint/object-schema': 2.1.4
debug: 4.3.7
minimatch: 3.1.2
transitivePeerDependencies:
- supports-color
- '@eslint/core@0.9.1':
- dependencies:
- '@types/json-schema': 7.0.15
+ '@eslint/core@0.9.0': {}
'@eslint/eslintrc@3.2.0':
dependencies:
@@ -3364,9 +3569,9 @@ snapshots:
'@eslint/js@9.16.0': {}
- '@eslint/object-schema@2.1.5': {}
+ '@eslint/object-schema@2.1.4': {}
- '@eslint/plugin-kit@0.2.4':
+ '@eslint/plugin-kit@0.2.3':
dependencies:
levn: 0.4.1
@@ -3643,22 +3848,22 @@ snapshots:
'@shikijs/vscode-textmate@9.3.0': {}
- '@svecodocs/kit@0.1.1(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(bits-ui@1.0.0-next.65(svelte@5.7.0))(svelte@5.7.0)(tailwindcss@4.0.0-beta.4)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))':
+ '@svecodocs/kit@0.0.5(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(bits-ui@1.0.0-next.65(svelte@5.4.0))(svelte@5.4.0)(tailwindcss@4.0.0-beta.4)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))':
dependencies:
- '@sveltejs/kit': 2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
- bits-ui: 1.0.0-next.65(svelte@5.7.0)
+ '@sveltejs/kit': 2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
+ bits-ui: 1.0.0-next.65(svelte@5.4.0)
clsx: 2.1.1
flexsearch: 0.7.43
- mode-watcher: 0.5.0(svelte@5.7.0)
- phosphor-svelte: 3.0.0(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
+ mode-watcher: 0.5.0(svelte@5.4.0)
+ phosphor-svelte: 3.0.0(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
rehype-autolink-headings: 7.1.0
rehype-pretty-code: 0.14.0(shiki@1.24.0)
rehype-slug: 6.0.0
remark-gfm: 4.0.0
remove-markdown: 0.5.5
shiki: 1.24.0
- svelte: 5.7.0
- svelte-toolbelt: 0.4.6(svelte@5.7.0)
+ svelte: 5.4.0
+ svelte-toolbelt: 0.4.6(svelte@5.4.0)
tailwind-merge: 2.5.5
tailwind-variants: 0.3.0(tailwindcss@4.0.0-beta.4)
tailwindcss-animate: 1.0.7(tailwindcss@4.0.0-beta.4)
@@ -3668,22 +3873,22 @@ snapshots:
- tailwindcss
- vite
- '@sveltejs/adapter-auto@3.3.1(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))':
+ '@sveltejs/adapter-auto@3.3.1(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))':
dependencies:
- '@sveltejs/kit': 2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
+ '@sveltejs/kit': 2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
import-meta-resolve: 4.1.0
- '@sveltejs/adapter-cloudflare@4.8.0(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(wrangler@3.92.0(@cloudflare/workers-types@4.20241202.0))':
+ '@sveltejs/adapter-cloudflare@4.8.0(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(wrangler@3.91.0(@cloudflare/workers-types@4.20241202.0))':
dependencies:
'@cloudflare/workers-types': 4.20241202.0
- '@sveltejs/kit': 2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
+ '@sveltejs/kit': 2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
esbuild: 0.24.0
worktop: 0.8.0-next.18
- wrangler: 3.92.0(@cloudflare/workers-types@4.20241202.0)
+ wrangler: 3.91.0(@cloudflare/workers-types@4.20241202.0)
- '@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))':
+ '@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))':
dependencies:
- '@sveltejs/vite-plugin-svelte': 5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
+ '@sveltejs/vite-plugin-svelte': 4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
'@types/cookie': 0.6.0
cookie: 0.6.0
devalue: 5.1.1
@@ -3695,47 +3900,47 @@ snapshots:
sade: 1.8.1
set-cookie-parser: 2.7.1
sirv: 3.0.0
- svelte: 5.7.0
+ svelte: 5.4.0
tiny-glob: 0.2.9
- vite: 6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)
+ vite: 5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)
- '@sveltejs/package@2.3.7(svelte@5.7.0)(typescript@5.7.2)':
+ '@sveltejs/package@2.3.7(svelte@5.4.0)(typescript@5.7.2)':
dependencies:
chokidar: 4.0.1
kleur: 4.1.5
sade: 1.8.1
semver: 7.6.3
- svelte: 5.7.0
- svelte2tsx: 0.7.30(svelte@5.7.0)(typescript@5.7.2)
+ svelte: 5.4.0
+ svelte2tsx: 0.7.28(svelte@5.4.0)(typescript@5.7.2)
transitivePeerDependencies:
- typescript
- '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))':
+ '@sveltejs/vite-plugin-svelte-inspector@3.0.1(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))':
dependencies:
- '@sveltejs/vite-plugin-svelte': 5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
+ '@sveltejs/vite-plugin-svelte': 4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
debug: 4.3.7
- svelte: 5.7.0
- vite: 6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)
+ svelte: 5.4.0
+ vite: 5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)
transitivePeerDependencies:
- supports-color
- '@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))':
+ '@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))':
dependencies:
- '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)))(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
+ '@sveltejs/vite-plugin-svelte-inspector': 3.0.1(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
debug: 4.3.7
deepmerge: 4.3.1
kleur: 4.1.5
magic-string: 0.30.14
- svelte: 5.7.0
- vite: 6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)
- vitefu: 1.0.4(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))
+ svelte: 5.4.0
+ vite: 5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)
+ vitefu: 1.0.4(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
transitivePeerDependencies:
- supports-color
'@svitejs/changesets-changelog-github-compact@1.2.0':
dependencies:
'@changesets/get-github-info': 0.6.0
- dotenv: 16.4.7
+ dotenv: 16.4.6
transitivePeerDependencies:
- encoding
@@ -3796,14 +4001,14 @@ snapshots:
'@tailwindcss/oxide-win32-arm64-msvc': 4.0.0-beta.4
'@tailwindcss/oxide-win32-x64-msvc': 4.0.0-beta.4
- '@tailwindcss/vite@4.0.0-beta.4(postcss-load-config@3.1.4(postcss@8.4.49))(postcss@8.4.49)(svelte@5.7.0)(typescript@5.7.2)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1))':
+ '@tailwindcss/vite@4.0.0-beta.4(postcss-load-config@3.1.4(postcss@8.4.49))(postcss@8.4.49)(svelte@5.4.0)(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))':
dependencies:
'@tailwindcss/node': 4.0.0-beta.4
'@tailwindcss/oxide': 4.0.0-beta.4
lightningcss: 1.28.2
- svelte-preprocess: 6.0.3(postcss-load-config@3.1.4(postcss@8.4.49))(postcss@8.4.49)(svelte@5.7.0)(typescript@5.7.2)
+ svelte-preprocess: 6.0.3(postcss-load-config@3.1.4(postcss@8.4.49))(postcss@8.4.49)(svelte@5.4.0)(typescript@5.7.2)
tailwindcss: 4.0.0-beta.4
- vite: 6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)
+ vite: 5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)
transitivePeerDependencies:
- '@babel/core'
- coffeescript
@@ -4009,15 +4214,15 @@ snapshots:
dependencies:
is-windows: 1.0.2
- bits-ui@1.0.0-next.65(svelte@5.7.0):
+ bits-ui@1.0.0-next.65(svelte@5.4.0):
dependencies:
'@floating-ui/core': 1.6.8
'@floating-ui/dom': 1.6.12
'@internationalized/date': 3.6.0
esm-env: 1.2.1
- runed: 0.15.4(svelte@5.7.0)
- svelte: 5.7.0
- svelte-toolbelt: 0.4.6(svelte@5.7.0)
+ runed: 0.15.4(svelte@5.4.0)
+ svelte: 5.4.0
+ svelte-toolbelt: 0.4.6(svelte@5.4.0)
blake3-wasm@2.1.5: {}
@@ -4146,7 +4351,7 @@ snapshots:
dependencies:
path-type: 4.0.0
- dotenv@16.4.7: {}
+ dotenv@16.4.6: {}
emoji-regex-xs@1.0.0: {}
@@ -4201,6 +4406,32 @@ snapshots:
'@esbuild/win32-ia32': 0.17.19
'@esbuild/win32-x64': 0.17.19
+ esbuild@0.21.5:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.21.5
+ '@esbuild/android-arm': 0.21.5
+ '@esbuild/android-arm64': 0.21.5
+ '@esbuild/android-x64': 0.21.5
+ '@esbuild/darwin-arm64': 0.21.5
+ '@esbuild/darwin-x64': 0.21.5
+ '@esbuild/freebsd-arm64': 0.21.5
+ '@esbuild/freebsd-x64': 0.21.5
+ '@esbuild/linux-arm': 0.21.5
+ '@esbuild/linux-arm64': 0.21.5
+ '@esbuild/linux-ia32': 0.21.5
+ '@esbuild/linux-loong64': 0.21.5
+ '@esbuild/linux-mips64el': 0.21.5
+ '@esbuild/linux-ppc64': 0.21.5
+ '@esbuild/linux-riscv64': 0.21.5
+ '@esbuild/linux-s390x': 0.21.5
+ '@esbuild/linux-x64': 0.21.5
+ '@esbuild/netbsd-x64': 0.21.5
+ '@esbuild/openbsd-x64': 0.21.5
+ '@esbuild/sunos-x64': 0.21.5
+ '@esbuild/win32-arm64': 0.21.5
+ '@esbuild/win32-ia32': 0.21.5
+ '@esbuild/win32-x64': 0.21.5
+
esbuild@0.24.0:
optionalDependencies:
'@esbuild/aix-ppc64': 0.24.0
@@ -4241,7 +4472,7 @@ snapshots:
dependencies:
eslint: 9.16.0(jiti@2.4.1)
- eslint-plugin-svelte@2.46.1(eslint@9.16.0(jiti@2.4.1))(svelte@5.7.0):
+ eslint-plugin-svelte@2.46.1(eslint@9.16.0(jiti@2.4.1))(svelte@5.4.0):
dependencies:
'@eslint-community/eslint-utils': 4.4.1(eslint@9.16.0(jiti@2.4.1))
'@jridgewell/sourcemap-codec': 1.5.0
@@ -4254,9 +4485,9 @@ snapshots:
postcss-safe-parser: 6.0.0(postcss@8.4.49)
postcss-selector-parser: 6.1.2
semver: 7.6.3
- svelte-eslint-parser: 0.43.0(svelte@5.7.0)
+ svelte-eslint-parser: 0.43.0(svelte@5.4.0)
optionalDependencies:
- svelte: 5.7.0
+ svelte: 5.4.0
transitivePeerDependencies:
- ts-node
@@ -4278,11 +4509,11 @@ snapshots:
dependencies:
'@eslint-community/eslint-utils': 4.4.1(eslint@9.16.0(jiti@2.4.1))
'@eslint-community/regexpp': 4.12.1
- '@eslint/config-array': 0.19.1
- '@eslint/core': 0.9.1
+ '@eslint/config-array': 0.19.0
+ '@eslint/core': 0.9.0
'@eslint/eslintrc': 3.2.0
'@eslint/js': 9.16.0
- '@eslint/plugin-kit': 0.2.4
+ '@eslint/plugin-kit': 0.2.3
'@humanfs/node': 0.16.6
'@humanwhocodes/module-importer': 1.0.1
'@humanwhocodes/retry': 0.4.1
@@ -4967,7 +5198,7 @@ snapshots:
dependencies:
'@types/mdast': 4.0.4
- mdsx@0.0.6(svelte@5.7.0):
+ mdsx@0.0.6(svelte@5.4.0):
dependencies:
esrap: 1.2.3
hast-util-to-html: 9.0.3
@@ -4976,7 +5207,7 @@ snapshots:
rehype-stringify: 10.0.1
remark-parse: 11.0.0
remark-rehype: 11.1.1
- svelte: 5.7.0
+ svelte: 5.4.0
unified: 11.0.5
unist-util-visit: 5.0.0
vfile: 6.0.3
@@ -5260,7 +5491,7 @@ snapshots:
mime@3.0.0: {}
- miniflare@3.20241106.2:
+ miniflare@3.20241106.1:
dependencies:
'@cspotcode/source-map-support': 0.8.1
acorn: 8.14.0
@@ -5270,7 +5501,7 @@ snapshots:
glob-to-regexp: 0.4.1
stoppable: 1.1.0
undici: 5.28.4
- workerd: 1.20241106.2
+ workerd: 1.20241106.1
ws: 8.18.0
youch: 3.3.4
zod: 3.23.8
@@ -5291,9 +5522,9 @@ snapshots:
dependencies:
brace-expansion: 2.0.1
- mode-watcher@0.5.0(svelte@5.7.0):
+ mode-watcher@0.5.0(svelte@5.4.0):
dependencies:
- svelte: 5.7.0
+ svelte: 5.4.0
mri@1.2.0: {}
@@ -5380,7 +5611,7 @@ snapshots:
p-try@2.2.0: {}
- package-manager-detector@0.2.7: {}
+ package-manager-detector@0.2.6: {}
parent-module@1.0.1:
dependencies:
@@ -5420,13 +5651,13 @@ snapshots:
pathe@1.1.2: {}
- phosphor-svelte@3.0.0(svelte@5.7.0)(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)):
+ phosphor-svelte@3.0.0(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)):
dependencies:
estree-walker: 3.0.3
magic-string: 0.30.14
- svelte: 5.7.0
+ svelte: 5.4.0
optionalDependencies:
- vite: 6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)
+ vite: 5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)
picocolors@1.1.1: {}
@@ -5462,20 +5693,20 @@ snapshots:
prelude-ls@1.2.1: {}
- prettier-plugin-svelte@3.3.2(prettier@3.4.2)(svelte@5.7.0):
+ prettier-plugin-svelte@3.3.2(prettier@3.4.1)(svelte@5.4.0):
dependencies:
- prettier: 3.4.2
- svelte: 5.7.0
+ prettier: 3.4.1
+ svelte: 5.4.0
- prettier-plugin-tailwindcss@0.6.9(prettier-plugin-svelte@3.3.2(prettier@3.4.2)(svelte@5.7.0))(prettier@3.4.2):
+ prettier-plugin-tailwindcss@0.6.9(prettier-plugin-svelte@3.3.2(prettier@3.4.1)(svelte@5.4.0))(prettier@3.4.1):
dependencies:
- prettier: 3.4.2
+ prettier: 3.4.1
optionalDependencies:
- prettier-plugin-svelte: 3.3.2(prettier@3.4.2)(svelte@5.7.0)
+ prettier-plugin-svelte: 3.3.2(prettier@3.4.1)(svelte@5.4.0)
prettier@2.8.8: {}
- prettier@3.4.2: {}
+ prettier@3.4.1: {}
printable-characters@1.0.42: {}
@@ -5638,6 +5869,8 @@ snapshots:
resolve-from@5.0.0: {}
+ resolve.exports@2.0.3: {}
+
resolve@1.22.8:
dependencies:
is-core-module: 2.15.1
@@ -5688,15 +5921,15 @@ snapshots:
dependencies:
queue-microtask: 1.2.3
- runed@0.15.4(svelte@5.7.0):
+ runed@0.15.4(svelte@5.4.0):
dependencies:
esm-env: 1.2.1
- svelte: 5.7.0
+ svelte: 5.4.0
- runed@0.16.2(svelte@5.7.0):
+ runed@0.16.1(svelte@5.4.0):
dependencies:
esm-env: 1.2.1
- svelte: 5.7.0
+ svelte: 5.4.0
sade@1.8.1:
dependencies:
@@ -5826,19 +6059,19 @@ snapshots:
supports-preserve-symlinks-flag@1.0.0: {}
- svelte-check@4.1.1(svelte@5.7.0)(typescript@5.7.2):
+ svelte-check@4.1.0(svelte@5.4.0)(typescript@5.7.2):
dependencies:
'@jridgewell/trace-mapping': 0.3.25
chokidar: 4.0.1
fdir: 6.4.2
picocolors: 1.1.1
sade: 1.8.1
- svelte: 5.7.0
+ svelte: 5.4.0
typescript: 5.7.2
transitivePeerDependencies:
- picomatch
- svelte-eslint-parser@0.43.0(svelte@5.7.0):
+ svelte-eslint-parser@0.43.0(svelte@5.4.0):
dependencies:
eslint-scope: 7.2.2
eslint-visitor-keys: 3.4.3
@@ -5846,30 +6079,30 @@ snapshots:
postcss: 8.4.49
postcss-scss: 4.0.9(postcss@8.4.49)
optionalDependencies:
- svelte: 5.7.0
+ svelte: 5.4.0
- svelte-preprocess@6.0.3(postcss-load-config@3.1.4(postcss@8.4.49))(postcss@8.4.49)(svelte@5.7.0)(typescript@5.7.2):
+ svelte-preprocess@6.0.3(postcss-load-config@3.1.4(postcss@8.4.49))(postcss@8.4.49)(svelte@5.4.0)(typescript@5.7.2):
dependencies:
- svelte: 5.7.0
+ svelte: 5.4.0
optionalDependencies:
postcss: 8.4.49
postcss-load-config: 3.1.4(postcss@8.4.49)
typescript: 5.7.2
- svelte-toolbelt@0.4.6(svelte@5.7.0):
+ svelte-toolbelt@0.4.6(svelte@5.4.0):
dependencies:
clsx: 2.1.1
style-to-object: 1.0.8
- svelte: 5.7.0
+ svelte: 5.4.0
- svelte2tsx@0.7.30(svelte@5.7.0)(typescript@5.7.2):
+ svelte2tsx@0.7.28(svelte@5.4.0)(typescript@5.7.2):
dependencies:
dedent-js: 1.0.1
pascal-case: 3.1.2
- svelte: 5.7.0
+ svelte: 5.4.0
typescript: 5.7.2
- svelte@5.7.0:
+ svelte@5.4.0:
dependencies:
'@ampproject/remapping': 2.3.0
'@jridgewell/sourcemap-codec': 1.5.0
@@ -5902,7 +6135,7 @@ snapshots:
term-size@2.2.1: {}
- terser@5.37.0:
+ terser@5.36.0:
dependencies:
'@jridgewell/source-map': 0.3.6
acorn: 8.14.0
@@ -6018,7 +6251,7 @@ snapshots:
'@mdx-js/mdx': 3.1.0(acorn@8.14.0)
esbuild: 0.24.0
sharp: 0.33.5
- terser: 5.37.0
+ terser: 5.36.0
transitivePeerDependencies:
- acorn
- supports-color
@@ -6038,22 +6271,20 @@ snapshots:
'@types/unist': 3.0.3
vfile-message: 4.0.2
- vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1):
+ vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0):
dependencies:
- esbuild: 0.24.0
+ esbuild: 0.21.5
postcss: 8.4.49
rollup: 4.28.0
optionalDependencies:
'@types/node': 22.10.1
fsevents: 2.3.3
- jiti: 2.4.1
lightningcss: 1.28.2
- terser: 5.37.0
- yaml: 2.6.1
+ terser: 5.36.0
- vitefu@1.0.4(vite@6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)):
+ vitefu@1.0.4(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)):
optionalDependencies:
- vite: 6.0.3(@types/node@22.10.1)(jiti@2.4.1)(lightningcss@1.28.2)(terser@5.37.0)(yaml@2.6.1)
+ vite: 5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)
web-namespaces@2.0.1: {}
@@ -6074,23 +6305,23 @@ snapshots:
word-wrap@1.2.5: {}
- workerd@1.20241106.2:
+ workerd@1.20241106.1:
optionalDependencies:
- '@cloudflare/workerd-darwin-64': 1.20241106.2
- '@cloudflare/workerd-darwin-arm64': 1.20241106.2
- '@cloudflare/workerd-linux-64': 1.20241106.2
- '@cloudflare/workerd-linux-arm64': 1.20241106.2
- '@cloudflare/workerd-windows-64': 1.20241106.2
+ '@cloudflare/workerd-darwin-64': 1.20241106.1
+ '@cloudflare/workerd-darwin-arm64': 1.20241106.1
+ '@cloudflare/workerd-linux-64': 1.20241106.1
+ '@cloudflare/workerd-linux-arm64': 1.20241106.1
+ '@cloudflare/workerd-windows-64': 1.20241106.1
worktop@0.8.0-next.18:
dependencies:
mrmime: 2.0.0
regexparam: 3.0.0
- wrangler@3.92.0(@cloudflare/workers-types@4.20241202.0):
+ wrangler@3.91.0(@cloudflare/workers-types@4.20241202.0):
dependencies:
'@cloudflare/kv-asset-handler': 0.3.4
- '@cloudflare/workers-shared': 0.9.1
+ '@cloudflare/workers-shared': 0.9.0
'@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19)
'@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19)
blake3-wasm: 2.1.5
@@ -6098,14 +6329,15 @@ snapshots:
date-fns: 4.1.0
esbuild: 0.17.19
itty-time: 1.0.6
- miniflare: 3.20241106.2
+ miniflare: 3.20241106.1
nanoid: 3.3.8
path-to-regexp: 6.3.0
resolve: 1.22.8
+ resolve.exports: 2.0.3
selfsigned: 2.4.1
source-map: 0.6.1
unenv: unenv-nightly@2.0.0-20241121-161142-806b5c0
- workerd: 1.20241106.2
+ workerd: 1.20241106.1
xxhash-wasm: 1.1.0
optionalDependencies:
'@cloudflare/workers-types': 4.20241202.0
From 31ff139c179b7e8b253bd6ac617e3a6acb50c4aa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Olle=20M=C3=A5nsson?=
<31876997+ollema@users.noreply.github.com>
Date: Thu, 5 Dec 2024 22:15:43 +0100
Subject: [PATCH 20/25] update @svecodocs/kit only
---
docs/package.json | 2 +-
docs/src/routes/api/search.json/search.json | 33 +--------------------
pnpm-lock.yaml | 10 +++----
3 files changed, 7 insertions(+), 38 deletions(-)
diff --git a/docs/package.json b/docs/package.json
index 5bc2949..69e64b8 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -14,7 +14,7 @@
"check:watch": "pnpm build:content && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
},
"devDependencies": {
- "@svecodocs/kit": "^0.0.5",
+ "@svecodocs/kit": "^0.1.1",
"@sveltejs/adapter-cloudflare": "^4.8.0",
"@sveltejs/kit": "^2.9.0",
"@sveltejs/vite-plugin-svelte": "^4.0.2",
diff --git a/docs/src/routes/api/search.json/search.json b/docs/src/routes/api/search.json/search.json
index 48c5b4a..2a2ee8f 100644
--- a/docs/src/routes/api/search.json/search.json
+++ b/docs/src/routes/api/search.json/search.json
@@ -1,32 +1 @@
-[
- {
- "title": "Getting Started",
- "href": "/docs/getting-started",
- "description": "A quick guide to get started using barqode",
- "content": "The following guide will walk you through installing and setting up the barqode components in your Svelte project. Installation Install the package using your preferred package manager: npm install barqode or pnpm add barqode or yarn add barqode Basic Usage The simplest way to use the library is with the BarqodeStream component for live scanning: import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .scanner { width: 100%; max-width: 600px; aspect-ratio: 4/3; } For detailed information about each component's capabilities and options, refer to their respective API documentation pages."
- },
- {
- "title": "Introduction",
- "href": "/docs/index",
- "description": "What is Barqode?",
- "content": "Barqode provides a set of Svelte components for detecting and decoding QR codes and various other barcode formats right in the browser. It's a comprehensive solution that supports both camera streams and static image processing. Barqode started out as a port of $2. Components BarqodeStream** - continuously scans frames from a camera stream. BarqodeDropzone** - drag & drop image files or web images. BarqodeCapture** - traditional file upload field input with camera support. Features Real-time scanning**. Detect codes from live camera stream. Multiple formats**. Support for QR codes and various barcode standards. Visual feedback**. Customizable canvas based tracking of detected codes. Cross-browser**. Works across modern browsers with a $2 if needed. Camera selection**. Choose between front/rear cameras. Torch control**. Control device flashlight where supported. Responsive**. Components adapt to fill available space. Error handling**. Comprehensive error handling for camera/detection issues. Usage Example import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .scanner { width: 100%; max-width: 600px; aspect-ratio: 4/3; } Browser Support The components rely primarily on the $2 and $2, with fallbacks where possible. While the core scanning functionality uses the native BarcodeDetector where available, it falls back to a $2 to ensure consistent behavior across browsers. For a detailed compatibility overview, check each component's documentation."
- },
- {
- "title": "BarqodeCapture",
- "href": "/docs/components/BarqodeCapture",
- "description": "File input with camera support on mobile.",
- "content": " import Demo from '$lib/components/demos/barqode-capture.svelte'; The BarqodeCapture component is a simple file input with the capture attribute set to environment which allows users to take a picture with their camera. Demo Props formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2, one callback per image uploaded. If not barcode is detected, the array will be empty. Other props The BarqodeCapture component accepts all attributes that a standard input element accepts. By default, the following attributes are set: type=\"file\". This is required to make the input a file input. You should not change this. name=\"image\". This is the name of the file input. accept=\"image/*\". This restricts the file types that can be uploaded to images. capture=\"environment\". This tells the browser to open the camera when the input is clicked on mobile devices. You can choose between user and environment, which opens the front and back camera respectively. You can also disable this functionality by setting it to null. multiple. This allows the user to upload multiple files at once. You can disable this by settings this to false. Usage import { BarqodeCapture, type DetectedBarcode } from \"barqode\"; let result = $state(\"\"); function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCodes.map((detectedCode) => detectedCode.rawValue).join(\", \"); } Last detected: {result} .result { margin-top: 1.25rem; } Browser Support This component depends on the $2 which is widely supported in modern browsers."
- },
- {
- "title": "BarqodeDropzone",
- "href": "/docs/components/BarqodeDropzone",
- "description": "File input with camera support on mobile.",
- "content": " import Demo from '$lib/components/demos/barqode-drop-zone.svelte'; You can drag-and-drop image files from your desktop or images embedded into other web pages anywhere in the area the component occupies. The images are directly scanned and positive results are indicated by the onDetect callback. Demo Props formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2, one callback per image dropped. If not barcode is detected, the array will be empty. onDragover Type: (isDraggingOver: boolean) => void Callback function that is called when a file is dragged over the drop zone. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. Usage import { BarqodeDropzone, type DetectedBarcode } from \"barqode\"; import { DemoContainer } from \"@svecodocs/kit\"; let result = $state(\"\"); let dragover = $state(false); function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCodes.map((detectedCode) => detectedCode.rawValue).join(\", \"); } function onDragover(isDraggingOver: boolean) { dragover = isDraggingOver; } Drop an image here to detect QR-codes Last detected: {result} .dropzone { width: 100%; height: 200px; border: 2px solid #2563eb; display: flex; justify-content: center; align-items: center; } .dragover { border-color: white; } .result { margin-top: 1.25rem; } Browser Support This component depends on the $2 which is widely supported in modern browsers."
- },
- {
- "title": "BarqodeStream",
- "href": "/docs/components/BarqodeStream",
- "description": "Continuously scans frames from a camera stream.",
- "content": " import Demo from '$lib/components/demos/barqode-stream.svelte'; import { Callout } from '@svecodocs/kit'; The BarqodeStream component continuously scans frames from a camera stream and detects barcodes in real-time. Demo Props constraints Type: $2 Default: { video: { facingMode: \"environment\" } } Configure the the various camera options, for example whether to use front or rear camera. The object must be of type MediaTrackConstraints. The object is passed as-is to getUserMedia, which is the API call for requesting a camera stream: navigator.mediaDevices.getUserMedia({ audio: false, video: the_constraint_object_you_provide, }); When constraints is updated, a new camera stream is requested which triggers the onCameraOn callback again. You can catch errors with the onError callback. An error can occur when you try to use the front camera on a device that doesn't have one for example. formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Don't select more barcode formats than needed. Scanning becomes more expensive the more formats you select. Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. paused Type: boolean (bindable) Default: false Whether the camera stream is or should be paused. Bindable, which means that you can pause/unpause the stream from outside the component. Pausing the stream by setting paused to true is useful if you want to show some microinteraction after successful scans. When the you set it to false, the camera stream will be restarted and the onCameraOn callback function will be triggered again. torch Type: boolean Default: false Turn the camera flashlight on or off. This is not consistently supported by all devices and browsers. Support can even vary on the same device with the same browser. For example the rear camera often has a flashlight but the front camera does not. We can only tell if flashlight control is supported once the camera is loaded and the onCameraOn callback has been called. At the moment, enabling the torch may silently fail on unsupported devices, but in the onCameraOn callback payload you can access the MediaTrackCapabilities object, from which you can determine if the torch is supported. The camera stream must be reloaded when turning the torch on or off. That means the onCameraOn event will be emitted again. track Type: (detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) => void Callback function that can be used to visually highlight detected barcodes. A transparent canvas is overlaid on top of the camera stream. The track function is used to draw on this canvas. It receives an array of $2 and a $2 as the second argument. Note that when track is set the scanning frequency has to be increased. So if you want to go easy on your target device you might not want to enable tracking. The track function is called for every frame. It is important to keep the function as performant as possible. This can lead to performance issues on low-end devices and memory leaks if not handled correctly. onCameraOn Type: (capabilities: MediaTrackCapabilities) => void Callback function that is called when the camera stream is successfully loaded. It might take a while before the component is ready and the scanning process starts. The user has to be asked for camera access permission first and the camera stream has to be loaded. If you want to show a loading indicator, you can wait for this callback to be called. It is called as soon as the camera start streaming. The callback receives the a promise which resolves with the cameras $2 when everything is ready. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. onCameraOff Type: () => void Callback function that is called when the camera stream is stopped. This can happen when the camera constraints are modified, for example when switching between front and rear camera or when turning the torch on or off. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2. If you scan the same barcode multiple times in a row, onDetect is still only called once. When you hold a barcode in the camera, frames are actually decoded multiple times a second but you don't want to be flooded with callbacks that often. That's why the last decoded QR code is always cached and only new results are propagated. However, changing the value of paused resets this internal cache. Usage import { BarqodeStream, type DetectedBarcode } from \"barqode\"; let loading = $state(true); let result: string | null = $state(null); function onCameraOn() { loading = false; } function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCode.map((code) => detectedCode.rawValue).join(\", \"); } function track(detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) { for (const detectedCode of detectedCodes) { const [firstPoint, ...otherPoints] = detectedCode.cornerPoints; ctx.strokeStyle = \"#2563eb\"; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(firstPoint.x, firstPoint.y); for (const { x, y } of otherPoints) { ctx.lineTo(x, y); } ctx.lineTo(firstPoint.x, firstPoint.y); ctx.closePath(); ctx.stroke(); } } {#if loading} Loading... {/if} Last detected: {result} .scanner { width: 100%; aspect-ratio: 4 / 3; } .loading-indicator { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; font-weight: bold; font-size: 2rem; } .result { margin-top: 1.25rem; } Browser Support This component depends on the $2 which is widely supported in modern browsers."
- }
-]
+[{"title":"Getting Started","href":"/docs/getting-started","description":"A quick guide to get started using barqode","content":"The following guide will walk you through installing and setting up the barqode components in your Svelte project. Installation Install the package using your preferred package manager: npm install barqode Basic Usage The simplest way to use the library is with the BarqodeStream component for live scanning: import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .barqode { width: 100%; max-width: 600px; aspect-ratio: 4/3; } For detailed information about each component's capabilities and options, refer to their respective API documentation pages."},{"title":"Introduction","href":"/docs/index","description":"What is Barqode?","content":"Barqode provides a set of Svelte components for detecting and decoding QR codes and various other barcode formats right in the browser. It's a comprehensive solution that supports both camera streams and static image processing. Barqode started out as a port of $2. Components BarqodeStream** - continuously scans frames from a camera stream. BarqodeDropzone** - drag & drop, click to upload or capture images from camera. Features Real-time scanning**. Detect codes from live camera stream. Multiple formats**. Support for QR codes and various barcode standards. Visual feedback**. Customizable canvas based tracking of detected codes. Cross-browser**. Works across modern browsers with a $2 if needed. Camera selection**. Choose between front/rear cameras. Torch control**. Control device flashlight where supported. Responsive**. Components adapt to fill available space. Error handling**. Comprehensive error handling for camera/detection issues. Usage Example import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .barqode { width: 100%; max-width: 600px; aspect-ratio: 4/3; } Browser Support The components rely primarily on the $2 and $2, with fallbacks where possible. While the core scanning functionality uses the native BarcodeDetector where available, it falls back to a $2 to ensure consistent behavior across browsers. For a detailed compatibility overview, check each component's documentation."},{"title":"BarqodeDropzone","href":"/docs/components/barqode-dropzone","description":"Click to upload images, drag & drop or use your camera to scan.","content":" import Demo from '$lib/components/demos/barqode-dropzone.svelte'; This component functions as a file input with the capture attribute set to environment which allows users to take a picture with their camera. You can also drag-and-drop image files from your desktop or images embedded into other web pages anywhere in the area the component occupies. The images are directly scanned and positive results are indicated by the onDetect callback. Demo Usage import { BarqodeDropzone, type DetectedBarcode } from \"barqode\"; let result = $state(\"\"); let dragover = $state(false); function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCodes.map((detectedCode) => detectedCode.rawValue).join(\", \"); } function onDragover(isDraggingOver: boolean) { dragover = isDraggingOver; } Click to upload or drop an image here Last detected: {result} .barqode { width: 100%; aspect-ratio: 4 / 3; border: 2px solid #2563eb; } .dragover { border-color: white; } .instructions { height: 100%; width: 100%; display: flex; justify-content: center; align-items: center; } Props formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2, one callback per image. If not barcode is detected, the array will be empty. onDragover Type: (isDraggingOver: boolean) => void Callback function that is called when a file is dragged over the drop zone. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. Other props The BarqodeDropzone component accepts all attributes that a standard input element accepts. By default, the following attributes are set: type=\"file\". This is required to make the input a file input. You should not change this. name=\"image\". This is the name of the file input. accept=\"image/*\". This restricts the file types that can be uploaded to images. capture=\"environment\". This tells the browser to open the camera when the input is clicked on mobile devices. You can choose between user and environment, which opens the front and back camera respectively. You can also disable this functionality by setting it to null. multiple. This allows the user to upload multiple files at once. You can disable this by settings this to false. Browser Support This component depends on the $2 which is widely supported in modern browsers."},{"title":"BarqodeStream","href":"/docs/components/barqode-stream","description":"Continuously scans frames from a camera stream.","content":" import Demo from '$lib/components/demos/barqode-stream.svelte'; import { Callout } from '@svecodocs/kit'; The BarqodeStream component continuously scans frames from a camera stream and detects barcodes in real-time. Demo Usage import { BarqodeStream, type DetectedBarcode } from \"barqode\"; let loading = $state(true); let result: string | null = $state(null); function onCameraOn() { loading = false; } function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCode.map((code) => detectedCode.rawValue).join(\", \"); } function track(detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) { for (const detectedCode of detectedCodes) { const [firstPoint, ...otherPoints] = detectedCode.cornerPoints; ctx.strokeStyle = \"#2563eb\"; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(firstPoint.x, firstPoint.y); for (const { x, y } of otherPoints) { ctx.lineTo(x, y); } ctx.lineTo(firstPoint.x, firstPoint.y); ctx.closePath(); ctx.stroke(); } } {#if loading} Loading... {/if} Last detected: {result} .barqode { width: 100%; aspect-ratio: 4 / 3; } .loading-indicator { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; font-weight: bold; font-size: 2rem; } Props constraints Type: $2 Default: { video: { facingMode: \"environment\" } } Configure the the various camera options, for example whether to use front or rear camera. The object must be of type MediaTrackConstraints. The object is passed as-is to getUserMedia, which is the API call for requesting a camera stream: navigator.mediaDevices.getUserMedia({ audio: false, video: the_constraint_object_you_provide, }); When constraints is updated, a new camera stream is requested which triggers the onCameraOn callback again. You can catch errors with the onError callback. An error can occur when you try to use the front camera on a device that doesn't have one for example. formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Don't select more barcode formats than needed. Scanning becomes more expensive the more formats you select. Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. paused Type: boolean (bindable) Default: false Whether the camera stream is or should be paused. Bindable, which means that you can pause/unpause the stream from outside the component. Pausing the stream by setting paused to true is useful if you want to show some microinteraction after successful scans. When the you set it to false, the camera stream will be restarted and the onCameraOn callback function will be triggered again. torch Type: boolean Default: false Turn the camera flashlight on or off. This is not consistently supported by all devices and browsers. Support can even vary on the same device with the same browser. For example the rear camera often has a flashlight but the front camera does not. We can only tell if flashlight control is supported once the camera is loaded and the onCameraOn callback has been called. At the moment, enabling the torch may silently fail on unsupported devices, but in the onCameraOn callback payload you can access the MediaTrackCapabilities object, from which you can determine if the torch is supported. The camera stream must be reloaded when turning the torch on or off. That means the onCameraOn event will be emitted again. track Type: (detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) => void Callback function that can be used to visually highlight detected barcodes. A transparent canvas is overlaid on top of the camera stream. The track function is used to draw on this canvas. It receives an array of $2 and a $2 as the second argument. Note that when track is set the scanning frequency has to be increased. So if you want to go easy on your target device you might not want to enable tracking. The track function is called for every frame. It is important to keep the function as performant as possible. This can lead to performance issues on low-end devices and memory leaks if not handled correctly. onCameraOn Type: (capabilities: MediaTrackCapabilities) => void Callback function that is called when the camera stream is successfully loaded. It might take a while before the component is ready and the scanning process starts. The user has to be asked for camera access permission first and the camera stream has to be loaded. If you want to show a loading indicator, you can wait for this callback to be called. It is called as soon as the camera start streaming. The callback receives the a promise which resolves with the cameras $2 when everything is ready. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. onCameraOff Type: () => void Callback function that is called when the camera stream is stopped. This can happen when the camera constraints are modified, for example when switching between front and rear camera or when turning the torch on or off. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2. If you scan the same barcode multiple times in a row, onDetect is still only called once. When you hold a barcode in the camera, frames are actually decoded multiple times a second but you don't want to be flooded with callbacks that often. That's why the last decoded QR code is always cached and only new results are propagated. However, changing the value of paused resets this internal cache. Browser Support This component depends on the $2 which is widely supported in modern browsers."}]
\ No newline at end of file
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 4bfe73b..d21c88b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -69,8 +69,8 @@ importers:
docs:
devDependencies:
'@svecodocs/kit':
- specifier: ^0.0.5
- version: 0.0.5(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(bits-ui@1.0.0-next.65(svelte@5.4.0))(svelte@5.4.0)(tailwindcss@4.0.0-beta.4)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
+ specifier: ^0.1.1
+ version: 0.1.1(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(bits-ui@1.0.0-next.65(svelte@5.4.0))(svelte@5.4.0)(tailwindcss@4.0.0-beta.4)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
'@sveltejs/adapter-cloudflare':
specifier: ^4.8.0
version: 4.8.0(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(wrangler@3.91.0(@cloudflare/workers-types@4.20241202.0))
@@ -1022,8 +1022,8 @@ packages:
'@shikijs/vscode-textmate@9.3.0':
resolution: {integrity: sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA==}
- '@svecodocs/kit@0.0.5':
- resolution: {integrity: sha512-DrwREJDQBDZTm6UOHg27CqpObFMUBcgYH9P94PSVsdJtaYOAv5GF33cjxwxvwNgczKgcpeZs4xWu3/HdFI5JKA==}
+ '@svecodocs/kit@0.1.1':
+ resolution: {integrity: sha512-VOaN+twbkStWo67QAk7DO88+CxVeTNzC49E4g7Ru0aJnBxzyXChr2dXUCJNyyONQ2LrvMnnjEQxkh69RuScEzA==}
peerDependencies:
'@sveltejs/kit': ^2.0.0
bits-ui: 1.0.0-next.65
@@ -3848,7 +3848,7 @@ snapshots:
'@shikijs/vscode-textmate@9.3.0': {}
- '@svecodocs/kit@0.0.5(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(bits-ui@1.0.0-next.65(svelte@5.4.0))(svelte@5.4.0)(tailwindcss@4.0.0-beta.4)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))':
+ '@svecodocs/kit@0.1.1(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(bits-ui@1.0.0-next.65(svelte@5.4.0))(svelte@5.4.0)(tailwindcss@4.0.0-beta.4)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))':
dependencies:
'@sveltejs/kit': 2.9.0(@sveltejs/vite-plugin-svelte@4.0.2(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0)))(svelte@5.4.0)(vite@5.4.11(@types/node@22.10.1)(lightningcss@1.28.2)(terser@5.36.0))
bits-ui: 1.0.0-next.65(svelte@5.4.0)
From 1e8ef81b7af4d98db3cab7c40b6e512d89a2889f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Olle=20M=C3=A5nsson?=
<31876997+ollema@users.noreply.github.com>
Date: Thu, 5 Dec 2024 22:17:28 +0100
Subject: [PATCH 21/25] format search.json
---
docs/src/routes/api/search.json/search.json | 27 ++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/docs/src/routes/api/search.json/search.json b/docs/src/routes/api/search.json/search.json
index 2a2ee8f..c089dde 100644
--- a/docs/src/routes/api/search.json/search.json
+++ b/docs/src/routes/api/search.json/search.json
@@ -1 +1,26 @@
-[{"title":"Getting Started","href":"/docs/getting-started","description":"A quick guide to get started using barqode","content":"The following guide will walk you through installing and setting up the barqode components in your Svelte project. Installation Install the package using your preferred package manager: npm install barqode Basic Usage The simplest way to use the library is with the BarqodeStream component for live scanning: import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .barqode { width: 100%; max-width: 600px; aspect-ratio: 4/3; } For detailed information about each component's capabilities and options, refer to their respective API documentation pages."},{"title":"Introduction","href":"/docs/index","description":"What is Barqode?","content":"Barqode provides a set of Svelte components for detecting and decoding QR codes and various other barcode formats right in the browser. It's a comprehensive solution that supports both camera streams and static image processing. Barqode started out as a port of $2. Components BarqodeStream** - continuously scans frames from a camera stream. BarqodeDropzone** - drag & drop, click to upload or capture images from camera. Features Real-time scanning**. Detect codes from live camera stream. Multiple formats**. Support for QR codes and various barcode standards. Visual feedback**. Customizable canvas based tracking of detected codes. Cross-browser**. Works across modern browsers with a $2 if needed. Camera selection**. Choose between front/rear cameras. Torch control**. Control device flashlight where supported. Responsive**. Components adapt to fill available space. Error handling**. Comprehensive error handling for camera/detection issues. Usage Example import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .barqode { width: 100%; max-width: 600px; aspect-ratio: 4/3; } Browser Support The components rely primarily on the $2 and $2, with fallbacks where possible. While the core scanning functionality uses the native BarcodeDetector where available, it falls back to a $2 to ensure consistent behavior across browsers. For a detailed compatibility overview, check each component's documentation."},{"title":"BarqodeDropzone","href":"/docs/components/barqode-dropzone","description":"Click to upload images, drag & drop or use your camera to scan.","content":" import Demo from '$lib/components/demos/barqode-dropzone.svelte'; This component functions as a file input with the capture attribute set to environment which allows users to take a picture with their camera. You can also drag-and-drop image files from your desktop or images embedded into other web pages anywhere in the area the component occupies. The images are directly scanned and positive results are indicated by the onDetect callback. Demo Usage import { BarqodeDropzone, type DetectedBarcode } from \"barqode\"; let result = $state(\"\"); let dragover = $state(false); function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCodes.map((detectedCode) => detectedCode.rawValue).join(\", \"); } function onDragover(isDraggingOver: boolean) { dragover = isDraggingOver; } Click to upload or drop an image here Last detected: {result} .barqode { width: 100%; aspect-ratio: 4 / 3; border: 2px solid #2563eb; } .dragover { border-color: white; } .instructions { height: 100%; width: 100%; display: flex; justify-content: center; align-items: center; } Props formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2, one callback per image. If not barcode is detected, the array will be empty. onDragover Type: (isDraggingOver: boolean) => void Callback function that is called when a file is dragged over the drop zone. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. Other props The BarqodeDropzone component accepts all attributes that a standard input element accepts. By default, the following attributes are set: type=\"file\". This is required to make the input a file input. You should not change this. name=\"image\". This is the name of the file input. accept=\"image/*\". This restricts the file types that can be uploaded to images. capture=\"environment\". This tells the browser to open the camera when the input is clicked on mobile devices. You can choose between user and environment, which opens the front and back camera respectively. You can also disable this functionality by setting it to null. multiple. This allows the user to upload multiple files at once. You can disable this by settings this to false. Browser Support This component depends on the $2 which is widely supported in modern browsers."},{"title":"BarqodeStream","href":"/docs/components/barqode-stream","description":"Continuously scans frames from a camera stream.","content":" import Demo from '$lib/components/demos/barqode-stream.svelte'; import { Callout } from '@svecodocs/kit'; The BarqodeStream component continuously scans frames from a camera stream and detects barcodes in real-time. Demo Usage import { BarqodeStream, type DetectedBarcode } from \"barqode\"; let loading = $state(true); let result: string | null = $state(null); function onCameraOn() { loading = false; } function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCode.map((code) => detectedCode.rawValue).join(\", \"); } function track(detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) { for (const detectedCode of detectedCodes) { const [firstPoint, ...otherPoints] = detectedCode.cornerPoints; ctx.strokeStyle = \"#2563eb\"; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(firstPoint.x, firstPoint.y); for (const { x, y } of otherPoints) { ctx.lineTo(x, y); } ctx.lineTo(firstPoint.x, firstPoint.y); ctx.closePath(); ctx.stroke(); } } {#if loading} Loading... {/if} Last detected: {result} .barqode { width: 100%; aspect-ratio: 4 / 3; } .loading-indicator { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; font-weight: bold; font-size: 2rem; } Props constraints Type: $2 Default: { video: { facingMode: \"environment\" } } Configure the the various camera options, for example whether to use front or rear camera. The object must be of type MediaTrackConstraints. The object is passed as-is to getUserMedia, which is the API call for requesting a camera stream: navigator.mediaDevices.getUserMedia({ audio: false, video: the_constraint_object_you_provide, }); When constraints is updated, a new camera stream is requested which triggers the onCameraOn callback again. You can catch errors with the onError callback. An error can occur when you try to use the front camera on a device that doesn't have one for example. formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Don't select more barcode formats than needed. Scanning becomes more expensive the more formats you select. Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. paused Type: boolean (bindable) Default: false Whether the camera stream is or should be paused. Bindable, which means that you can pause/unpause the stream from outside the component. Pausing the stream by setting paused to true is useful if you want to show some microinteraction after successful scans. When the you set it to false, the camera stream will be restarted and the onCameraOn callback function will be triggered again. torch Type: boolean Default: false Turn the camera flashlight on or off. This is not consistently supported by all devices and browsers. Support can even vary on the same device with the same browser. For example the rear camera often has a flashlight but the front camera does not. We can only tell if flashlight control is supported once the camera is loaded and the onCameraOn callback has been called. At the moment, enabling the torch may silently fail on unsupported devices, but in the onCameraOn callback payload you can access the MediaTrackCapabilities object, from which you can determine if the torch is supported. The camera stream must be reloaded when turning the torch on or off. That means the onCameraOn event will be emitted again. track Type: (detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) => void Callback function that can be used to visually highlight detected barcodes. A transparent canvas is overlaid on top of the camera stream. The track function is used to draw on this canvas. It receives an array of $2 and a $2 as the second argument. Note that when track is set the scanning frequency has to be increased. So if you want to go easy on your target device you might not want to enable tracking. The track function is called for every frame. It is important to keep the function as performant as possible. This can lead to performance issues on low-end devices and memory leaks if not handled correctly. onCameraOn Type: (capabilities: MediaTrackCapabilities) => void Callback function that is called when the camera stream is successfully loaded. It might take a while before the component is ready and the scanning process starts. The user has to be asked for camera access permission first and the camera stream has to be loaded. If you want to show a loading indicator, you can wait for this callback to be called. It is called as soon as the camera start streaming. The callback receives the a promise which resolves with the cameras $2 when everything is ready. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. onCameraOff Type: () => void Callback function that is called when the camera stream is stopped. This can happen when the camera constraints are modified, for example when switching between front and rear camera or when turning the torch on or off. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2. If you scan the same barcode multiple times in a row, onDetect is still only called once. When you hold a barcode in the camera, frames are actually decoded multiple times a second but you don't want to be flooded with callbacks that often. That's why the last decoded QR code is always cached and only new results are propagated. However, changing the value of paused resets this internal cache. Browser Support This component depends on the $2 which is widely supported in modern browsers."}]
\ No newline at end of file
+[
+ {
+ "title": "Getting Started",
+ "href": "/docs/getting-started",
+ "description": "A quick guide to get started using barqode",
+ "content": "The following guide will walk you through installing and setting up the barqode components in your Svelte project. Installation Install the package using your preferred package manager: npm install barqode Basic Usage The simplest way to use the library is with the BarqodeStream component for live scanning: import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .barqode { width: 100%; max-width: 600px; aspect-ratio: 4/3; } For detailed information about each component's capabilities and options, refer to their respective API documentation pages."
+ },
+ {
+ "title": "Introduction",
+ "href": "/docs/index",
+ "description": "What is Barqode?",
+ "content": "Barqode provides a set of Svelte components for detecting and decoding QR codes and various other barcode formats right in the browser. It's a comprehensive solution that supports both camera streams and static image processing. Barqode started out as a port of $2. Components BarqodeStream** - continuously scans frames from a camera stream. BarqodeDropzone** - drag & drop, click to upload or capture images from camera. Features Real-time scanning**. Detect codes from live camera stream. Multiple formats**. Support for QR codes and various barcode standards. Visual feedback**. Customizable canvas based tracking of detected codes. Cross-browser**. Works across modern browsers with a $2 if needed. Camera selection**. Choose between front/rear cameras. Torch control**. Control device flashlight where supported. Responsive**. Components adapt to fill available space. Error handling**. Comprehensive error handling for camera/detection issues. Usage Example import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .barqode { width: 100%; max-width: 600px; aspect-ratio: 4/3; } Browser Support The components rely primarily on the $2 and $2, with fallbacks where possible. While the core scanning functionality uses the native BarcodeDetector where available, it falls back to a $2 to ensure consistent behavior across browsers. For a detailed compatibility overview, check each component's documentation."
+ },
+ {
+ "title": "BarqodeDropzone",
+ "href": "/docs/components/barqode-dropzone",
+ "description": "Click to upload images, drag & drop or use your camera to scan.",
+ "content": " import Demo from '$lib/components/demos/barqode-dropzone.svelte'; This component functions as a file input with the capture attribute set to environment which allows users to take a picture with their camera. You can also drag-and-drop image files from your desktop or images embedded into other web pages anywhere in the area the component occupies. The images are directly scanned and positive results are indicated by the onDetect callback. Demo Usage import { BarqodeDropzone, type DetectedBarcode } from \"barqode\"; let result = $state(\"\"); let dragover = $state(false); function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCodes.map((detectedCode) => detectedCode.rawValue).join(\", \"); } function onDragover(isDraggingOver: boolean) { dragover = isDraggingOver; } Click to upload or drop an image here Last detected: {result} .barqode { width: 100%; aspect-ratio: 4 / 3; border: 2px solid #2563eb; } .dragover { border-color: white; } .instructions { height: 100%; width: 100%; display: flex; justify-content: center; align-items: center; } Props formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2, one callback per image. If not barcode is detected, the array will be empty. onDragover Type: (isDraggingOver: boolean) => void Callback function that is called when a file is dragged over the drop zone. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. Other props The BarqodeDropzone component accepts all attributes that a standard input element accepts. By default, the following attributes are set: type=\"file\". This is required to make the input a file input. You should not change this. name=\"image\". This is the name of the file input. accept=\"image/*\". This restricts the file types that can be uploaded to images. capture=\"environment\". This tells the browser to open the camera when the input is clicked on mobile devices. You can choose between user and environment, which opens the front and back camera respectively. You can also disable this functionality by setting it to null. multiple. This allows the user to upload multiple files at once. You can disable this by settings this to false. Browser Support This component depends on the $2 which is widely supported in modern browsers."
+ },
+ {
+ "title": "BarqodeStream",
+ "href": "/docs/components/barqode-stream",
+ "description": "Continuously scans frames from a camera stream.",
+ "content": " import Demo from '$lib/components/demos/barqode-stream.svelte'; import { Callout } from '@svecodocs/kit'; The BarqodeStream component continuously scans frames from a camera stream and detects barcodes in real-time. Demo Usage import { BarqodeStream, type DetectedBarcode } from \"barqode\"; let loading = $state(true); let result: string | null = $state(null); function onCameraOn() { loading = false; } function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCode.map((code) => detectedCode.rawValue).join(\", \"); } function track(detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) { for (const detectedCode of detectedCodes) { const [firstPoint, ...otherPoints] = detectedCode.cornerPoints; ctx.strokeStyle = \"#2563eb\"; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(firstPoint.x, firstPoint.y); for (const { x, y } of otherPoints) { ctx.lineTo(x, y); } ctx.lineTo(firstPoint.x, firstPoint.y); ctx.closePath(); ctx.stroke(); } } {#if loading} Loading... {/if} Last detected: {result} .barqode { width: 100%; aspect-ratio: 4 / 3; } .loading-indicator { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; font-weight: bold; font-size: 2rem; } Props constraints Type: $2 Default: { video: { facingMode: \"environment\" } } Configure the the various camera options, for example whether to use front or rear camera. The object must be of type MediaTrackConstraints. The object is passed as-is to getUserMedia, which is the API call for requesting a camera stream: navigator.mediaDevices.getUserMedia({ audio: false, video: the_constraint_object_you_provide, }); When constraints is updated, a new camera stream is requested which triggers the onCameraOn callback again. You can catch errors with the onError callback. An error can occur when you try to use the front camera on a device that doesn't have one for example. formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Don't select more barcode formats than needed. Scanning becomes more expensive the more formats you select. Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. paused Type: boolean (bindable) Default: false Whether the camera stream is or should be paused. Bindable, which means that you can pause/unpause the stream from outside the component. Pausing the stream by setting paused to true is useful if you want to show some microinteraction after successful scans. When the you set it to false, the camera stream will be restarted and the onCameraOn callback function will be triggered again. torch Type: boolean Default: false Turn the camera flashlight on or off. This is not consistently supported by all devices and browsers. Support can even vary on the same device with the same browser. For example the rear camera often has a flashlight but the front camera does not. We can only tell if flashlight control is supported once the camera is loaded and the onCameraOn callback has been called. At the moment, enabling the torch may silently fail on unsupported devices, but in the onCameraOn callback payload you can access the MediaTrackCapabilities object, from which you can determine if the torch is supported. The camera stream must be reloaded when turning the torch on or off. That means the onCameraOn event will be emitted again. track Type: (detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) => void Callback function that can be used to visually highlight detected barcodes. A transparent canvas is overlaid on top of the camera stream. The track function is used to draw on this canvas. It receives an array of $2 and a $2 as the second argument. Note that when track is set the scanning frequency has to be increased. So if you want to go easy on your target device you might not want to enable tracking. The track function is called for every frame. It is important to keep the function as performant as possible. This can lead to performance issues on low-end devices and memory leaks if not handled correctly. onCameraOn Type: (capabilities: MediaTrackCapabilities) => void Callback function that is called when the camera stream is successfully loaded. It might take a while before the component is ready and the scanning process starts. The user has to be asked for camera access permission first and the camera stream has to be loaded. If you want to show a loading indicator, you can wait for this callback to be called. It is called as soon as the camera start streaming. The callback receives the a promise which resolves with the cameras $2 when everything is ready. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. onCameraOff Type: () => void Callback function that is called when the camera stream is stopped. This can happen when the camera constraints are modified, for example when switching between front and rear camera or when turning the torch on or off. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2. If you scan the same barcode multiple times in a row, onDetect is still only called once. When you hold a barcode in the camera, frames are actually decoded multiple times a second but you don't want to be flooded with callbacks that often. That's why the last decoded QR code is always cached and only new results are propagated. However, changing the value of paused resets this internal cache. Browser Support This component depends on the $2 which is widely supported in modern browsers."
+ }
+]
From 3749a711241217b8d7e558f468dea919006e9865 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Olle=20M=C3=A5nsson?=
<31876997+ollema@users.noreply.github.com>
Date: Sat, 7 Dec 2024 20:31:06 +0100
Subject: [PATCH 22/25] add some sort of full kitchen sink demo
---
docs/src/content/demos/full-demo.md | 271 ++++++++++++++++++
.../src/lib/components/demos/full-demo.svelte | 261 +++++++++++++++++
docs/src/routes/api/search.json/search.json | 6 +
3 files changed, 538 insertions(+)
create mode 100644 docs/src/content/demos/full-demo.md
create mode 100644 docs/src/lib/components/demos/full-demo.svelte
diff --git a/docs/src/content/demos/full-demo.md b/docs/src/content/demos/full-demo.md
new file mode 100644
index 0000000..8a13b99
--- /dev/null
+++ b/docs/src/content/demos/full-demo.md
@@ -0,0 +1,271 @@
+---
+title: Full demo
+description: Kitchen sink demo of the BarqodeStream component.
+section: Demos
+---
+
+
+
+The `BarqodeStream` component continuously scans frames from a camera stream and detects barcodes in real-time.
+
+## Demo
+
+Modern mobile phones often have a variety of different cameras installed (e.g. front, rear,
+wide-angle, infrared, desk-view). The one picked by default is sometimes not the best
+choice. For more fine-grained control, you can select a camera by device constraints or by
+the device ID.
+
+Detected codes are visually highlighted in real-time. In this demo you can use the track function dropdown to change the flavor.
+
+By default only QR-codes are detected but a variety of other barcode formats are also supported.
+You can select one or multiple but the more you select the more expensive scanning becomes.
+
+
+
+## Usage
+
+```svelte
+
+
+Camera constraints:
+
+ {#each constraintOptions as option}
+
+ {option.label}
+
+ {/each}
+
+
+Track function:
+
+ {#each trackFunctionOptions as option}
+
+ {option.text}
+
+ {/each}
+
+
+Barcode formats:
+
+ {#each Object.keys(barcodeFormats) as option}
+ {@const barcodeOption = option as BarcodeFormat}
+
+
+ {option}
+
+ {/each}
+
+
+{#if error}
+ {error}
+{/if}
+
+
+
+
+
+
+ Last result: {result}
+
+
+
+```
diff --git a/docs/src/lib/components/demos/full-demo.svelte b/docs/src/lib/components/demos/full-demo.svelte
new file mode 100644
index 0000000..3b382fc
--- /dev/null
+++ b/docs/src/lib/components/demos/full-demo.svelte
@@ -0,0 +1,261 @@
+
+
+
+
+ Camera constraints:
+
+ {#each constraintOptions as option}
+
+ {option.label}
+
+ {/each}
+
+
+
+
+ Track function:
+
+ {#each trackFunctionOptions as option}
+
+ {option.text}
+
+ {/each}
+
+
+
+
+
+
Barcode formats:
+
+ {#each Object.keys(barcodeFormats) as option}
+ {@const barcodeOption = option as BarcodeFormat}
+
+
+ {option}
+
+ {/each}
+
+
+
+ {#if error}
+ {error}
+ {/if}
+
+
+
+
+
+
+ Last result: {result}
+
+
+
+
diff --git a/docs/src/routes/api/search.json/search.json b/docs/src/routes/api/search.json/search.json
index c089dde..571a2db 100644
--- a/docs/src/routes/api/search.json/search.json
+++ b/docs/src/routes/api/search.json/search.json
@@ -11,6 +11,12 @@
"description": "What is Barqode?",
"content": "Barqode provides a set of Svelte components for detecting and decoding QR codes and various other barcode formats right in the browser. It's a comprehensive solution that supports both camera streams and static image processing. Barqode started out as a port of $2. Components BarqodeStream** - continuously scans frames from a camera stream. BarqodeDropzone** - drag & drop, click to upload or capture images from camera. Features Real-time scanning**. Detect codes from live camera stream. Multiple formats**. Support for QR codes and various barcode standards. Visual feedback**. Customizable canvas based tracking of detected codes. Cross-browser**. Works across modern browsers with a $2 if needed. Camera selection**. Choose between front/rear cameras. Torch control**. Control device flashlight where supported. Responsive**. Components adapt to fill available space. Error handling**. Comprehensive error handling for camera/detection issues. Usage Example import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .barqode { width: 100%; max-width: 600px; aspect-ratio: 4/3; } Browser Support The components rely primarily on the $2 and $2, with fallbacks where possible. While the core scanning functionality uses the native BarcodeDetector where available, it falls back to a $2 to ensure consistent behavior across browsers. For a detailed compatibility overview, check each component's documentation."
},
+ {
+ "title": "Full demo",
+ "href": "/docs/demos/full-demo",
+ "description": "Kitchen sink demo of the BarqodeStream component.",
+ "content": " import Demo from '$lib/components/demos/full-demo.svelte'; The BarqodeStream component continuously scans frames from a camera stream and detects barcodes in real-time. Demo Modern mobile phones often have a variety of different cameras installed (e.g. front, rear, wide-angle, infrared, desk-view). The one picked by default is sometimes not the best choice. For more fine-grained control, you can select a camera by device constraints or by the device ID. Detected codes are visually highlighted in real-time. In this demo you can use the track function dropdown to change the flavor. By default only QR-codes are detected but a variety of other barcode formats are also supported. You can select one or multiple but the more you select the more expensive scanning becomes. Usage import { BarqodeStream, type BarcodeFormat, type DetectedBarcode } from \"barqode\"; let result = $state(\"\"); let error = $state(\"\"); let selectedConstraints = $state({ facingMode: \"environment\" }); let barcodeFormats: { [key in BarcodeFormat]: boolean; } = $state({ aztec: false, code_128: false, code_39: false, code_93: false, codabar: false, databar: false, databar_expanded: false, databar_limited: false, data_matrix: false, dx_film_edge: false, ean_13: false, ean_8: false, itf: false, maxi_code: false, micro_qr_code: false, pdf417: false, qr_code: true, rm_qr_code: false, upc_a: false, upc_e: false, linear_codes: false, matrix_codes: false, unknown: false, }); // computed value for selected formats let selectedBarcodeFormats: BarcodeFormat[] = $derived( Object.keys(barcodeFormats).filter( (format: string) => barcodeFormats[format] ) as BarcodeFormat[] ); // track function options const trackFunctionOptions = [ { text: \"nothing (default)\", value: undefined }, { text: \"outline\", value: paintOutline }, { text: \"centered text\", value: paintCenterText }, { text: \"bounding box\", value: paintBoundingBox }, ]; let trackFunctionSelected = $state(trackFunctionOptions[1]); // camera constraint options const defaultConstraintOptions: { label: string; constraints: MediaTrackConstraints }[] = [ { label: \"rear camera\", constraints: { facingMode: \"environment\" } }, { label: \"front camera\", constraints: { facingMode: \"user\" } }, ]; let constraintOptions = $state(defaultConstraintOptions); async function onCameraOn() { try { const devices = await navigator.mediaDevices.enumerateDevices(); const videoDevices = devices.filter(({ kind }) => kind === \"videoinput\"); constraintOptions = [ ...defaultConstraintOptions, ...videoDevices.map(({ deviceId, label }) => ({ label: ${label}, constraints: { deviceId }, })), ]; error = \"\"; } catch (e) { console.error(e); } } function onError(err: { name: string; message: string }) { error = [${err.name}]: ; if (err.name === \"NotAllowedError\") { error += \"you need to grant camera access permission\"; } else if (err.name === \"NotFoundError\") { error += \"no camera on this device\"; } else if (err.name === \"NotSupportedError\") { error += \"secure context required (HTTPS, localhost)\"; } else if (err.name === \"NotReadableError\") { error += \"is the camera already in use?\"; } else if (err.name === \"OverconstrainedError\") { error += \"installed cameras are not suitable\"; } else if (err.name === \"StreamApiNotSupportedError\") { error += \"Stream API is not supported in this browser\"; } else { error += err.message; } } function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes); result = JSON.stringify(detectedCodes.map((code) => code.rawValue)); } // track functions function paintOutline( detectedCodes: { cornerPoints: { x: number; y: number }[]; boundingBox: DOMRectReadOnly; rawValue: string; format: Exclude; }[], ctx: CanvasRenderingContext2D ) { for (const detectedCode of detectedCodes) { const [firstPoint, ...otherPoints] = detectedCode.cornerPoints; ctx.strokeStyle = \"red\"; ctx.beginPath(); ctx.moveTo(firstPoint.x, firstPoint.y); for (const { x, y } of otherPoints) { ctx.lineTo(x, y); } ctx.lineTo(firstPoint.x, firstPoint.y); ctx.closePath(); ctx.stroke(); } } function paintBoundingBox( detectedCodes: { cornerPoints: { x: number; y: number }[]; boundingBox: DOMRectReadOnly; rawValue: string; format: Exclude; }[], ctx: CanvasRenderingContext2D ) { for (const detectedCode of detectedCodes) { const { boundingBox: { x, y, width, height }, } = detectedCode; ctx.lineWidth = 2; ctx.strokeStyle = \"#007bff\"; ctx.strokeRect(x, y, width, height); } } function paintCenterText( detectedCodes: { cornerPoints: { x: number; y: number }[]; boundingBox: DOMRectReadOnly; rawValue: string; format: Exclude; }[], ctx: CanvasRenderingContext2D ) { for (const detectedCode of detectedCodes) { const { boundingBox, rawValue } = detectedCode; const centerX = boundingBox.x + boundingBox.width / 2; const centerY = boundingBox.y + boundingBox.height / 2; const fontSize = Math.max(12, (50 * boundingBox.width) / ctx.canvas.width); ctx.font = bold ${fontSize}px sans-serif; ctx.textAlign = \"center\"; ctx.lineWidth = 3; ctx.strokeStyle = \"#35495e\"; ctx.strokeText(detectedCode.rawValue, centerX, centerY); ctx.fillStyle = \"#5cb984\"; ctx.fillText(rawValue, centerX, centerY); } } Camera constraints: {#each constraintOptions as option} {option.label} {/each} Track function: {#each trackFunctionOptions as option} {option.text} {/each} Barcode formats: {#each Object.keys(barcodeFormats) as option} {@const barcodeOption = option as BarcodeFormat} {option} {/each} {#if error} {error} {/if} Last result: {result} .error { font-weight: bold; color: red; } .scanner { width: 100%; aspect-ratio: 4/3; } `"
+ },
{
"title": "BarqodeDropzone",
"href": "/docs/components/barqode-dropzone",
From d698c2675f1c029b4f527ca6539c2b7caa11eac4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Olle=20M=C3=A5nsson?=
<31876997+ollema@users.noreply.github.com>
Date: Sat, 7 Dec 2024 20:34:06 +0100
Subject: [PATCH 23/25] rearrange text order
---
docs/src/content/demos/full-demo.md | 6 ++----
docs/src/routes/api/search.json/search.json | 12 ++++++------
2 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/docs/src/content/demos/full-demo.md b/docs/src/content/demos/full-demo.md
index 8a13b99..74fc581 100644
--- a/docs/src/content/demos/full-demo.md
+++ b/docs/src/content/demos/full-demo.md
@@ -8,10 +8,6 @@ section: Demos
import Demo from '$lib/components/demos/full-demo.svelte';
-The `BarqodeStream` component continuously scans frames from a camera stream and detects barcodes in real-time.
-
-## Demo
-
Modern mobile phones often have a variety of different cameras installed (e.g. front, rear,
wide-angle, infrared, desk-view). The one picked by default is sometimes not the best
choice. For more fine-grained control, you can select a camera by device constraints or by
@@ -22,6 +18,8 @@ Detected codes are visually highlighted in real-time. In this demo you can use t
By default only QR-codes are detected but a variety of other barcode formats are also supported.
You can select one or multiple but the more you select the more expensive scanning becomes.
+## Demo
+
## Usage
diff --git a/docs/src/routes/api/search.json/search.json b/docs/src/routes/api/search.json/search.json
index 571a2db..2da1b4d 100644
--- a/docs/src/routes/api/search.json/search.json
+++ b/docs/src/routes/api/search.json/search.json
@@ -11,12 +11,6 @@
"description": "What is Barqode?",
"content": "Barqode provides a set of Svelte components for detecting and decoding QR codes and various other barcode formats right in the browser. It's a comprehensive solution that supports both camera streams and static image processing. Barqode started out as a port of $2. Components BarqodeStream** - continuously scans frames from a camera stream. BarqodeDropzone** - drag & drop, click to upload or capture images from camera. Features Real-time scanning**. Detect codes from live camera stream. Multiple formats**. Support for QR codes and various barcode standards. Visual feedback**. Customizable canvas based tracking of detected codes. Cross-browser**. Works across modern browsers with a $2 if needed. Camera selection**. Choose between front/rear cameras. Torch control**. Control device flashlight where supported. Responsive**. Components adapt to fill available space. Error handling**. Comprehensive error handling for camera/detection issues. Usage Example import { BarqodeStream, type DetectedBarcode } from \"barqode\"; function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes.map((detectedCode) => detectedCode.rawValue)); } .barqode { width: 100%; max-width: 600px; aspect-ratio: 4/3; } Browser Support The components rely primarily on the $2 and $2, with fallbacks where possible. While the core scanning functionality uses the native BarcodeDetector where available, it falls back to a $2 to ensure consistent behavior across browsers. For a detailed compatibility overview, check each component's documentation."
},
- {
- "title": "Full demo",
- "href": "/docs/demos/full-demo",
- "description": "Kitchen sink demo of the BarqodeStream component.",
- "content": " import Demo from '$lib/components/demos/full-demo.svelte'; The BarqodeStream component continuously scans frames from a camera stream and detects barcodes in real-time. Demo Modern mobile phones often have a variety of different cameras installed (e.g. front, rear, wide-angle, infrared, desk-view). The one picked by default is sometimes not the best choice. For more fine-grained control, you can select a camera by device constraints or by the device ID. Detected codes are visually highlighted in real-time. In this demo you can use the track function dropdown to change the flavor. By default only QR-codes are detected but a variety of other barcode formats are also supported. You can select one or multiple but the more you select the more expensive scanning becomes. Usage import { BarqodeStream, type BarcodeFormat, type DetectedBarcode } from \"barqode\"; let result = $state(\"\"); let error = $state(\"\"); let selectedConstraints = $state({ facingMode: \"environment\" }); let barcodeFormats: { [key in BarcodeFormat]: boolean; } = $state({ aztec: false, code_128: false, code_39: false, code_93: false, codabar: false, databar: false, databar_expanded: false, databar_limited: false, data_matrix: false, dx_film_edge: false, ean_13: false, ean_8: false, itf: false, maxi_code: false, micro_qr_code: false, pdf417: false, qr_code: true, rm_qr_code: false, upc_a: false, upc_e: false, linear_codes: false, matrix_codes: false, unknown: false, }); // computed value for selected formats let selectedBarcodeFormats: BarcodeFormat[] = $derived( Object.keys(barcodeFormats).filter( (format: string) => barcodeFormats[format] ) as BarcodeFormat[] ); // track function options const trackFunctionOptions = [ { text: \"nothing (default)\", value: undefined }, { text: \"outline\", value: paintOutline }, { text: \"centered text\", value: paintCenterText }, { text: \"bounding box\", value: paintBoundingBox }, ]; let trackFunctionSelected = $state(trackFunctionOptions[1]); // camera constraint options const defaultConstraintOptions: { label: string; constraints: MediaTrackConstraints }[] = [ { label: \"rear camera\", constraints: { facingMode: \"environment\" } }, { label: \"front camera\", constraints: { facingMode: \"user\" } }, ]; let constraintOptions = $state(defaultConstraintOptions); async function onCameraOn() { try { const devices = await navigator.mediaDevices.enumerateDevices(); const videoDevices = devices.filter(({ kind }) => kind === \"videoinput\"); constraintOptions = [ ...defaultConstraintOptions, ...videoDevices.map(({ deviceId, label }) => ({ label: ${label}, constraints: { deviceId }, })), ]; error = \"\"; } catch (e) { console.error(e); } } function onError(err: { name: string; message: string }) { error = [${err.name}]: ; if (err.name === \"NotAllowedError\") { error += \"you need to grant camera access permission\"; } else if (err.name === \"NotFoundError\") { error += \"no camera on this device\"; } else if (err.name === \"NotSupportedError\") { error += \"secure context required (HTTPS, localhost)\"; } else if (err.name === \"NotReadableError\") { error += \"is the camera already in use?\"; } else if (err.name === \"OverconstrainedError\") { error += \"installed cameras are not suitable\"; } else if (err.name === \"StreamApiNotSupportedError\") { error += \"Stream API is not supported in this browser\"; } else { error += err.message; } } function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes); result = JSON.stringify(detectedCodes.map((code) => code.rawValue)); } // track functions function paintOutline( detectedCodes: { cornerPoints: { x: number; y: number }[]; boundingBox: DOMRectReadOnly; rawValue: string; format: Exclude; }[], ctx: CanvasRenderingContext2D ) { for (const detectedCode of detectedCodes) { const [firstPoint, ...otherPoints] = detectedCode.cornerPoints; ctx.strokeStyle = \"red\"; ctx.beginPath(); ctx.moveTo(firstPoint.x, firstPoint.y); for (const { x, y } of otherPoints) { ctx.lineTo(x, y); } ctx.lineTo(firstPoint.x, firstPoint.y); ctx.closePath(); ctx.stroke(); } } function paintBoundingBox( detectedCodes: { cornerPoints: { x: number; y: number }[]; boundingBox: DOMRectReadOnly; rawValue: string; format: Exclude; }[], ctx: CanvasRenderingContext2D ) { for (const detectedCode of detectedCodes) { const { boundingBox: { x, y, width, height }, } = detectedCode; ctx.lineWidth = 2; ctx.strokeStyle = \"#007bff\"; ctx.strokeRect(x, y, width, height); } } function paintCenterText( detectedCodes: { cornerPoints: { x: number; y: number }[]; boundingBox: DOMRectReadOnly; rawValue: string; format: Exclude; }[], ctx: CanvasRenderingContext2D ) { for (const detectedCode of detectedCodes) { const { boundingBox, rawValue } = detectedCode; const centerX = boundingBox.x + boundingBox.width / 2; const centerY = boundingBox.y + boundingBox.height / 2; const fontSize = Math.max(12, (50 * boundingBox.width) / ctx.canvas.width); ctx.font = bold ${fontSize}px sans-serif; ctx.textAlign = \"center\"; ctx.lineWidth = 3; ctx.strokeStyle = \"#35495e\"; ctx.strokeText(detectedCode.rawValue, centerX, centerY); ctx.fillStyle = \"#5cb984\"; ctx.fillText(rawValue, centerX, centerY); } } Camera constraints: {#each constraintOptions as option} {option.label} {/each} Track function: {#each trackFunctionOptions as option} {option.text} {/each} Barcode formats: {#each Object.keys(barcodeFormats) as option} {@const barcodeOption = option as BarcodeFormat} {option} {/each} {#if error} {error} {/if} Last result: {result} .error { font-weight: bold; color: red; } .scanner { width: 100%; aspect-ratio: 4/3; } `"
- },
{
"title": "BarqodeDropzone",
"href": "/docs/components/barqode-dropzone",
@@ -28,5 +22,11 @@
"href": "/docs/components/barqode-stream",
"description": "Continuously scans frames from a camera stream.",
"content": " import Demo from '$lib/components/demos/barqode-stream.svelte'; import { Callout } from '@svecodocs/kit'; The BarqodeStream component continuously scans frames from a camera stream and detects barcodes in real-time. Demo Usage import { BarqodeStream, type DetectedBarcode } from \"barqode\"; let loading = $state(true); let result: string | null = $state(null); function onCameraOn() { loading = false; } function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCode.map((code) => detectedCode.rawValue).join(\", \"); } function track(detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) { for (const detectedCode of detectedCodes) { const [firstPoint, ...otherPoints] = detectedCode.cornerPoints; ctx.strokeStyle = \"#2563eb\"; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(firstPoint.x, firstPoint.y); for (const { x, y } of otherPoints) { ctx.lineTo(x, y); } ctx.lineTo(firstPoint.x, firstPoint.y); ctx.closePath(); ctx.stroke(); } } {#if loading} Loading... {/if} Last detected: {result} .barqode { width: 100%; aspect-ratio: 4 / 3; } .loading-indicator { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; font-weight: bold; font-size: 2rem; } Props constraints Type: $2 Default: { video: { facingMode: \"environment\" } } Configure the the various camera options, for example whether to use front or rear camera. The object must be of type MediaTrackConstraints. The object is passed as-is to getUserMedia, which is the API call for requesting a camera stream: navigator.mediaDevices.getUserMedia({ audio: false, video: the_constraint_object_you_provide, }); When constraints is updated, a new camera stream is requested which triggers the onCameraOn callback again. You can catch errors with the onError callback. An error can occur when you try to use the front camera on a device that doesn't have one for example. formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Don't select more barcode formats than needed. Scanning becomes more expensive the more formats you select. Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. paused Type: boolean (bindable) Default: false Whether the camera stream is or should be paused. Bindable, which means that you can pause/unpause the stream from outside the component. Pausing the stream by setting paused to true is useful if you want to show some microinteraction after successful scans. When the you set it to false, the camera stream will be restarted and the onCameraOn callback function will be triggered again. torch Type: boolean Default: false Turn the camera flashlight on or off. This is not consistently supported by all devices and browsers. Support can even vary on the same device with the same browser. For example the rear camera often has a flashlight but the front camera does not. We can only tell if flashlight control is supported once the camera is loaded and the onCameraOn callback has been called. At the moment, enabling the torch may silently fail on unsupported devices, but in the onCameraOn callback payload you can access the MediaTrackCapabilities object, from which you can determine if the torch is supported. The camera stream must be reloaded when turning the torch on or off. That means the onCameraOn event will be emitted again. track Type: (detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) => void Callback function that can be used to visually highlight detected barcodes. A transparent canvas is overlaid on top of the camera stream. The track function is used to draw on this canvas. It receives an array of $2 and a $2 as the second argument. Note that when track is set the scanning frequency has to be increased. So if you want to go easy on your target device you might not want to enable tracking. The track function is called for every frame. It is important to keep the function as performant as possible. This can lead to performance issues on low-end devices and memory leaks if not handled correctly. onCameraOn Type: (capabilities: MediaTrackCapabilities) => void Callback function that is called when the camera stream is successfully loaded. It might take a while before the component is ready and the scanning process starts. The user has to be asked for camera access permission first and the camera stream has to be loaded. If you want to show a loading indicator, you can wait for this callback to be called. It is called as soon as the camera start streaming. The callback receives the a promise which resolves with the cameras $2 when everything is ready. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. onCameraOff Type: () => void Callback function that is called when the camera stream is stopped. This can happen when the camera constraints are modified, for example when switching between front and rear camera or when turning the torch on or off. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2. If you scan the same barcode multiple times in a row, onDetect is still only called once. When you hold a barcode in the camera, frames are actually decoded multiple times a second but you don't want to be flooded with callbacks that often. That's why the last decoded QR code is always cached and only new results are propagated. However, changing the value of paused resets this internal cache. Browser Support This component depends on the $2 which is widely supported in modern browsers."
+ },
+ {
+ "title": "Full demo",
+ "href": "/docs/demos/full-demo",
+ "description": "Kitchen sink demo of the BarqodeStream component.",
+ "content": " import Demo from '$lib/components/demos/full-demo.svelte'; Modern mobile phones often have a variety of different cameras installed (e.g. front, rear, wide-angle, infrared, desk-view). The one picked by default is sometimes not the best choice. For more fine-grained control, you can select a camera by device constraints or by the device ID. Detected codes are visually highlighted in real-time. In this demo you can use the track function dropdown to change the flavor. By default only QR-codes are detected but a variety of other barcode formats are also supported. You can select one or multiple but the more you select the more expensive scanning becomes. Demo Usage import { BarqodeStream, type BarcodeFormat, type DetectedBarcode } from \"barqode\"; let result = $state(\"\"); let error = $state(\"\"); let selectedConstraints = $state({ facingMode: \"environment\" }); let barcodeFormats: { [key in BarcodeFormat]: boolean; } = $state({ aztec: false, code_128: false, code_39: false, code_93: false, codabar: false, databar: false, databar_expanded: false, databar_limited: false, data_matrix: false, dx_film_edge: false, ean_13: false, ean_8: false, itf: false, maxi_code: false, micro_qr_code: false, pdf417: false, qr_code: true, rm_qr_code: false, upc_a: false, upc_e: false, linear_codes: false, matrix_codes: false, unknown: false, }); // computed value for selected formats let selectedBarcodeFormats: BarcodeFormat[] = $derived( Object.keys(barcodeFormats).filter( (format: string) => barcodeFormats[format] ) as BarcodeFormat[] ); // track function options const trackFunctionOptions = [ { text: \"nothing (default)\", value: undefined }, { text: \"outline\", value: paintOutline }, { text: \"centered text\", value: paintCenterText }, { text: \"bounding box\", value: paintBoundingBox }, ]; let trackFunctionSelected = $state(trackFunctionOptions[1]); // camera constraint options const defaultConstraintOptions: { label: string; constraints: MediaTrackConstraints }[] = [ { label: \"rear camera\", constraints: { facingMode: \"environment\" } }, { label: \"front camera\", constraints: { facingMode: \"user\" } }, ]; let constraintOptions = $state(defaultConstraintOptions); async function onCameraOn() { try { const devices = await navigator.mediaDevices.enumerateDevices(); const videoDevices = devices.filter(({ kind }) => kind === \"videoinput\"); constraintOptions = [ ...defaultConstraintOptions, ...videoDevices.map(({ deviceId, label }) => ({ label: ${label}, constraints: { deviceId }, })), ]; error = \"\"; } catch (e) { console.error(e); } } function onError(err: { name: string; message: string }) { error = [${err.name}]: ; if (err.name === \"NotAllowedError\") { error += \"you need to grant camera access permission\"; } else if (err.name === \"NotFoundError\") { error += \"no camera on this device\"; } else if (err.name === \"NotSupportedError\") { error += \"secure context required (HTTPS, localhost)\"; } else if (err.name === \"NotReadableError\") { error += \"is the camera already in use?\"; } else if (err.name === \"OverconstrainedError\") { error += \"installed cameras are not suitable\"; } else if (err.name === \"StreamApiNotSupportedError\") { error += \"Stream API is not supported in this browser\"; } else { error += err.message; } } function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes); result = JSON.stringify(detectedCodes.map((code) => code.rawValue)); } // track functions function paintOutline( detectedCodes: { cornerPoints: { x: number; y: number }[]; boundingBox: DOMRectReadOnly; rawValue: string; format: Exclude; }[], ctx: CanvasRenderingContext2D ) { for (const detectedCode of detectedCodes) { const [firstPoint, ...otherPoints] = detectedCode.cornerPoints; ctx.strokeStyle = \"red\"; ctx.beginPath(); ctx.moveTo(firstPoint.x, firstPoint.y); for (const { x, y } of otherPoints) { ctx.lineTo(x, y); } ctx.lineTo(firstPoint.x, firstPoint.y); ctx.closePath(); ctx.stroke(); } } function paintBoundingBox( detectedCodes: { cornerPoints: { x: number; y: number }[]; boundingBox: DOMRectReadOnly; rawValue: string; format: Exclude; }[], ctx: CanvasRenderingContext2D ) { for (const detectedCode of detectedCodes) { const { boundingBox: { x, y, width, height }, } = detectedCode; ctx.lineWidth = 2; ctx.strokeStyle = \"#007bff\"; ctx.strokeRect(x, y, width, height); } } function paintCenterText( detectedCodes: { cornerPoints: { x: number; y: number }[]; boundingBox: DOMRectReadOnly; rawValue: string; format: Exclude; }[], ctx: CanvasRenderingContext2D ) { for (const detectedCode of detectedCodes) { const { boundingBox, rawValue } = detectedCode; const centerX = boundingBox.x + boundingBox.width / 2; const centerY = boundingBox.y + boundingBox.height / 2; const fontSize = Math.max(12, (50 * boundingBox.width) / ctx.canvas.width); ctx.font = bold ${fontSize}px sans-serif; ctx.textAlign = \"center\"; ctx.lineWidth = 3; ctx.strokeStyle = \"#35495e\"; ctx.strokeText(detectedCode.rawValue, centerX, centerY); ctx.fillStyle = \"#5cb984\"; ctx.fillText(rawValue, centerX, centerY); } } Camera constraints: {#each constraintOptions as option} {option.label} {/each} Track function: {#each trackFunctionOptions as option} {option.text} {/each} Barcode formats: {#each Object.keys(barcodeFormats) as option} {@const barcodeOption = option as BarcodeFormat} {option} {/each} {#if error} {error} {/if} Last result: {result} .error { font-weight: bold; color: red; } .scanner { width: 100%; aspect-ratio: 4/3; } `"
}
]
From 4ab63cd41bbee8c1c15b86d1b2ff458a157aa310 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Olle=20M=C3=A5nsson?=
<31876997+ollema@users.noreply.github.com>
Date: Sat, 7 Dec 2024 20:49:15 +0100
Subject: [PATCH 24/25] remove error styling
---
docs/src/content/demos/full-demo.md | 5 -----
1 file changed, 5 deletions(-)
diff --git a/docs/src/content/demos/full-demo.md b/docs/src/content/demos/full-demo.md
index 74fc581..d4b40bc 100644
--- a/docs/src/content/demos/full-demo.md
+++ b/docs/src/content/demos/full-demo.md
@@ -256,11 +256,6 @@ You can select one or multiple but the more you select the more expensive scanni
```
diff --git a/docs/src/content/components/barqode-stream.md b/docs/src/content/components/barqode-stream.md
index e2a3319..1d11c44 100644
--- a/docs/src/content/components/barqode-stream.md
+++ b/docs/src/content/components/barqode-stream.md
@@ -52,7 +52,7 @@ The `BarqodeStream` component continuously scans frames from a camera stream and
}
-
+
{#if loading}
Loading...
@@ -61,23 +61,6 @@ The `BarqodeStream` component continuously scans frames from a camera stream and
Last detected: {result}
-
-
```
## Props
diff --git a/docs/src/content/demos/full-demo.md b/docs/src/content/demos/full-demo.md
index d4b40bc..838c3c1 100644
--- a/docs/src/content/demos/full-demo.md
+++ b/docs/src/content/demos/full-demo.md
@@ -226,21 +226,19 @@ You can select one or multiple but the more you select the more expensive scanni
Barcode formats:
-
- {#each Object.keys(barcodeFormats) as option}
- {@const barcodeOption = option as BarcodeFormat}
-
-
- {option}
-
- {/each}
-
+{#each Object.keys(barcodeFormats) as option}
+ {@const barcodeOption = option as BarcodeFormat}
+
+
+ {option}
+
+{/each}
{#if error}
-
{error}
+ {error}
{/if}
-
+
-
- Last result: {result}
-
-
-
+Last result: {result}
```
diff --git a/docs/src/lib/components/demos/barqode-dropzone.svelte b/docs/src/lib/components/demos/barqode-dropzone.svelte
index 3ac448e..0089ee5 100644
--- a/docs/src/lib/components/demos/barqode-dropzone.svelte
+++ b/docs/src/lib/components/demos/barqode-dropzone.svelte
@@ -17,7 +17,7 @@
Detecting QR-codes
-
+
Click to upload or drop an image here
@@ -35,12 +35,6 @@
margin-bottom: 1.25rem;
}
- .barqode {
- width: 100%;
- aspect-ratio: 4 / 3;
- border: 2px solid #2563eb;
- }
-
.dragover {
border-color: white;
}
diff --git a/docs/src/lib/components/demos/barqode-stream.svelte b/docs/src/lib/components/demos/barqode-stream.svelte
index 8073869..309667f 100644
--- a/docs/src/lib/components/demos/barqode-stream.svelte
+++ b/docs/src/lib/components/demos/barqode-stream.svelte
@@ -36,7 +36,7 @@
Detecting QR-codes
-
+
{#if loading}
Loading...
@@ -54,11 +54,6 @@
margin-bottom: 1.25rem;
}
- .barqode {
- width: 100%;
- aspect-ratio: 4 / 3;
- }
-
.loading-indicator {
width: 100%;
height: 100%;
diff --git a/docs/src/lib/components/demos/full-demo.svelte b/docs/src/lib/components/demos/full-demo.svelte
index 3b382fc..dbb4ec9 100644
--- a/docs/src/lib/components/demos/full-demo.svelte
+++ b/docs/src/lib/components/demos/full-demo.svelte
@@ -232,7 +232,7 @@
{error}
{/if}
-
+
- Last result: {result}
+ Last detected: {result}
@@ -253,9 +253,4 @@
font-weight: bold;
color: red;
}
-
- .scanner {
- width: 100%;
- aspect-ratio: 4/3;
- }
diff --git a/docs/src/routes/api/search.json/search.json b/docs/src/routes/api/search.json/search.json
index 2da1b4d..319052c 100644
--- a/docs/src/routes/api/search.json/search.json
+++ b/docs/src/routes/api/search.json/search.json
@@ -15,18 +15,18 @@
"title": "BarqodeDropzone",
"href": "/docs/components/barqode-dropzone",
"description": "Click to upload images, drag & drop or use your camera to scan.",
- "content": " import Demo from '$lib/components/demos/barqode-dropzone.svelte'; This component functions as a file input with the capture attribute set to environment which allows users to take a picture with their camera. You can also drag-and-drop image files from your desktop or images embedded into other web pages anywhere in the area the component occupies. The images are directly scanned and positive results are indicated by the onDetect callback. Demo Usage import { BarqodeDropzone, type DetectedBarcode } from \"barqode\"; let result = $state(\"\"); let dragover = $state(false); function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCodes.map((detectedCode) => detectedCode.rawValue).join(\", \"); } function onDragover(isDraggingOver: boolean) { dragover = isDraggingOver; } Click to upload or drop an image here Last detected: {result} .barqode { width: 100%; aspect-ratio: 4 / 3; border: 2px solid #2563eb; } .dragover { border-color: white; } .instructions { height: 100%; width: 100%; display: flex; justify-content: center; align-items: center; } Props formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2, one callback per image. If not barcode is detected, the array will be empty. onDragover Type: (isDraggingOver: boolean) => void Callback function that is called when a file is dragged over the drop zone. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. Other props The BarqodeDropzone component accepts all attributes that a standard input element accepts. By default, the following attributes are set: type=\"file\". This is required to make the input a file input. You should not change this. name=\"image\". This is the name of the file input. accept=\"image/*\". This restricts the file types that can be uploaded to images. capture=\"environment\". This tells the browser to open the camera when the input is clicked on mobile devices. You can choose between user and environment, which opens the front and back camera respectively. You can also disable this functionality by setting it to null. multiple. This allows the user to upload multiple files at once. You can disable this by settings this to false. Browser Support This component depends on the $2 which is widely supported in modern browsers."
+ "content": " import Demo from '$lib/components/demos/barqode-dropzone.svelte'; This component functions as a file input with the capture attribute set to environment which allows users to take a picture with their camera. You can also drag-and-drop image files from your desktop or images embedded into other web pages anywhere in the area the component occupies. The images are directly scanned and positive results are indicated by the onDetect callback. Demo Usage import { BarqodeDropzone, type DetectedBarcode } from \"barqode\"; let result = $state(\"\"); let dragover = $state(false); function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCodes.map((detectedCode) => detectedCode.rawValue).join(\", \"); } function onDragover(isDraggingOver: boolean) { dragover = isDraggingOver; } Click to upload or drop an image here Last detected: {result} .dragover { border-color: white; } Props formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2, one callback per image. If not barcode is detected, the array will be empty. onDragover Type: (isDraggingOver: boolean) => void Callback function that is called when a file is dragged over the drop zone. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. Other props The BarqodeDropzone component accepts all attributes that a standard input element accepts. By default, the following attributes are set: type=\"file\". This is required to make the input a file input. You should not change this. name=\"image\". This is the name of the file input. accept=\"image/*\". This restricts the file types that can be uploaded to images. capture=\"environment\". This tells the browser to open the camera when the input is clicked on mobile devices. You can choose between user and environment, which opens the front and back camera respectively. You can also disable this functionality by setting it to null. multiple. This allows the user to upload multiple files at once. You can disable this by settings this to false. Browser Support This component depends on the $2 which is widely supported in modern browsers."
},
{
"title": "BarqodeStream",
"href": "/docs/components/barqode-stream",
"description": "Continuously scans frames from a camera stream.",
- "content": " import Demo from '$lib/components/demos/barqode-stream.svelte'; import { Callout } from '@svecodocs/kit'; The BarqodeStream component continuously scans frames from a camera stream and detects barcodes in real-time. Demo Usage import { BarqodeStream, type DetectedBarcode } from \"barqode\"; let loading = $state(true); let result: string | null = $state(null); function onCameraOn() { loading = false; } function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCode.map((code) => detectedCode.rawValue).join(\", \"); } function track(detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) { for (const detectedCode of detectedCodes) { const [firstPoint, ...otherPoints] = detectedCode.cornerPoints; ctx.strokeStyle = \"#2563eb\"; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(firstPoint.x, firstPoint.y); for (const { x, y } of otherPoints) { ctx.lineTo(x, y); } ctx.lineTo(firstPoint.x, firstPoint.y); ctx.closePath(); ctx.stroke(); } } {#if loading} Loading... {/if} Last detected: {result} .barqode { width: 100%; aspect-ratio: 4 / 3; } .loading-indicator { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; font-weight: bold; font-size: 2rem; } Props constraints Type: $2 Default: { video: { facingMode: \"environment\" } } Configure the the various camera options, for example whether to use front or rear camera. The object must be of type MediaTrackConstraints. The object is passed as-is to getUserMedia, which is the API call for requesting a camera stream: navigator.mediaDevices.getUserMedia({ audio: false, video: the_constraint_object_you_provide, }); When constraints is updated, a new camera stream is requested which triggers the onCameraOn callback again. You can catch errors with the onError callback. An error can occur when you try to use the front camera on a device that doesn't have one for example. formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Don't select more barcode formats than needed. Scanning becomes more expensive the more formats you select. Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. paused Type: boolean (bindable) Default: false Whether the camera stream is or should be paused. Bindable, which means that you can pause/unpause the stream from outside the component. Pausing the stream by setting paused to true is useful if you want to show some microinteraction after successful scans. When the you set it to false, the camera stream will be restarted and the onCameraOn callback function will be triggered again. torch Type: boolean Default: false Turn the camera flashlight on or off. This is not consistently supported by all devices and browsers. Support can even vary on the same device with the same browser. For example the rear camera often has a flashlight but the front camera does not. We can only tell if flashlight control is supported once the camera is loaded and the onCameraOn callback has been called. At the moment, enabling the torch may silently fail on unsupported devices, but in the onCameraOn callback payload you can access the MediaTrackCapabilities object, from which you can determine if the torch is supported. The camera stream must be reloaded when turning the torch on or off. That means the onCameraOn event will be emitted again. track Type: (detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) => void Callback function that can be used to visually highlight detected barcodes. A transparent canvas is overlaid on top of the camera stream. The track function is used to draw on this canvas. It receives an array of $2 and a $2 as the second argument. Note that when track is set the scanning frequency has to be increased. So if you want to go easy on your target device you might not want to enable tracking. The track function is called for every frame. It is important to keep the function as performant as possible. This can lead to performance issues on low-end devices and memory leaks if not handled correctly. onCameraOn Type: (capabilities: MediaTrackCapabilities) => void Callback function that is called when the camera stream is successfully loaded. It might take a while before the component is ready and the scanning process starts. The user has to be asked for camera access permission first and the camera stream has to be loaded. If you want to show a loading indicator, you can wait for this callback to be called. It is called as soon as the camera start streaming. The callback receives the a promise which resolves with the cameras $2 when everything is ready. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. onCameraOff Type: () => void Callback function that is called when the camera stream is stopped. This can happen when the camera constraints are modified, for example when switching between front and rear camera or when turning the torch on or off. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2. If you scan the same barcode multiple times in a row, onDetect is still only called once. When you hold a barcode in the camera, frames are actually decoded multiple times a second but you don't want to be flooded with callbacks that often. That's why the last decoded QR code is always cached and only new results are propagated. However, changing the value of paused resets this internal cache. Browser Support This component depends on the $2 which is widely supported in modern browsers."
+ "content": " import Demo from '$lib/components/demos/barqode-stream.svelte'; import { Callout } from '@svecodocs/kit'; The BarqodeStream component continuously scans frames from a camera stream and detects barcodes in real-time. Demo Usage import { BarqodeStream, type DetectedBarcode } from \"barqode\"; let loading = $state(true); let result: string | null = $state(null); function onCameraOn() { loading = false; } function onDetect(detectedCodes: DetectedBarcode[]) { result = detectedCode.map((code) => detectedCode.rawValue).join(\", \"); } function track(detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) { for (const detectedCode of detectedCodes) { const [firstPoint, ...otherPoints] = detectedCode.cornerPoints; ctx.strokeStyle = \"#2563eb\"; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(firstPoint.x, firstPoint.y); for (const { x, y } of otherPoints) { ctx.lineTo(x, y); } ctx.lineTo(firstPoint.x, firstPoint.y); ctx.closePath(); ctx.stroke(); } } {#if loading} Loading... {/if} Last detected: {result} Props constraints Type: $2 Default: { video: { facingMode: \"environment\" } } Configure the the various camera options, for example whether to use front or rear camera. The object must be of type MediaTrackConstraints. The object is passed as-is to getUserMedia, which is the API call for requesting a camera stream: navigator.mediaDevices.getUserMedia({ audio: false, video: the_constraint_object_you_provide, }); When constraints is updated, a new camera stream is requested which triggers the onCameraOn callback again. You can catch errors with the onError callback. An error can occur when you try to use the front camera on a device that doesn't have one for example. formats Type: [BarcodeFormat[]](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) Default: [\"qr_code\"] Configure the barcode formats to detect. By default, only QR codes are detected. If you want to detect multiple formats, pass an array of formats: Don't select more barcode formats than needed. Scanning becomes more expensive the more formats you select. Under the hood, the standard $2 is used. Support varies across devices, operating systems and browsers. All components will prefer to use the native implementation if available and otherwise falls back to a polyfill implementation. Note that even if the native implementation is available, the component still might use the polyfill. For example, if the native implementation only supports the format 'qr_code' but the you select the formats ['qr_code', 'aztec']. paused Type: boolean (bindable) Default: false Whether the camera stream is or should be paused. Bindable, which means that you can pause/unpause the stream from outside the component. Pausing the stream by setting paused to true is useful if you want to show some microinteraction after successful scans. When the you set it to false, the camera stream will be restarted and the onCameraOn callback function will be triggered again. torch Type: boolean Default: false Turn the camera flashlight on or off. This is not consistently supported by all devices and browsers. Support can even vary on the same device with the same browser. For example the rear camera often has a flashlight but the front camera does not. We can only tell if flashlight control is supported once the camera is loaded and the onCameraOn callback has been called. At the moment, enabling the torch may silently fail on unsupported devices, but in the onCameraOn callback payload you can access the MediaTrackCapabilities object, from which you can determine if the torch is supported. The camera stream must be reloaded when turning the torch on or off. That means the onCameraOn event will be emitted again. track Type: (detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) => void Callback function that can be used to visually highlight detected barcodes. A transparent canvas is overlaid on top of the camera stream. The track function is used to draw on this canvas. It receives an array of $2 and a $2 as the second argument. Note that when track is set the scanning frequency has to be increased. So if you want to go easy on your target device you might not want to enable tracking. The track function is called for every frame. It is important to keep the function as performant as possible. This can lead to performance issues on low-end devices and memory leaks if not handled correctly. onCameraOn Type: (capabilities: MediaTrackCapabilities) => void Callback function that is called when the camera stream is successfully loaded. It might take a while before the component is ready and the scanning process starts. The user has to be asked for camera access permission first and the camera stream has to be loaded. If you want to show a loading indicator, you can wait for this callback to be called. It is called as soon as the camera start streaming. The callback receives the a promise which resolves with the cameras $2 when everything is ready. onError Type: (error: Error) => void Callback function that is called when an error occurs. TODO: insert link to errors. onCameraOff Type: () => void Callback function that is called when the camera stream is stopped. This can happen when the camera constraints are modified, for example when switching between front and rear camera or when turning the torch on or off. onDetect Type: (detectedCodes: DetectedBarcode[]) => void Callback function that is called when a barcode is detected. It receives an array of $2. If you scan the same barcode multiple times in a row, onDetect is still only called once. When you hold a barcode in the camera, frames are actually decoded multiple times a second but you don't want to be flooded with callbacks that often. That's why the last decoded QR code is always cached and only new results are propagated. However, changing the value of paused resets this internal cache. Browser Support This component depends on the $2 which is widely supported in modern browsers."
},
{
"title": "Full demo",
"href": "/docs/demos/full-demo",
"description": "Kitchen sink demo of the BarqodeStream component.",
- "content": " import Demo from '$lib/components/demos/full-demo.svelte'; Modern mobile phones often have a variety of different cameras installed (e.g. front, rear, wide-angle, infrared, desk-view). The one picked by default is sometimes not the best choice. For more fine-grained control, you can select a camera by device constraints or by the device ID. Detected codes are visually highlighted in real-time. In this demo you can use the track function dropdown to change the flavor. By default only QR-codes are detected but a variety of other barcode formats are also supported. You can select one or multiple but the more you select the more expensive scanning becomes. Demo Usage import { BarqodeStream, type BarcodeFormat, type DetectedBarcode } from \"barqode\"; let result = $state(\"\"); let error = $state(\"\"); let selectedConstraints = $state({ facingMode: \"environment\" }); let barcodeFormats: { [key in BarcodeFormat]: boolean; } = $state({ aztec: false, code_128: false, code_39: false, code_93: false, codabar: false, databar: false, databar_expanded: false, databar_limited: false, data_matrix: false, dx_film_edge: false, ean_13: false, ean_8: false, itf: false, maxi_code: false, micro_qr_code: false, pdf417: false, qr_code: true, rm_qr_code: false, upc_a: false, upc_e: false, linear_codes: false, matrix_codes: false, unknown: false, }); // computed value for selected formats let selectedBarcodeFormats: BarcodeFormat[] = $derived( Object.keys(barcodeFormats).filter( (format: string) => barcodeFormats[format] ) as BarcodeFormat[] ); // track function options const trackFunctionOptions = [ { text: \"nothing (default)\", value: undefined }, { text: \"outline\", value: paintOutline }, { text: \"centered text\", value: paintCenterText }, { text: \"bounding box\", value: paintBoundingBox }, ]; let trackFunctionSelected = $state(trackFunctionOptions[1]); // camera constraint options const defaultConstraintOptions: { label: string; constraints: MediaTrackConstraints }[] = [ { label: \"rear camera\", constraints: { facingMode: \"environment\" } }, { label: \"front camera\", constraints: { facingMode: \"user\" } }, ]; let constraintOptions = $state(defaultConstraintOptions); async function onCameraOn() { try { const devices = await navigator.mediaDevices.enumerateDevices(); const videoDevices = devices.filter(({ kind }) => kind === \"videoinput\"); constraintOptions = [ ...defaultConstraintOptions, ...videoDevices.map(({ deviceId, label }) => ({ label: ${label}, constraints: { deviceId }, })), ]; error = \"\"; } catch (e) { console.error(e); } } function onError(err: { name: string; message: string }) { error = [${err.name}]: ; if (err.name === \"NotAllowedError\") { error += \"you need to grant camera access permission\"; } else if (err.name === \"NotFoundError\") { error += \"no camera on this device\"; } else if (err.name === \"NotSupportedError\") { error += \"secure context required (HTTPS, localhost)\"; } else if (err.name === \"NotReadableError\") { error += \"is the camera already in use?\"; } else if (err.name === \"OverconstrainedError\") { error += \"installed cameras are not suitable\"; } else if (err.name === \"StreamApiNotSupportedError\") { error += \"Stream API is not supported in this browser\"; } else { error += err.message; } } function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes); result = JSON.stringify(detectedCodes.map((code) => code.rawValue)); } // track functions function paintOutline( detectedCodes: { cornerPoints: { x: number; y: number }[]; boundingBox: DOMRectReadOnly; rawValue: string; format: Exclude; }[], ctx: CanvasRenderingContext2D ) { for (const detectedCode of detectedCodes) { const [firstPoint, ...otherPoints] = detectedCode.cornerPoints; ctx.strokeStyle = \"red\"; ctx.beginPath(); ctx.moveTo(firstPoint.x, firstPoint.y); for (const { x, y } of otherPoints) { ctx.lineTo(x, y); } ctx.lineTo(firstPoint.x, firstPoint.y); ctx.closePath(); ctx.stroke(); } } function paintBoundingBox( detectedCodes: { cornerPoints: { x: number; y: number }[]; boundingBox: DOMRectReadOnly; rawValue: string; format: Exclude; }[], ctx: CanvasRenderingContext2D ) { for (const detectedCode of detectedCodes) { const { boundingBox: { x, y, width, height }, } = detectedCode; ctx.lineWidth = 2; ctx.strokeStyle = \"#007bff\"; ctx.strokeRect(x, y, width, height); } } function paintCenterText( detectedCodes: { cornerPoints: { x: number; y: number }[]; boundingBox: DOMRectReadOnly; rawValue: string; format: Exclude; }[], ctx: CanvasRenderingContext2D ) { for (const detectedCode of detectedCodes) { const { boundingBox, rawValue } = detectedCode; const centerX = boundingBox.x + boundingBox.width / 2; const centerY = boundingBox.y + boundingBox.height / 2; const fontSize = Math.max(12, (50 * boundingBox.width) / ctx.canvas.width); ctx.font = bold ${fontSize}px sans-serif; ctx.textAlign = \"center\"; ctx.lineWidth = 3; ctx.strokeStyle = \"#35495e\"; ctx.strokeText(detectedCode.rawValue, centerX, centerY); ctx.fillStyle = \"#5cb984\"; ctx.fillText(rawValue, centerX, centerY); } } Camera constraints: {#each constraintOptions as option} {option.label} {/each} Track function: {#each trackFunctionOptions as option} {option.text} {/each} Barcode formats: {#each Object.keys(barcodeFormats) as option} {@const barcodeOption = option as BarcodeFormat} {option} {/each} {#if error} {error} {/if} Last result: {result} .error { font-weight: bold; color: red; } .scanner { width: 100%; aspect-ratio: 4/3; } `"
+ "content": " import Demo from '$lib/components/demos/full-demo.svelte'; Modern mobile phones often have a variety of different cameras installed (e.g. front, rear, wide-angle, infrared, desk-view). The one picked by default is sometimes not the best choice. For more fine-grained control, you can select a camera by device constraints or by the device ID. Detected codes are visually highlighted in real-time. In this demo you can use the track function dropdown to change the flavor. By default only QR-codes are detected but a variety of other barcode formats are also supported. You can select one or multiple but the more you select the more expensive scanning becomes. Demo Usage import { BarqodeStream, type BarcodeFormat, type DetectedBarcode } from \"barqode\"; let result = $state(\"\"); let error = $state(\"\"); let selectedConstraints = $state({ facingMode: \"environment\" }); let barcodeFormats: { [key in BarcodeFormat]: boolean; } = $state({ aztec: false, code_128: false, code_39: false, code_93: false, codabar: false, databar: false, databar_expanded: false, databar_limited: false, data_matrix: false, dx_film_edge: false, ean_13: false, ean_8: false, itf: false, maxi_code: false, micro_qr_code: false, pdf417: false, qr_code: true, rm_qr_code: false, upc_a: false, upc_e: false, linear_codes: false, matrix_codes: false, unknown: false, }); // computed value for selected formats let selectedBarcodeFormats: BarcodeFormat[] = $derived( Object.keys(barcodeFormats).filter( (format: string) => barcodeFormats[format] ) as BarcodeFormat[] ); // track function options const trackFunctionOptions = [ { text: \"nothing (default)\", value: undefined }, { text: \"outline\", value: paintOutline }, { text: \"centered text\", value: paintCenterText }, { text: \"bounding box\", value: paintBoundingBox }, ]; let trackFunctionSelected = $state(trackFunctionOptions[1]); // camera constraint options const defaultConstraintOptions: { label: string; constraints: MediaTrackConstraints }[] = [ { label: \"rear camera\", constraints: { facingMode: \"environment\" } }, { label: \"front camera\", constraints: { facingMode: \"user\" } }, ]; let constraintOptions = $state(defaultConstraintOptions); async function onCameraOn() { try { const devices = await navigator.mediaDevices.enumerateDevices(); const videoDevices = devices.filter(({ kind }) => kind === \"videoinput\"); constraintOptions = [ ...defaultConstraintOptions, ...videoDevices.map(({ deviceId, label }) => ({ label: ${label}, constraints: { deviceId }, })), ]; error = \"\"; } catch (e) { console.error(e); } } function onError(err: { name: string; message: string }) { error = [${err.name}]: ; if (err.name === \"NotAllowedError\") { error += \"you need to grant camera access permission\"; } else if (err.name === \"NotFoundError\") { error += \"no camera on this device\"; } else if (err.name === \"NotSupportedError\") { error += \"secure context required (HTTPS, localhost)\"; } else if (err.name === \"NotReadableError\") { error += \"is the camera already in use?\"; } else if (err.name === \"OverconstrainedError\") { error += \"installed cameras are not suitable\"; } else if (err.name === \"StreamApiNotSupportedError\") { error += \"Stream API is not supported in this browser\"; } else { error += err.message; } } function onDetect(detectedCodes: DetectedBarcode[]) { console.log(detectedCodes); result = JSON.stringify(detectedCodes.map((code) => code.rawValue)); } // track functions function paintOutline( detectedCodes: { cornerPoints: { x: number; y: number }[]; boundingBox: DOMRectReadOnly; rawValue: string; format: Exclude; }[], ctx: CanvasRenderingContext2D ) { for (const detectedCode of detectedCodes) { const [firstPoint, ...otherPoints] = detectedCode.cornerPoints; ctx.strokeStyle = \"red\"; ctx.beginPath(); ctx.moveTo(firstPoint.x, firstPoint.y); for (const { x, y } of otherPoints) { ctx.lineTo(x, y); } ctx.lineTo(firstPoint.x, firstPoint.y); ctx.closePath(); ctx.stroke(); } } function paintBoundingBox( detectedCodes: { cornerPoints: { x: number; y: number }[]; boundingBox: DOMRectReadOnly; rawValue: string; format: Exclude; }[], ctx: CanvasRenderingContext2D ) { for (const detectedCode of detectedCodes) { const { boundingBox: { x, y, width, height }, } = detectedCode; ctx.lineWidth = 2; ctx.strokeStyle = \"#007bff\"; ctx.strokeRect(x, y, width, height); } } function paintCenterText( detectedCodes: { cornerPoints: { x: number; y: number }[]; boundingBox: DOMRectReadOnly; rawValue: string; format: Exclude; }[], ctx: CanvasRenderingContext2D ) { for (const detectedCode of detectedCodes) { const { boundingBox, rawValue } = detectedCode; const centerX = boundingBox.x + boundingBox.width / 2; const centerY = boundingBox.y + boundingBox.height / 2; const fontSize = Math.max(12, (50 * boundingBox.width) / ctx.canvas.width); ctx.font = bold ${fontSize}px sans-serif; ctx.textAlign = \"center\"; ctx.lineWidth = 3; ctx.strokeStyle = \"#35495e\"; ctx.strokeText(detectedCode.rawValue, centerX, centerY); ctx.fillStyle = \"#5cb984\"; ctx.fillText(rawValue, centerX, centerY); } } Camera constraints: {#each constraintOptions as option} {option.label} {/each} Track function: {#each trackFunctionOptions as option} {option.text} {/each} Barcode formats: {#each Object.keys(barcodeFormats) as option} {@const barcodeOption = option as BarcodeFormat} {option} {/each} {#if error} {error} {/if} Last result:{result} `"
}
]