Upload folder using huggingface_hub
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .gitattributes +5 -0
- DATA/1.jpg +0 -0
- DATA/2.jpg +0 -0
- DATA/3.jpg +0 -0
- DATA/4.jpg +0 -0
- DATA/blackcar.png +0 -0
- DATA/bluecar.png +0 -0
- DATA/cadilac.png +0 -0
- DATA/cadilac2.png +0 -0
- DATA/car_NU51OSU.jpg +0 -0
- DATA/gray.png +0 -0
- DATA/greencar.png +0 -0
- DATA/greencar1.png +0 -0
- DATA/orangecar.png +0 -0
- DATA/purplecar.png +0 -0
- README.md +3 -9
- __pycache__/deploy.cpython-311.pyc +0 -0
- __pycache__/grad.cpython-311.pyc +0 -0
- __pycache__/gradio.cpython-311.pyc +0 -0
- __pycache__/uti.cpython-311.pyc +0 -0
- __pycache__/util.cpython-311.pyc +0 -0
- anpr-v3-b5bb8-firebase-adminsdk-8pkgt-d88b8f69b1.json +13 -0
- car.pt +3 -0
- color.pt +3 -0
- deploy.py +338 -0
- f1.mp4 +3 -0
- f2.mp4 +0 -0
- flagged/Upload Video/e0aad4346d6eb0ce1c58/Untitled video - Made with Clipchamp.mp4 +3 -0
- flagged/log.csv +3 -0
- main.py +227 -0
- make.pt +3 -0
- models/license_plate_detector.pt +3 -0
- models/run45.pt +3 -0
- models/run46.pt +3 -0
- models/train4.pt +3 -0
- models/train5.pt +3 -0
- node_modules/.bin/loose-envify +3 -0
- node_modules/.bin/loose-envify.cmd +3 -0
- node_modules/.bin/loose-envify.ps1 +3 -0
- node_modules/.bin/proto-loader-gen-types +3 -0
- node_modules/.bin/proto-loader-gen-types.cmd +3 -0
- node_modules/.bin/proto-loader-gen-types.ps1 +3 -0
- node_modules/.package-lock.json +955 -0
- node_modules/@fastify/busboy/LICENSE +19 -0
- node_modules/@fastify/busboy/README.md +271 -0
- node_modules/@fastify/busboy/deps/dicer/LICENSE +19 -0
- node_modules/@fastify/busboy/deps/dicer/lib/Dicer.js +207 -0
- node_modules/@fastify/busboy/deps/dicer/lib/HeaderParser.js +100 -0
- node_modules/@fastify/busboy/deps/dicer/lib/PartStream.js +13 -0
- node_modules/@fastify/busboy/deps/dicer/lib/dicer.d.ts +164 -0
.gitattributes
CHANGED
@@ -33,3 +33,8 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
+
f1.mp4 filter=lfs diff=lfs merge=lfs -text
|
37 |
+
flagged/Upload[[:space:]]Video/e0aad4346d6eb0ce1c58/Untitled[[:space:]]video[[:space:]]-[[:space:]]Made[[:space:]]with[[:space:]]Clipchamp.mp4 filter=lfs diff=lfs merge=lfs -text
|
38 |
+
sample.mp4 filter=lfs diff=lfs merge=lfs -text
|
39 |
+
sample1.mp4 filter=lfs diff=lfs merge=lfs -text
|
40 |
+
sample2.mp4 filter=lfs diff=lfs merge=lfs -text
|
DATA/1.jpg
ADDED
DATA/2.jpg
ADDED
DATA/3.jpg
ADDED
DATA/4.jpg
ADDED
DATA/blackcar.png
ADDED
DATA/bluecar.png
ADDED
DATA/cadilac.png
ADDED
DATA/cadilac2.png
ADDED
DATA/car_NU51OSU.jpg
ADDED
DATA/gray.png
ADDED
DATA/greencar.png
ADDED
DATA/greencar1.png
ADDED
DATA/orangecar.png
ADDED
DATA/purplecar.png
ADDED
README.md
CHANGED
@@ -1,12 +1,6 @@
|
|
1 |
---
|
2 |
-
title: ANPR
|
3 |
-
|
4 |
-
colorFrom: blue
|
5 |
-
colorTo: indigo
|
6 |
sdk: gradio
|
7 |
-
sdk_version: 4.19.
|
8 |
-
app_file: app.py
|
9 |
-
pinned: false
|
10 |
---
|
11 |
-
|
12 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
1 |
---
|
2 |
+
title: ANPR-V3
|
3 |
+
app_file: deploy.py
|
|
|
|
|
4 |
sdk: gradio
|
5 |
+
sdk_version: 4.19.1
|
|
|
|
|
6 |
---
|
|
|
|
__pycache__/deploy.cpython-311.pyc
ADDED
Binary file (13 kB). View file
|
|
__pycache__/grad.cpython-311.pyc
ADDED
Binary file (13.2 kB). View file
|
|
__pycache__/gradio.cpython-311.pyc
ADDED
Binary file (13.2 kB). View file
|
|
__pycache__/uti.cpython-311.pyc
ADDED
Binary file (1.42 kB). View file
|
|
__pycache__/util.cpython-311.pyc
ADDED
Binary file (7.69 kB). View file
|
|
anpr-v3-b5bb8-firebase-adminsdk-8pkgt-d88b8f69b1.json
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"type": "service_account",
|
3 |
+
"project_id": "anpr-v3-b5bb8",
|
4 |
+
"private_key_id": "d88b8f69b1cf613de0a1d0ee5e8b1af6afb6dbee",
|
5 |
+
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCovf1wiRo74Q2R\nKdtGvvbhks1wTTAbuDktzci2VHkIhRZZCM+FLDzxqRnJxpqMHINO+nWrwyckOhEZ\nJ954DBf6Yr5zWLrs5oozrjbcTiq+KTtQuHTE/2nhpVgw+B4jZdPk+kj6IAgYuJyH\nI50+1GPvagCfRpxLfFq9Mj6/4i/SO5cb7fywtNSLUdbmP5JpM4pBaCD/8NsaIkuj\njwDyY17RH74AJFRWzaGotf9w3hfzaRPJC+Ib/BjUqMm/5NxY88eOoEeWU417Rvxr\nZ3FET4r1wHvzbYE6mK4+rqTI84binhsnWd+6h5BBSeenF/JDzIEtBjxSJeuSHLBr\n7lr0RWx3AgMBAAECgf8EKT2Ea05LuMcdvZ3e50YYoQHFPtOrN59V6k94OgPKxEdq\nwpido+dYejZO5lE19EgPMJ7QWZclWAAVrmUjXjUrO2pxqPD9jbqI4Q3OnCzIu2qU\nuVCM2XLugo+HWrnS/ZW3vDWaEUiG1iXy2BmF93gk2ztgbHW3XF7nbJD6/tQdpel8\ntaFJBaLJQRcjR2FgsSt7wxCxnwLGXKzaMUH8RsjPxG/mZpQ9RG2cJfIguf5QbuzP\nl5bL6AQTFeDL4JK1UxYD7+3YykqJRbWCyic6eXH7bohRb10QyZnbw4UgAVhCgpIw\nmxBtQkGoom47NIU6o2vV6oLdtezGDTLN1wHVfQECgYEA5nNh0jO4VIkoaouYc+Yu\nsuoJRvXWx9wTHTZkCStxBqEbfZOdYD6Cm9EYStsz87305d9FHCnrrS1cwPQcIRiG\nylmb6c0TLZLfyNFzaNGYRUU5XyqGaCDsrn9cbzHiDI1L8q/7/UKcEqgH/8fn/wXw\nPi5Yy6p98FBR2AUypjmiTK0CgYEAu3M0YVKLj4MHzza3Ejuqxkr2ZVlNxn6p5XWS\nFy9ZvtJ4PEJG1kdZ4tHlyfEFOXQmVwtsn5B1i1N2OtQMyHj9m0jD3A9ktbSWorzn\nK5O/Q7o0cxDXUX16WNzxe3re+p6E4Qycr8VOIKqk54WutX7elL1p2/kkmLjQ8Upr\now9ffjMCgYApCvOpFD0IEUV5dFM6kQxQIQ517OLLxY5B7aXzXCFNJPRYcSneMkPg\nrGS/MDsYdgRfzFvqoCyxMxsJ4nAAFPYso7j48uUvgLEKewMq7+lGrQWCxXgao4KD\nsXss8p1nzuJv3pfqiypwyCxkiZ3v9YbMDEUUQNEdM7Df4E0c/bbCIQKBgQCaDpbQ\nHa1Bp2j1rnxLaepyyg0zQnAfYN51DWmh0HKr2AKlU7swRLflKKj4jTPEAme4RlVh\n1rIkbdXPh5Nx965Gv0jpRWV5yQ+8dBBxyh35pcGRiBfOi5fQDNYSq+sygrGm3Fyy\nQTByvIyHE2GBHOIF0J5+AYdIVSy0AnvwKaRL7QKBgQDkAUu4xIMQdaoKTGK634ah\nemTAS8RTMiIZX8dB/eGFbqym06Itk8NVBf4AUm50GBLgtYCqMHuSV1rlj6O9ARy4\nLPkINwxp7B/4OpsC+X9eRiqqKkyV/o/s6NzIsywg0CmEVDvM3kuQYTD7OJwTbJ2d\nKvciBBZTXeYjXVNNvugo3A==\n-----END PRIVATE KEY-----\n",
|
6 |
+
"client_email": "[email protected]",
|
7 |
+
"client_id": "115254033604831582656",
|
8 |
+
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
9 |
+
"token_uri": "https://oauth2.googleapis.com/token",
|
10 |
+
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
11 |
+
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-8pkgt%40anpr-v3-b5bb8.iam.gserviceaccount.com",
|
12 |
+
"universe_domain": "googleapis.com"
|
13 |
+
}
|
car.pt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:c6c9d9b21ad4145cceec1c584e4f6f93ae73e2db51c0a27a27805e997b41a056
|
3 |
+
size 2980223
|
color.pt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:d2f83df8c3f8ded675c39d951b65ab29f2c00d2ab1640c6a94184126db6b23b4
|
3 |
+
size 3001343
|
deploy.py
ADDED
@@ -0,0 +1,338 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from ultralytics import YOLO
|
2 |
+
import cv2
|
3 |
+
import numpy as np
|
4 |
+
from scipy.spatial import KDTree
|
5 |
+
import os
|
6 |
+
import datetime
|
7 |
+
from sort.sort import *
|
8 |
+
import util
|
9 |
+
import io
|
10 |
+
from util import get_car, read_license_plate
|
11 |
+
import firebase_admin
|
12 |
+
from firebase_admin import credentials, db, storage
|
13 |
+
import base64
|
14 |
+
import gradio as gr
|
15 |
+
|
16 |
+
# Firebase Information Server
|
17 |
+
cred = credentials.Certificate("anpr-v3-b5bb8-firebase-adminsdk-8pkgt-d88b8f69b1.json")
|
18 |
+
firebase_admin.initialize_app(cred, {
|
19 |
+
'databaseURL': 'https://anpr-v3-b5bb8-default-rtdb.asia-southeast1.firebasedatabase.app',
|
20 |
+
'storageBucket': 'anpr-v3-b5bb8.appspot.com'
|
21 |
+
})
|
22 |
+
ref = db.reference('/')
|
23 |
+
|
24 |
+
|
25 |
+
|
26 |
+
################################################################Need To Chaneg This Part too for the Demonastartion
|
27 |
+
users_ref = ref.child('right')
|
28 |
+
|
29 |
+
#Get Data from the RealTime Database of The Firebase
|
30 |
+
root_ref = db.reference('/Detected')
|
31 |
+
# Fetch all data at the root of the database
|
32 |
+
Detected_data = root_ref.get()
|
33 |
+
plates = [data['plate'] for data in Detected_data.values()] if Detected_data else []
|
34 |
+
print(plates)
|
35 |
+
|
36 |
+
car_output_dir = "detected_cars"
|
37 |
+
plate_output_dir = "detected_plates"
|
38 |
+
Detected_dir = "DATA"
|
39 |
+
|
40 |
+
if not os.path.exists(car_output_dir):
|
41 |
+
os.makedirs(car_output_dir)
|
42 |
+
if not os.path.exists(plate_output_dir):
|
43 |
+
os.makedirs(plate_output_dir)
|
44 |
+
|
45 |
+
results = {}
|
46 |
+
mot_tracker = Sort()
|
47 |
+
|
48 |
+
# Load models
|
49 |
+
coco_model = YOLO('yolov8n.pt')
|
50 |
+
license_plate_detector = YOLO('./models/run46.pt')
|
51 |
+
model = YOLO('car.pt')
|
52 |
+
model1 = YOLO("color.pt")
|
53 |
+
# Load video
|
54 |
+
|
55 |
+
|
56 |
+
vehicles = [2, 3, 4, 5, 6, 7]
|
57 |
+
|
58 |
+
frame_skip = 40
|
59 |
+
|
60 |
+
# Read frames
|
61 |
+
frame_nmr = -1
|
62 |
+
ret = True
|
63 |
+
|
64 |
+
# Color Recognition functions
|
65 |
+
# Predefined colors dictionary
|
66 |
+
class_map_color = {
|
67 |
+
0: 'beige',
|
68 |
+
1: 'black',
|
69 |
+
2: 'blue',
|
70 |
+
3: 'brown',
|
71 |
+
4: 'gold',
|
72 |
+
5: 'green',
|
73 |
+
6: 'grey',
|
74 |
+
7: 'orange',
|
75 |
+
8: 'pink',
|
76 |
+
9: 'purple',
|
77 |
+
10: 'red',
|
78 |
+
11: 'sivler',
|
79 |
+
12: 'tan',
|
80 |
+
13: 'white',
|
81 |
+
14: 'yellow'
|
82 |
+
}
|
83 |
+
|
84 |
+
# def reset_counts():
|
85 |
+
# global vehicle_counts, current_frame_count, unique_vehicle_ids
|
86 |
+
# vehicle_counts = {v: 0 for v in coco_class_to_vehicle_type.values()} # Reset vehicle counts
|
87 |
+
# unique_vehicle_ids.clear() # Clear the set of unique vehicle IDs
|
88 |
+
# current_frame_count = 0 # Reset frame counter
|
89 |
+
|
90 |
+
# def upload_text(path, text):
|
91 |
+
# ref = db.reference(path)
|
92 |
+
# ref.set(text)
|
93 |
+
|
94 |
+
# def upload_two_texts_append(path, text1, text2):
|
95 |
+
# # Create a reference to the specified path in the Firebase Realtime Database
|
96 |
+
# ref = db.reference(path)
|
97 |
+
|
98 |
+
# # Structure the data as a dictionary with two keys, each holding one of the text strings
|
99 |
+
# data = {
|
100 |
+
# 'text1': text1,
|
101 |
+
# 'text2': text2
|
102 |
+
# }
|
103 |
+
|
104 |
+
# # Use the push() method to add the data under a new, unique child node at the specified path
|
105 |
+
# new_ref = ref.push(data)
|
106 |
+
|
107 |
+
# print(f"Appended text1 and text2 under {path} at {new_ref.key}")
|
108 |
+
|
109 |
+
def upload_to_firebase(filename, destination_blob_name):
|
110 |
+
bucket = storage.bucket()
|
111 |
+
blob = bucket.blob(destination_blob_name)
|
112 |
+
blob.upload_from_filename(filename)
|
113 |
+
|
114 |
+
print(f"File {filename} uploaded to {destination_blob_name}.")
|
115 |
+
|
116 |
+
# Return the public URL of the uploaded image
|
117 |
+
return blob.public_url
|
118 |
+
|
119 |
+
# print(f"Data saved to database with key: {new_user.key}")
|
120 |
+
|
121 |
+
def find_plate(search_plate, plate_array):
|
122 |
+
return search_plate in plate_array
|
123 |
+
|
124 |
+
#----------------------------------------------------------------
|
125 |
+
#Car coutner
|
126 |
+
|
127 |
+
|
128 |
+
|
129 |
+
|
130 |
+
#================================================================
|
131 |
+
class_map = {0: 'Convertible', 1: 'Coupe', 2: 'Hatchback', 3: 'Pickup', 4: 'SUV', 5: 'Sedan'}
|
132 |
+
|
133 |
+
def process_video(video_path):
|
134 |
+
cap = cv2.VideoCapture(video_path)
|
135 |
+
# Initialize a set to keep track of unique vehicle IDs detected by SORT
|
136 |
+
coco_class_to_vehicle_type = {
|
137 |
+
2: 'car', 3: 'motorcycle', 4: 'airplane', 5: 'bus', 6: 'train', 7: 'truck'
|
138 |
+
}
|
139 |
+
vehicle_counts = {v: 0 for v in coco_class_to_vehicle_type.values()}
|
140 |
+
# Initialize a set to keep track of unique vehicle IDs detected by SORT
|
141 |
+
unique_vehicle_ids = set()
|
142 |
+
# Initialize dictionary to map vehicle track IDs to their COCO class IDs
|
143 |
+
track_id_to_class_id = {}
|
144 |
+
cnt = 0
|
145 |
+
score = 1
|
146 |
+
frame_rate = cap.get(cv2.CAP_PROP_FPS) # Get the frame rate of the video
|
147 |
+
count_duration_seconds = 10 # Duration in seconds before resetting counts
|
148 |
+
frame_count_for_reset = int(frame_rate * count_duration_seconds) # Calculate number of frames for the duration
|
149 |
+
current_frame_count = 0 # Initialize a counter for frames
|
150 |
+
|
151 |
+
output_messages = []
|
152 |
+
ret = True
|
153 |
+
frame_nmr = 0
|
154 |
+
while ret:
|
155 |
+
frame_nmr += 1
|
156 |
+
ret, frame = cap.read()
|
157 |
+
current_frame_count += 1 # Increment frame counter
|
158 |
+
|
159 |
+
if ret and frame_nmr % frame_skip == 0:
|
160 |
+
# Perform detection
|
161 |
+
detections = coco_model(frame)[0]
|
162 |
+
detections_ = []
|
163 |
+
|
164 |
+
for detection in detections.boxes.data.tolist():
|
165 |
+
x1, y1, x2, y2, score, class_id = detection
|
166 |
+
cnt+=1
|
167 |
+
if int(class_id) in vehicles:
|
168 |
+
# Append detections with class ID for later reference
|
169 |
+
detections_.append([x1, y1, x2, y2, score, class_id])
|
170 |
+
|
171 |
+
# Convert detections for tracking (excluding class_id)
|
172 |
+
tracking_data = np.array([d[:5] for d in detections_])
|
173 |
+
track_bbs_ids = mot_tracker.update(tracking_data)
|
174 |
+
|
175 |
+
# Update track ID to class ID mapping
|
176 |
+
for track in track_bbs_ids:
|
177 |
+
track_id = int(track[4])
|
178 |
+
# Find matching detection (assuming first match is correct for simplicity)
|
179 |
+
for d in detections_:
|
180 |
+
if all([np.isclose(track[i], d[i], atol=1e-3) for i in range(4)]): # Simple bounding box match
|
181 |
+
class_id = d[5]
|
182 |
+
track_id_to_class_id[track_id] = class_id
|
183 |
+
break
|
184 |
+
|
185 |
+
# Debug print
|
186 |
+
# if detections_:
|
187 |
+
# print(f"Vehicle detections with confidence: {[(d[4], 'Confidence') for d in detections_]}")
|
188 |
+
|
189 |
+
# Track vehicles
|
190 |
+
track_ids = mot_tracker.update(np.asarray(detections_))
|
191 |
+
for track in track_bbs_ids:
|
192 |
+
track_id = int(track[4]) # Track ID is the last element in the track array
|
193 |
+
unique_vehicle_ids.add(track_id)
|
194 |
+
|
195 |
+
# Debug print
|
196 |
+
# if len(track_ids) > 0:
|
197 |
+
# print(f"Tracking IDs: {track_ids}")
|
198 |
+
|
199 |
+
# Detect license plates
|
200 |
+
license_plates = license_plate_detector(frame)[0]
|
201 |
+
|
202 |
+
# Debug print
|
203 |
+
# if license_plates:
|
204 |
+
# print(f"License plates detected: {len(license_plates.boxes.data.tolist())}")
|
205 |
+
|
206 |
+
for license_plate in license_plates.boxes.data.tolist():
|
207 |
+
x1, y1, x2, y2, score, class_id = license_plate
|
208 |
+
|
209 |
+
# Assign license plate to car
|
210 |
+
xcar1, ycar1, xcar2, ycar2, car_id = get_car(license_plate, track_ids)
|
211 |
+
|
212 |
+
if car_id != -1:
|
213 |
+
print(f"Car ID: {car_id}, Confidence: {score}") # Debug print
|
214 |
+
# upload_text('/', car_id)
|
215 |
+
# Crop and process license plate
|
216 |
+
license_plate_crop = frame[int(y1):int(y2), int(x1): int(x2), :]
|
217 |
+
license_plate_crop_gray = cv2.cvtColor(license_plate_crop, cv2.COLOR_BGR2GRAY)
|
218 |
+
_, license_plate_crop_thresh = cv2.threshold(license_plate_crop_gray, 64, 255, cv2.THRESH_BINARY_INV)
|
219 |
+
|
220 |
+
# Read license plate number
|
221 |
+
license_plate_text, license_plate_text_score = read_license_plate(license_plate_crop_thresh)
|
222 |
+
|
223 |
+
|
224 |
+
|
225 |
+
if license_plate_text is not None:
|
226 |
+
print(f"License Plate Text: {license_plate_text}") # Debug print
|
227 |
+
|
228 |
+
is_plate_found = find_plate(license_plate_text, plates)
|
229 |
+
print(f"Is the plate '{license_plate_text}' found? {'Yes' if is_plate_found else 'No'}")
|
230 |
+
# if(is_plate_found):
|
231 |
+
# print(1)
|
232 |
+
# else:
|
233 |
+
# continue
|
234 |
+
|
235 |
+
# Save the image of the detected car
|
236 |
+
car_image = frame[int(ycar1):int(ycar2), int(xcar1): int(xcar2), :]
|
237 |
+
|
238 |
+
# dominant_color = find_dominant_color(car_image)
|
239 |
+
# closest_color_name = find_closest_color_name(dominant_color)
|
240 |
+
# print(f"Vehicle Color: {closest_color_name}") # Debug print
|
241 |
+
results1 = model1(car_image)
|
242 |
+
|
243 |
+
# Assuming the top prediction is what you're interested in
|
244 |
+
top_prediction_index = results1[0].probs.top5[0] # Index of the highest probability class
|
245 |
+
top_prediction_prob = results1[0].probs.top5conf[0].item() # Highest probability
|
246 |
+
|
247 |
+
# Get the car type from the class_map
|
248 |
+
car_color = class_map_color[top_prediction_index]
|
249 |
+
print(f"{car_color}")
|
250 |
+
|
251 |
+
# Save the car image to the local filesystem
|
252 |
+
# cv2.imwrite(car_image_filename, car_image)
|
253 |
+
|
254 |
+
|
255 |
+
################################
|
256 |
+
#Type of Car Detectin
|
257 |
+
# Perform object detection
|
258 |
+
results = model(car_image)
|
259 |
+
|
260 |
+
# Assuming the top prediction is what you're interested in
|
261 |
+
top_prediction_index = results[0].probs.top5[0] # Index of the highest probability class
|
262 |
+
top_prediction_prob = results[0].probs.top5conf[0].item() # Highest probability
|
263 |
+
|
264 |
+
# Get the car type from the class_map
|
265 |
+
car_type = class_map[top_prediction_index]
|
266 |
+
print(f"{car_type}")
|
267 |
+
|
268 |
+
now_str = datetime.datetime.utcnow().replace(microsecond=0).isoformat()
|
269 |
+
# Current date and time as Unix timestamp in milliseconds
|
270 |
+
now_int = int(datetime.datetime.utcnow().timestamp() * 1000)
|
271 |
+
|
272 |
+
|
273 |
+
# Save the image of the detected car
|
274 |
+
car_image_filename = os.path.join(car_output_dir, f"car_{license_plate_text}.jpg")
|
275 |
+
cv2.imwrite(car_image_filename, car_image)
|
276 |
+
car_image_url = upload_to_firebase(car_image_filename, f"detected_cars/car_{license_plate_text}_{now_str}_{now_int}_{car_color}_{car_type}.jpg")
|
277 |
+
|
278 |
+
if(is_plate_found):
|
279 |
+
Detected_dir1 = os.path.join(Detected_dir, f"car_{license_plate_text}.jpg")
|
280 |
+
cv2.imwrite(Detected_dir1, car_image)
|
281 |
+
car_image_url = upload_to_firebase(Detected_dir1, f"DATA/car_{license_plate_text}_{now_str}_{now_int}_{car_color}_{car_type}.jpg")
|
282 |
+
|
283 |
+
|
284 |
+
# Save the image of the detected license plate
|
285 |
+
license_plate_image_filename = os.path.join(plate_output_dir, f"plate_{license_plate_text}.jpg")
|
286 |
+
cv2.imwrite(license_plate_image_filename, license_plate_crop)
|
287 |
+
license_plate_url = upload_to_firebase(license_plate_image_filename, f"detected_plates/plate_{license_plate_text}_{now_str}_{now_int}.jpg")
|
288 |
+
|
289 |
+
|
290 |
+
# print(f"License plate image uploaded: {license_plate_url}") # Debug print
|
291 |
+
# print(f"Current vehicle counts (before potential reset): {vehicle_counts}")
|
292 |
+
|
293 |
+
# Count vehicles by type after processing all frames
|
294 |
+
vehicle_counts = {v: 0 for v in coco_class_to_vehicle_type.values()}
|
295 |
+
for class_id in track_id_to_class_id.values():
|
296 |
+
vehicle_type = coco_class_to_vehicle_type.get(class_id, 'unknown')
|
297 |
+
if vehicle_type in vehicle_counts:
|
298 |
+
vehicle_counts[vehicle_type] += 1
|
299 |
+
|
300 |
+
# Print counts
|
301 |
+
for vehicle_type, count in vehicle_counts.items():
|
302 |
+
if vehicle_counts.items() == 0:
|
303 |
+
score += count * 1
|
304 |
+
else:
|
305 |
+
score += count* 4
|
306 |
+
|
307 |
+
print(f"Total {vehicle_type}s detected: {count}")
|
308 |
+
data = users_ref.push({'text1': vehicle_type,'text2': count})
|
309 |
+
# upload_two_texts_append("/right", vehicle_type, count)
|
310 |
+
|
311 |
+
print(cnt)
|
312 |
+
print('/traffic-score1', score)
|
313 |
+
# print('/traffic-score2', score)
|
314 |
+
|
315 |
+
#####First
|
316 |
+
# score1 = ref.child('TrafficScore1')
|
317 |
+
# score1.set(score)
|
318 |
+
|
319 |
+
|
320 |
+
#####Second
|
321 |
+
score2 = ref.child('TrafficScore2')
|
322 |
+
score2.set(score)
|
323 |
+
|
324 |
+
output_messages.append(f"Traffic-Score1: {score}")
|
325 |
+
# output_messages.append(f"Traffic-Score1: {score}")
|
326 |
+
output_messages.append(f"Total detections: {cnt}") # Assuming cnt is your counter for detections
|
327 |
+
|
328 |
+
return "\n".join(output_messages) # Join all messages into a single string
|
329 |
+
|
330 |
+
|
331 |
+
iface = gr.Interface(fn=process_video,
|
332 |
+
inputs=gr.Video(label="Upload Video"),
|
333 |
+
outputs="text",
|
334 |
+
title="Vehicle and License Plate Detection",
|
335 |
+
description="Upload a video to detect vehicles and license plates.")
|
336 |
+
|
337 |
+
if __name__ == "__main__":
|
338 |
+
iface.launch(share=True)
|
f1.mp4
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:c6a5d4ed8b2594e6263d0f48ca559672b5db97161c8d5c4320869f9c9febdaf5
|
3 |
+
size 6523212
|
f2.mp4
ADDED
Binary file (979 kB). View file
|
|
flagged/Upload Video/e0aad4346d6eb0ce1c58/Untitled video - Made with Clipchamp.mp4
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:c6a5d4ed8b2594e6263d0f48ca559672b5db97161c8d5c4320869f9c9febdaf5
|
3 |
+
size 6523212
|
flagged/log.csv
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
Upload Video,output,flag,username,timestamp
|
2 |
+
"{""video"":{""path"":""flagged\\Upload Video\\e0aad4346d6eb0ce1c58\\Untitled video - Made with Clipchamp.mp4"",""url"":""http://127.0.0.1:7860/file=C:\\Users\\songh\\AppData\\Local\\Temp\\gradio\\00cc535124d8b2cab971797bdbf8a05572a1ee73\\Untitled video - Made with Clipchamp.mp4"",""size"":6523212,""orig_name"":""Untitled video - Made with Clipchamp.mp4"",""mime_type"":"""",""is_stream"":false},""subtitles"":null}","Total frames processed: 0
|
3 |
+
Total detections: 71",,,2024-02-21 02:56:53.479832
|
main.py
ADDED
@@ -0,0 +1,227 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from ultralytics import YOLO
|
2 |
+
import cv2
|
3 |
+
import numpy as np
|
4 |
+
import util
|
5 |
+
from sort.sort import *
|
6 |
+
from util import get_car, read_license_plate
|
7 |
+
import os
|
8 |
+
import firebase_admin
|
9 |
+
from firebase_admin import storage
|
10 |
+
import datetime
|
11 |
+
|
12 |
+
current_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
13 |
+
|
14 |
+
|
15 |
+
#Firebase Information Server
|
16 |
+
import firebase_admin
|
17 |
+
from firebase_admin import credentials, db
|
18 |
+
|
19 |
+
cred = credentials.Certificate("anpr-5a023-firebase-adminsdk-mrrmo-d159fa0e4d.json")
|
20 |
+
firebase_admin.initialize_app(cred, {
|
21 |
+
'databaseURL': 'https://anpr-5a023-default-rtdb.asia-southeast1.firebasedatabase.app',
|
22 |
+
'storageBucket': 'anpr-5a023.appspot.com'
|
23 |
+
})
|
24 |
+
ref = db.reference('/')
|
25 |
+
users_ref = ref.child('users_detected')
|
26 |
+
#Firebase Information Server
|
27 |
+
|
28 |
+
|
29 |
+
# Directories for saving detected cars and license plates
|
30 |
+
car_output_dir = "detected_cars"
|
31 |
+
plate_output_dir = "detected_plates"
|
32 |
+
if not os.path.exists(car_output_dir):
|
33 |
+
os.makedirs(car_output_dir)
|
34 |
+
if not os.path.exists(plate_output_dir):
|
35 |
+
os.makedirs(plate_output_dir)
|
36 |
+
|
37 |
+
|
38 |
+
results = {}
|
39 |
+
mot_tracker = Sort()
|
40 |
+
|
41 |
+
# Load models
|
42 |
+
coco_model = YOLO('yolov8n.pt')
|
43 |
+
license_plate_detector = YOLO('./models/run46.pt')
|
44 |
+
|
45 |
+
# Load video
|
46 |
+
cap = cv2.VideoCapture('./f1.mp4')
|
47 |
+
|
48 |
+
vehicles = [2, 3, 4, 5, 6, 7]
|
49 |
+
|
50 |
+
frame_skip = 40
|
51 |
+
|
52 |
+
# Read frames
|
53 |
+
frame_nmr = -1
|
54 |
+
ret = True
|
55 |
+
|
56 |
+
|
57 |
+
|
58 |
+
|
59 |
+
def upload_to_firebase(filename, destination_blob_name):
|
60 |
+
"""
|
61 |
+
Uploads a file to Firebase Cloud Storage.
|
62 |
+
|
63 |
+
Parameters:
|
64 |
+
- filename: Path to the file to upload.
|
65 |
+
- destination_blob_name: Storage object name.
|
66 |
+
"""
|
67 |
+
|
68 |
+
bucket = storage.bucket()
|
69 |
+
blob = bucket.blob(destination_blob_name)
|
70 |
+
blob.upload_from_filename(filename)
|
71 |
+
|
72 |
+
print(f"File {filename} uploaded to {destination_blob_name}.")
|
73 |
+
|
74 |
+
# Return the public URL of the uploaded image
|
75 |
+
return blob.public_url
|
76 |
+
|
77 |
+
|
78 |
+
|
79 |
+
|
80 |
+
while ret:
|
81 |
+
frame_nmr += 1
|
82 |
+
ret, frame = cap.read()
|
83 |
+
if ret and frame_nmr % frame_skip == 0:
|
84 |
+
print(f"Processing frame {frame_nmr}") # Debug print
|
85 |
+
results[frame_nmr] = {}
|
86 |
+
|
87 |
+
# Detect vehicles
|
88 |
+
detections = coco_model(frame)[0]
|
89 |
+
detections_ = []
|
90 |
+
|
91 |
+
for detection in detections.boxes.data.tolist():
|
92 |
+
x1, y1, x2, y2, score, class_id = detection
|
93 |
+
if int(class_id) in vehicles:
|
94 |
+
detections_.append([x1, y1, x2, y2, score])
|
95 |
+
|
96 |
+
# Debug print
|
97 |
+
if detections_:
|
98 |
+
print(f"Vehicle detections with confidence: {[(d[4], 'Confidence') for d in detections_]}")
|
99 |
+
|
100 |
+
# Track vehicles
|
101 |
+
track_ids = mot_tracker.update(np.asarray(detections_))
|
102 |
+
|
103 |
+
# Debug print
|
104 |
+
if len(track_ids) > 0:
|
105 |
+
print(f"Tracking IDs: {track_ids}")
|
106 |
+
|
107 |
+
# Detect license plates
|
108 |
+
license_plates = license_plate_detector(frame)[0]
|
109 |
+
|
110 |
+
# Debug print
|
111 |
+
if license_plates:
|
112 |
+
print(f"License plates detected: {len(license_plates.boxes.data.tolist())}")
|
113 |
+
|
114 |
+
for license_plate in license_plates.boxes.data.tolist():
|
115 |
+
x1, y1, x2, y2, score, class_id = license_plate
|
116 |
+
|
117 |
+
# Assign license plate to car
|
118 |
+
xcar1, ycar1, xcar2, ycar2, car_id = get_car(license_plate, track_ids)
|
119 |
+
|
120 |
+
if car_id != -1:
|
121 |
+
print(f"Car ID: {car_id}, Confidence: {score}") # Debug print
|
122 |
+
|
123 |
+
# Crop and process license plate
|
124 |
+
license_plate_crop = frame[int(y1):int(y2), int(x1): int(x2), :]
|
125 |
+
license_plate_crop_gray = cv2.cvtColor(license_plate_crop, cv2.COLOR_BGR2GRAY)
|
126 |
+
_, license_plate_crop_thresh = cv2.threshold(license_plate_crop_gray, 64, 255, cv2.THRESH_BINARY_INV)
|
127 |
+
|
128 |
+
# Read license plate number
|
129 |
+
license_plate_text, license_plate_text_score = read_license_plate(license_plate_crop_thresh)
|
130 |
+
|
131 |
+
# # Resize the thresholded license plate for better visibility
|
132 |
+
# scale_factor = 2 # Change this value as needed
|
133 |
+
# h, w = license_plate_crop_thresh.shape[:2]
|
134 |
+
# resized_license_plate = cv2.resize(license_plate_crop_thresh, (int(w * scale_factor), int(h * scale_factor)))
|
135 |
+
|
136 |
+
# # Display the resized thresholded license plate
|
137 |
+
# cv2.imshow('License Plate Thresholded', resized_license_plate)
|
138 |
+
# key = cv2.waitKey(0) # Wait until a key is pressed
|
139 |
+
# if key == 27: # ESC key
|
140 |
+
# break
|
141 |
+
|
142 |
+
|
143 |
+
if license_plate_text is not None:
|
144 |
+
print(f"License Plate Text: {license_plate_text}") # Debug print
|
145 |
+
|
146 |
+
# Save the image of the detected car
|
147 |
+
car_image = frame[int(ycar1):int(ycar2), int(xcar1): int(xcar2), :]
|
148 |
+
car_image_filename = os.path.join(car_output_dir, f"car_{license_plate_text}.jpg")
|
149 |
+
cv2.imwrite(car_image_filename, car_image)
|
150 |
+
car_image_url = upload_to_firebase(car_image_filename, f"detected_cars/car_{license_plate_text}.jpg")
|
151 |
+
|
152 |
+
# Save the image of the detected license plate
|
153 |
+
license_plate_image_filename = os.path.join(plate_output_dir, f"plate_{license_plate_text}.jpg")
|
154 |
+
cv2.imwrite(license_plate_image_filename, license_plate_crop)
|
155 |
+
license_plate_url = upload_to_firebase(license_plate_image_filename, f"detected_plates/plate_{license_plate_text}.jpg")
|
156 |
+
|
157 |
+
|
158 |
+
new_user = users_ref.push({
|
159 |
+
'license_plate': license_plate_text,
|
160 |
+
'timestamp': current_time
|
161 |
+
})
|
162 |
+
|
163 |
+
|
164 |
+
results[frame_nmr][car_id] = {
|
165 |
+
'car': {'bbox': [xcar1, ycar1, xcar2, ycar2], 'score': score},
|
166 |
+
'license_plate': {'bbox': [x1, y1, x2, y2],
|
167 |
+
'text': license_plate_text,
|
168 |
+
'bbox_score': score,
|
169 |
+
'text_score': license_plate_text_score}
|
170 |
+
}
|
171 |
+
|
172 |
+
|
173 |
+
|
174 |
+
# Fetch data from Firebase
|
175 |
+
users_detected_data = users_ref.get()
|
176 |
+
users_database_ref = ref.child('users_database')
|
177 |
+
users_database_data = users_database_ref.get()
|
178 |
+
|
179 |
+
# Extract license plate values
|
180 |
+
detected_license_plates = {uid: details['license_plate'] for uid, details in users_detected_data.items()}
|
181 |
+
database_license_plates = {uid: entry['License_Plate'] for uid, entry in enumerate(users_database_data) if 'License_Plate' in entry}
|
182 |
+
|
183 |
+
|
184 |
+
# Find matching license plates and store the complete data
|
185 |
+
flagged_data = {}
|
186 |
+
|
187 |
+
for uid, license_plate in detected_license_plates.items():
|
188 |
+
if license_plate in database_license_plates.values():
|
189 |
+
flagged_data[uid] = users_detected_data[uid]
|
190 |
+
|
191 |
+
# Write flagged data to Firebase if any matches found
|
192 |
+
if flagged_data:
|
193 |
+
flagged_ref = ref.child('flagged')
|
194 |
+
flagged_ref.set(flagged_data)
|
195 |
+
|
196 |
+
flagged_details_data = {} # Dictionary to store detailed flagged data
|
197 |
+
|
198 |
+
# Collect details from users_database for flagged License_Plate and upload to Firebase
|
199 |
+
for uid in flagged_data:
|
200 |
+
license_plate = flagged_data[uid]['license_plate']
|
201 |
+
for user_id, user_data in enumerate(users_database_data):
|
202 |
+
if user_data.get('License_Plate') == license_plate:
|
203 |
+
print("\nFlagged User Details:")
|
204 |
+
flagged_user_detail = {} # Dictionary to store details of this flagged user
|
205 |
+
for key, value in user_data.items():
|
206 |
+
print(f"{key}: {value}")
|
207 |
+
flagged_user_detail[key] = value
|
208 |
+
flagged_details_data[user_id] = flagged_user_detail # Append to main dictionary
|
209 |
+
|
210 |
+
# Push flagged user details to Firebase
|
211 |
+
if flagged_details_data:
|
212 |
+
flagged_details_ref = ref.child('flagged_details')
|
213 |
+
flagged_details_ref.set(flagged_details_data)
|
214 |
+
|
215 |
+
print("Suspected data")
|
216 |
+
print(flagged_data)
|
217 |
+
|
218 |
+
|
219 |
+
if flagged_data:
|
220 |
+
flagged_ref = ref.child('flagged')
|
221 |
+
flagged_ref.set(flagged_data)
|
222 |
+
|
223 |
+
# Collect details from users_database for flagged License_Plate and upload to Firebase
|
224 |
+
# ...
|
225 |
+
if flagged_details_data:
|
226 |
+
flagged_details_ref = ref.child('flagged_details')
|
227 |
+
flagged_details_ref.set(flagged_details_data)
|
make.pt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:a2aaf56f34cd861f7041312a8c46018ed4ab2a0367a4d1ca3065ca9646c55b22
|
3 |
+
size 3475007
|
models/license_plate_detector.pt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:8ec3b254a6c87610f037a90957462cafa11a9c03224e33a28c6a1d1ac2ac51b0
|
3 |
+
size 6241454
|
models/run45.pt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:dfb0048af37224c2b3068771dcd887694166426d9578786f71815974412ab36e
|
3 |
+
size 6263087
|
models/run46.pt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:163606ad1191db6d545a84ea4ebc1d0ec991a38a488854907e9f2a518ad328bf
|
3 |
+
size 6262575
|
models/train4.pt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:989192e4c66e2ed715f9570f1e07b6c803a54dae4b877a5a73322806487048ba
|
3 |
+
size 6238959
|
models/train5.pt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:9826d43ef4078aa3686aa222311340613d188897a8444a0e670003f535cf17b2
|
3 |
+
size 24545071
|
node_modules/.bin/loose-envify
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:73e89194039ffb1b7a325066f61ae2f30301efe7de6a60396447989b4b0d8cd7
|
3 |
+
size 306
|
node_modules/.bin/loose-envify.cmd
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:b8cb11966e80179f907d3fd0d8bb808a6dd7ea08ad4af9cc496f67eeed8a4080
|
3 |
+
size 324
|
node_modules/.bin/loose-envify.ps1
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:4e8449b4d8cc0f3009fca0820513cdb0cee7dbdcd19871296cb2cbafc399c4c1
|
3 |
+
size 801
|
node_modules/.bin/proto-loader-gen-types
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:b7234ca762e6a83fe6122bee61442d406f96370f30a3e941f18a7a9bceb6ce80
|
3 |
+
size 376
|
node_modules/.bin/proto-loader-gen-types.cmd
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:cd95d039f853fa930b299b5d30c0b2d9d08de9eef969dd7a82c119a5d4a5d023
|
3 |
+
size 359
|
node_modules/.bin/proto-loader-gen-types.ps1
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:cea49f12a3f42e2b6319b828a8b38d02734fa600002cf5717e822c3305716942
|
3 |
+
size 941
|
node_modules/.package-lock.json
ADDED
@@ -0,0 +1,955 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "automatic-number-plate-recognition-python-yolov8",
|
3 |
+
"lockfileVersion": 3,
|
4 |
+
"requires": true,
|
5 |
+
"packages": {
|
6 |
+
"node_modules/@fastify/busboy": {
|
7 |
+
"version": "2.1.0",
|
8 |
+
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz",
|
9 |
+
"integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==",
|
10 |
+
"engines": {
|
11 |
+
"node": ">=14"
|
12 |
+
}
|
13 |
+
},
|
14 |
+
"node_modules/@firebase/analytics": {
|
15 |
+
"version": "0.10.1",
|
16 |
+
"resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.1.tgz",
|
17 |
+
"integrity": "sha512-5mnH1aQa99J5lZMJwTNzIoRc4yGXHf+fOn+EoEWhCDA3XGPweGHcylCbqq+G1wVJmfILL57fohDMa8ftMZ+44g==",
|
18 |
+
"dependencies": {
|
19 |
+
"@firebase/component": "0.6.5",
|
20 |
+
"@firebase/installations": "0.6.5",
|
21 |
+
"@firebase/logger": "0.4.0",
|
22 |
+
"@firebase/util": "1.9.4",
|
23 |
+
"tslib": "^2.1.0"
|
24 |
+
},
|
25 |
+
"peerDependencies": {
|
26 |
+
"@firebase/app": "0.x"
|
27 |
+
}
|
28 |
+
},
|
29 |
+
"node_modules/@firebase/analytics-compat": {
|
30 |
+
"version": "0.2.7",
|
31 |
+
"resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.7.tgz",
|
32 |
+
"integrity": "sha512-17VCly4P0VFBDqaaal7m1nhyYQwsygtaTpSsnc51sFPRrr9XIYtnD8ficon9fneEGEoJQ2g7OtASvhwX9EbK8g==",
|
33 |
+
"dependencies": {
|
34 |
+
"@firebase/analytics": "0.10.1",
|
35 |
+
"@firebase/analytics-types": "0.8.0",
|
36 |
+
"@firebase/component": "0.6.5",
|
37 |
+
"@firebase/util": "1.9.4",
|
38 |
+
"tslib": "^2.1.0"
|
39 |
+
},
|
40 |
+
"peerDependencies": {
|
41 |
+
"@firebase/app-compat": "0.x"
|
42 |
+
}
|
43 |
+
},
|
44 |
+
"node_modules/@firebase/analytics-types": {
|
45 |
+
"version": "0.8.0",
|
46 |
+
"resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.0.tgz",
|
47 |
+
"integrity": "sha512-iRP+QKI2+oz3UAh4nPEq14CsEjrjD6a5+fuypjScisAh9kXKFvdJOZJDwk7kikLvWVLGEs9+kIUS4LPQV7VZVw=="
|
48 |
+
},
|
49 |
+
"node_modules/@firebase/app": {
|
50 |
+
"version": "0.9.27",
|
51 |
+
"resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.27.tgz",
|
52 |
+
"integrity": "sha512-p2Dvl1ge4kRsyK5+wWcmdAIE9MSwZ0pDKAYB51LZgZuz6wciUZk4E1yAEdkfQlRxuHehn+Ol9WP5Qk2XQZiHGg==",
|
53 |
+
"dependencies": {
|
54 |
+
"@firebase/component": "0.6.5",
|
55 |
+
"@firebase/logger": "0.4.0",
|
56 |
+
"@firebase/util": "1.9.4",
|
57 |
+
"idb": "7.1.1",
|
58 |
+
"tslib": "^2.1.0"
|
59 |
+
}
|
60 |
+
},
|
61 |
+
"node_modules/@firebase/app-check": {
|
62 |
+
"version": "0.8.2",
|
63 |
+
"resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.8.2.tgz",
|
64 |
+
"integrity": "sha512-A2B5+ldOguYAeqW1quFN5qNdruSNRrg4W59ag1Eq6QzxuHNIkrE+TrapfrW/z5NYFjCxAYqr/unVCgmk80Dwcg==",
|
65 |
+
"dependencies": {
|
66 |
+
"@firebase/component": "0.6.5",
|
67 |
+
"@firebase/logger": "0.4.0",
|
68 |
+
"@firebase/util": "1.9.4",
|
69 |
+
"tslib": "^2.1.0"
|
70 |
+
},
|
71 |
+
"peerDependencies": {
|
72 |
+
"@firebase/app": "0.x"
|
73 |
+
}
|
74 |
+
},
|
75 |
+
"node_modules/@firebase/app-check-compat": {
|
76 |
+
"version": "0.3.9",
|
77 |
+
"resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.9.tgz",
|
78 |
+
"integrity": "sha512-7LxyupQ8XeEHRh72mO+tqm69kHT6KbWi2KtFMGedJ6tNbwzFzojcXESMKN8RpADXbYoQgY3loWMJjMx4r2Zt7w==",
|
79 |
+
"dependencies": {
|
80 |
+
"@firebase/app-check": "0.8.2",
|
81 |
+
"@firebase/app-check-types": "0.5.0",
|
82 |
+
"@firebase/component": "0.6.5",
|
83 |
+
"@firebase/logger": "0.4.0",
|
84 |
+
"@firebase/util": "1.9.4",
|
85 |
+
"tslib": "^2.1.0"
|
86 |
+
},
|
87 |
+
"peerDependencies": {
|
88 |
+
"@firebase/app-compat": "0.x"
|
89 |
+
}
|
90 |
+
},
|
91 |
+
"node_modules/@firebase/app-check-interop-types": {
|
92 |
+
"version": "0.3.0",
|
93 |
+
"resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.0.tgz",
|
94 |
+
"integrity": "sha512-xAxHPZPIgFXnI+vb4sbBjZcde7ZluzPPaSK7Lx3/nmuVk4TjZvnL8ONnkd4ERQKL8WePQySU+pRcWkh8rDf5Sg=="
|
95 |
+
},
|
96 |
+
"node_modules/@firebase/app-check-types": {
|
97 |
+
"version": "0.5.0",
|
98 |
+
"resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.0.tgz",
|
99 |
+
"integrity": "sha512-uwSUj32Mlubybw7tedRzR24RP8M8JUVR3NPiMk3/Z4bCmgEKTlQBwMXrehDAZ2wF+TsBq0SN1c6ema71U/JPyQ=="
|
100 |
+
},
|
101 |
+
"node_modules/@firebase/app-compat": {
|
102 |
+
"version": "0.2.27",
|
103 |
+
"resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.27.tgz",
|
104 |
+
"integrity": "sha512-SYlqocfUDKPHR6MSFC8hree0BTiWFu5o8wbf6zFlYXyG41w7TcHp4wJi4H/EL5V6cM4kxwruXTJtqXX/fRAZtw==",
|
105 |
+
"dependencies": {
|
106 |
+
"@firebase/app": "0.9.27",
|
107 |
+
"@firebase/component": "0.6.5",
|
108 |
+
"@firebase/logger": "0.4.0",
|
109 |
+
"@firebase/util": "1.9.4",
|
110 |
+
"tslib": "^2.1.0"
|
111 |
+
}
|
112 |
+
},
|
113 |
+
"node_modules/@firebase/app-types": {
|
114 |
+
"version": "0.9.0",
|
115 |
+
"resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.0.tgz",
|
116 |
+
"integrity": "sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q=="
|
117 |
+
},
|
118 |
+
"node_modules/@firebase/auth": {
|
119 |
+
"version": "1.6.0",
|
120 |
+
"resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.6.0.tgz",
|
121 |
+
"integrity": "sha512-Qhl35eJTV6BwvuueTPCY6x8kUlYyzALtjp/Ws0X3fw3AnjVVfuVb7oQ3Xh5VPVfMFhaIuUAd1KXwcAuIklkSDw==",
|
122 |
+
"dependencies": {
|
123 |
+
"@firebase/component": "0.6.5",
|
124 |
+
"@firebase/logger": "0.4.0",
|
125 |
+
"@firebase/util": "1.9.4",
|
126 |
+
"tslib": "^2.1.0",
|
127 |
+
"undici": "5.26.5"
|
128 |
+
},
|
129 |
+
"peerDependencies": {
|
130 |
+
"@firebase/app": "0.x",
|
131 |
+
"@react-native-async-storage/async-storage": "^1.18.1"
|
132 |
+
},
|
133 |
+
"peerDependenciesMeta": {
|
134 |
+
"@react-native-async-storage/async-storage": {
|
135 |
+
"optional": true
|
136 |
+
}
|
137 |
+
}
|
138 |
+
},
|
139 |
+
"node_modules/@firebase/auth-compat": {
|
140 |
+
"version": "0.5.2",
|
141 |
+
"resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.2.tgz",
|
142 |
+
"integrity": "sha512-pRgje5BPCNR1vXyvGOVXwOHtv88A2WooXfklI8sV7/jWi03ExFqNfpJT26GUo/oD39NoKJ3Kt6rD5gVvdV7lMw==",
|
143 |
+
"dependencies": {
|
144 |
+
"@firebase/auth": "1.6.0",
|
145 |
+
"@firebase/auth-types": "0.12.0",
|
146 |
+
"@firebase/component": "0.6.5",
|
147 |
+
"@firebase/util": "1.9.4",
|
148 |
+
"tslib": "^2.1.0",
|
149 |
+
"undici": "5.26.5"
|
150 |
+
},
|
151 |
+
"peerDependencies": {
|
152 |
+
"@firebase/app-compat": "0.x"
|
153 |
+
}
|
154 |
+
},
|
155 |
+
"node_modules/@firebase/auth-interop-types": {
|
156 |
+
"version": "0.2.1",
|
157 |
+
"resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.1.tgz",
|
158 |
+
"integrity": "sha512-VOaGzKp65MY6P5FI84TfYKBXEPi6LmOCSMMzys6o2BN2LOsqy7pCuZCup7NYnfbk5OkkQKzvIfHOzTm0UDpkyg=="
|
159 |
+
},
|
160 |
+
"node_modules/@firebase/auth-types": {
|
161 |
+
"version": "0.12.0",
|
162 |
+
"resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.0.tgz",
|
163 |
+
"integrity": "sha512-pPwaZt+SPOshK8xNoiQlK5XIrS97kFYc3Rc7xmy373QsOJ9MmqXxLaYssP5Kcds4wd2qK//amx/c+A8O2fVeZA==",
|
164 |
+
"peerDependencies": {
|
165 |
+
"@firebase/app-types": "0.x",
|
166 |
+
"@firebase/util": "1.x"
|
167 |
+
}
|
168 |
+
},
|
169 |
+
"node_modules/@firebase/component": {
|
170 |
+
"version": "0.6.5",
|
171 |
+
"resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.5.tgz",
|
172 |
+
"integrity": "sha512-2tVDk1ixi12sbDmmfITK8lxSjmcb73BMF6Qwc3U44hN/J1Fi1QY/Hnnb6klFlbB9/G16a3J3d4nXykye2EADTw==",
|
173 |
+
"dependencies": {
|
174 |
+
"@firebase/util": "1.9.4",
|
175 |
+
"tslib": "^2.1.0"
|
176 |
+
}
|
177 |
+
},
|
178 |
+
"node_modules/@firebase/database": {
|
179 |
+
"version": "1.0.3",
|
180 |
+
"resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.3.tgz",
|
181 |
+
"integrity": "sha512-9fjqLt9JzL46gw9+NRqsgQEMjgRwfd8XtzcKqG+UYyhVeFCdVRQ0Wp6Dw/dvYHnbH5vNEKzNv36dcB4p+PIAAA==",
|
182 |
+
"dependencies": {
|
183 |
+
"@firebase/app-check-interop-types": "0.3.0",
|
184 |
+
"@firebase/auth-interop-types": "0.2.1",
|
185 |
+
"@firebase/component": "0.6.5",
|
186 |
+
"@firebase/logger": "0.4.0",
|
187 |
+
"@firebase/util": "1.9.4",
|
188 |
+
"faye-websocket": "0.11.4",
|
189 |
+
"tslib": "^2.1.0"
|
190 |
+
}
|
191 |
+
},
|
192 |
+
"node_modules/@firebase/database-compat": {
|
193 |
+
"version": "1.0.3",
|
194 |
+
"resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-1.0.3.tgz",
|
195 |
+
"integrity": "sha512-7tHEOcMbK5jJzHWyphPux4osogH/adWwncxdMxdBpB9g1DNIyY4dcz1oJdlkXGM/i/AjUBesZsd5CuwTRTBNTw==",
|
196 |
+
"dependencies": {
|
197 |
+
"@firebase/component": "0.6.5",
|
198 |
+
"@firebase/database": "1.0.3",
|
199 |
+
"@firebase/database-types": "1.0.1",
|
200 |
+
"@firebase/logger": "0.4.0",
|
201 |
+
"@firebase/util": "1.9.4",
|
202 |
+
"tslib": "^2.1.0"
|
203 |
+
}
|
204 |
+
},
|
205 |
+
"node_modules/@firebase/database-types": {
|
206 |
+
"version": "1.0.1",
|
207 |
+
"resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.1.tgz",
|
208 |
+
"integrity": "sha512-Tmcmx5XgiI7UVF/4oGg2P3AOTfq3WKEPsm2yf+uXtN7uG/a4WTWhVMrXGYRY2ZUL1xPxv9V33wQRJ+CcrUhVXw==",
|
209 |
+
"dependencies": {
|
210 |
+
"@firebase/app-types": "0.9.0",
|
211 |
+
"@firebase/util": "1.9.4"
|
212 |
+
}
|
213 |
+
},
|
214 |
+
"node_modules/@firebase/firestore": {
|
215 |
+
"version": "4.4.2",
|
216 |
+
"resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.4.2.tgz",
|
217 |
+
"integrity": "sha512-YaX6ypa/RzU6OkxzUQlpSxwhOIWdTraCNz7sMsbaSEjjl/pj/QvX6TqjkdWGzuBYh2S6rz7ErhDO0g39oZZw/g==",
|
218 |
+
"dependencies": {
|
219 |
+
"@firebase/component": "0.6.5",
|
220 |
+
"@firebase/logger": "0.4.0",
|
221 |
+
"@firebase/util": "1.9.4",
|
222 |
+
"@firebase/webchannel-wrapper": "0.10.5",
|
223 |
+
"@grpc/grpc-js": "~1.9.0",
|
224 |
+
"@grpc/proto-loader": "^0.7.8",
|
225 |
+
"tslib": "^2.1.0",
|
226 |
+
"undici": "5.26.5"
|
227 |
+
},
|
228 |
+
"engines": {
|
229 |
+
"node": ">=10.10.0"
|
230 |
+
},
|
231 |
+
"peerDependencies": {
|
232 |
+
"@firebase/app": "0.x"
|
233 |
+
}
|
234 |
+
},
|
235 |
+
"node_modules/@firebase/firestore-compat": {
|
236 |
+
"version": "0.3.25",
|
237 |
+
"resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.25.tgz",
|
238 |
+
"integrity": "sha512-+xI7WmsgZCBhMn/+uhDKcg+lsOUJ9FJyt5PGTzkFPbCsozWfeQZ7eVnfPh0rMkUOf0yIQ924RIe04gwvEIbcoQ==",
|
239 |
+
"dependencies": {
|
240 |
+
"@firebase/component": "0.6.5",
|
241 |
+
"@firebase/firestore": "4.4.2",
|
242 |
+
"@firebase/firestore-types": "3.0.0",
|
243 |
+
"@firebase/util": "1.9.4",
|
244 |
+
"tslib": "^2.1.0"
|
245 |
+
},
|
246 |
+
"peerDependencies": {
|
247 |
+
"@firebase/app-compat": "0.x"
|
248 |
+
}
|
249 |
+
},
|
250 |
+
"node_modules/@firebase/firestore-types": {
|
251 |
+
"version": "3.0.0",
|
252 |
+
"resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.0.tgz",
|
253 |
+
"integrity": "sha512-Meg4cIezHo9zLamw0ymFYBD4SMjLb+ZXIbuN7T7ddXN6MGoICmOTq3/ltdCGoDCS2u+H1XJs2u/cYp75jsX9Qw==",
|
254 |
+
"peerDependencies": {
|
255 |
+
"@firebase/app-types": "0.x",
|
256 |
+
"@firebase/util": "1.x"
|
257 |
+
}
|
258 |
+
},
|
259 |
+
"node_modules/@firebase/functions": {
|
260 |
+
"version": "0.11.1",
|
261 |
+
"resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.11.1.tgz",
|
262 |
+
"integrity": "sha512-3uUa1hB79Gmy6E1gHTfzoHeZolBeHc/I/n3+lOCDe6BOos9AHmzRjKygcFE/7VA2FJjitCE0K+OHI6+OuoY8fQ==",
|
263 |
+
"dependencies": {
|
264 |
+
"@firebase/app-check-interop-types": "0.3.0",
|
265 |
+
"@firebase/auth-interop-types": "0.2.1",
|
266 |
+
"@firebase/component": "0.6.5",
|
267 |
+
"@firebase/messaging-interop-types": "0.2.0",
|
268 |
+
"@firebase/util": "1.9.4",
|
269 |
+
"tslib": "^2.1.0",
|
270 |
+
"undici": "5.26.5"
|
271 |
+
},
|
272 |
+
"peerDependencies": {
|
273 |
+
"@firebase/app": "0.x"
|
274 |
+
}
|
275 |
+
},
|
276 |
+
"node_modules/@firebase/functions-compat": {
|
277 |
+
"version": "0.3.7",
|
278 |
+
"resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.7.tgz",
|
279 |
+
"integrity": "sha512-uXe6Kmku5lNogp3OpPBcOJbSvnaCOn+YxS3zlXKNU6Q/NLwcvO3RY1zwYyctCos2RemEw3KEQ7YdzcECXjHWLw==",
|
280 |
+
"dependencies": {
|
281 |
+
"@firebase/component": "0.6.5",
|
282 |
+
"@firebase/functions": "0.11.1",
|
283 |
+
"@firebase/functions-types": "0.6.0",
|
284 |
+
"@firebase/util": "1.9.4",
|
285 |
+
"tslib": "^2.1.0"
|
286 |
+
},
|
287 |
+
"peerDependencies": {
|
288 |
+
"@firebase/app-compat": "0.x"
|
289 |
+
}
|
290 |
+
},
|
291 |
+
"node_modules/@firebase/functions-types": {
|
292 |
+
"version": "0.6.0",
|
293 |
+
"resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.0.tgz",
|
294 |
+
"integrity": "sha512-hfEw5VJtgWXIRf92ImLkgENqpL6IWpYaXVYiRkFY1jJ9+6tIhWM7IzzwbevwIIud/jaxKVdRzD7QBWfPmkwCYw=="
|
295 |
+
},
|
296 |
+
"node_modules/@firebase/installations": {
|
297 |
+
"version": "0.6.5",
|
298 |
+
"resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.5.tgz",
|
299 |
+
"integrity": "sha512-0xxnQWw8rSRzu0ZOCkZaO+MJ0LkDAfwwTB2Z1SxRK6FAz5xkxD1ZUwM0WbCRni49PKubCrZYOJ6yg7tSjU7AKA==",
|
300 |
+
"dependencies": {
|
301 |
+
"@firebase/component": "0.6.5",
|
302 |
+
"@firebase/util": "1.9.4",
|
303 |
+
"idb": "7.1.1",
|
304 |
+
"tslib": "^2.1.0"
|
305 |
+
},
|
306 |
+
"peerDependencies": {
|
307 |
+
"@firebase/app": "0.x"
|
308 |
+
}
|
309 |
+
},
|
310 |
+
"node_modules/@firebase/installations-compat": {
|
311 |
+
"version": "0.2.5",
|
312 |
+
"resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.5.tgz",
|
313 |
+
"integrity": "sha512-usvoIaog5CHEw082HXLrKAZ1qd4hIC3N/LDe2NqBgI3pkGE/7auLVM4Gn5gvyryp0x8z/IP1+d9fkGUj2OaGLQ==",
|
314 |
+
"dependencies": {
|
315 |
+
"@firebase/component": "0.6.5",
|
316 |
+
"@firebase/installations": "0.6.5",
|
317 |
+
"@firebase/installations-types": "0.5.0",
|
318 |
+
"@firebase/util": "1.9.4",
|
319 |
+
"tslib": "^2.1.0"
|
320 |
+
},
|
321 |
+
"peerDependencies": {
|
322 |
+
"@firebase/app-compat": "0.x"
|
323 |
+
}
|
324 |
+
},
|
325 |
+
"node_modules/@firebase/installations-types": {
|
326 |
+
"version": "0.5.0",
|
327 |
+
"resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.0.tgz",
|
328 |
+
"integrity": "sha512-9DP+RGfzoI2jH7gY4SlzqvZ+hr7gYzPODrbzVD82Y12kScZ6ZpRg/i3j6rleto8vTFC8n6Len4560FnV1w2IRg==",
|
329 |
+
"peerDependencies": {
|
330 |
+
"@firebase/app-types": "0.x"
|
331 |
+
}
|
332 |
+
},
|
333 |
+
"node_modules/@firebase/logger": {
|
334 |
+
"version": "0.4.0",
|
335 |
+
"resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.0.tgz",
|
336 |
+
"integrity": "sha512-eRKSeykumZ5+cJPdxxJRgAC3G5NknY2GwEbKfymdnXtnT0Ucm4pspfR6GT4MUQEDuJwRVbVcSx85kgJulMoFFA==",
|
337 |
+
"dependencies": {
|
338 |
+
"tslib": "^2.1.0"
|
339 |
+
}
|
340 |
+
},
|
341 |
+
"node_modules/@firebase/messaging": {
|
342 |
+
"version": "0.12.6",
|
343 |
+
"resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.6.tgz",
|
344 |
+
"integrity": "sha512-IORsPp9IPWq4j4yEhTOZ6GAGi3gQwGc+4yexmTAlya+qeBRSdRnJg2iIU/aj+tcKDQYr9RQuQPgHHOdFIx//vA==",
|
345 |
+
"dependencies": {
|
346 |
+
"@firebase/component": "0.6.5",
|
347 |
+
"@firebase/installations": "0.6.5",
|
348 |
+
"@firebase/messaging-interop-types": "0.2.0",
|
349 |
+
"@firebase/util": "1.9.4",
|
350 |
+
"idb": "7.1.1",
|
351 |
+
"tslib": "^2.1.0"
|
352 |
+
},
|
353 |
+
"peerDependencies": {
|
354 |
+
"@firebase/app": "0.x"
|
355 |
+
}
|
356 |
+
},
|
357 |
+
"node_modules/@firebase/messaging-compat": {
|
358 |
+
"version": "0.2.6",
|
359 |
+
"resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.6.tgz",
|
360 |
+
"integrity": "sha512-Q2xC1s4L7Vpss7P7Gy6GuIS+xmJrf/vm9+gX76IK1Bo1TjoKwleCLHt1LHkPz5Rvqg5pTgzzI8qqPhBpZosFCg==",
|
361 |
+
"dependencies": {
|
362 |
+
"@firebase/component": "0.6.5",
|
363 |
+
"@firebase/messaging": "0.12.6",
|
364 |
+
"@firebase/util": "1.9.4",
|
365 |
+
"tslib": "^2.1.0"
|
366 |
+
},
|
367 |
+
"peerDependencies": {
|
368 |
+
"@firebase/app-compat": "0.x"
|
369 |
+
}
|
370 |
+
},
|
371 |
+
"node_modules/@firebase/messaging-interop-types": {
|
372 |
+
"version": "0.2.0",
|
373 |
+
"resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.0.tgz",
|
374 |
+
"integrity": "sha512-ujA8dcRuVeBixGR9CtegfpU4YmZf3Lt7QYkcj693FFannwNuZgfAYaTmbJ40dtjB81SAu6tbFPL9YLNT15KmOQ=="
|
375 |
+
},
|
376 |
+
"node_modules/@firebase/performance": {
|
377 |
+
"version": "0.6.5",
|
378 |
+
"resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.6.5.tgz",
|
379 |
+
"integrity": "sha512-OzAGcWhOqEFH9GdwUuY0oC5FSlnMejcnmSAhR+EjpI7exdDvixyLyCR4txjSHYNTbumrFBG+EP8GO11CNXRaJA==",
|
380 |
+
"dependencies": {
|
381 |
+
"@firebase/component": "0.6.5",
|
382 |
+
"@firebase/installations": "0.6.5",
|
383 |
+
"@firebase/logger": "0.4.0",
|
384 |
+
"@firebase/util": "1.9.4",
|
385 |
+
"tslib": "^2.1.0"
|
386 |
+
},
|
387 |
+
"peerDependencies": {
|
388 |
+
"@firebase/app": "0.x"
|
389 |
+
}
|
390 |
+
},
|
391 |
+
"node_modules/@firebase/performance-compat": {
|
392 |
+
"version": "0.2.5",
|
393 |
+
"resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.5.tgz",
|
394 |
+
"integrity": "sha512-jJwJkVyDcIMBaVGrZ6CRGs4m5FCZsWB5QCWYI3FdsHyIa9/TfteNDilxj9wGciF2naFIHDW7TgE69U5dAH9Ktg==",
|
395 |
+
"dependencies": {
|
396 |
+
"@firebase/component": "0.6.5",
|
397 |
+
"@firebase/logger": "0.4.0",
|
398 |
+
"@firebase/performance": "0.6.5",
|
399 |
+
"@firebase/performance-types": "0.2.0",
|
400 |
+
"@firebase/util": "1.9.4",
|
401 |
+
"tslib": "^2.1.0"
|
402 |
+
},
|
403 |
+
"peerDependencies": {
|
404 |
+
"@firebase/app-compat": "0.x"
|
405 |
+
}
|
406 |
+
},
|
407 |
+
"node_modules/@firebase/performance-types": {
|
408 |
+
"version": "0.2.0",
|
409 |
+
"resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.0.tgz",
|
410 |
+
"integrity": "sha512-kYrbr8e/CYr1KLrLYZZt2noNnf+pRwDq2KK9Au9jHrBMnb0/C9X9yWSXmZkFt4UIdsQknBq8uBB7fsybZdOBTA=="
|
411 |
+
},
|
412 |
+
"node_modules/@firebase/remote-config": {
|
413 |
+
"version": "0.4.5",
|
414 |
+
"resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.4.5.tgz",
|
415 |
+
"integrity": "sha512-rGLqc/4OmxrS39RA9kgwa6JmgWytQuMo+B8pFhmGp3d++x2Hf9j+MLQfhOLyyUo64fNw20J19mLXhrXvKHsjZQ==",
|
416 |
+
"dependencies": {
|
417 |
+
"@firebase/component": "0.6.5",
|
418 |
+
"@firebase/installations": "0.6.5",
|
419 |
+
"@firebase/logger": "0.4.0",
|
420 |
+
"@firebase/util": "1.9.4",
|
421 |
+
"tslib": "^2.1.0"
|
422 |
+
},
|
423 |
+
"peerDependencies": {
|
424 |
+
"@firebase/app": "0.x"
|
425 |
+
}
|
426 |
+
},
|
427 |
+
"node_modules/@firebase/remote-config-compat": {
|
428 |
+
"version": "0.2.5",
|
429 |
+
"resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.5.tgz",
|
430 |
+
"integrity": "sha512-ImkNnLuGrD/bylBHDJigSY6LMwRrwt37wQbsGZhWG4QQ6KLzHzSf0nnFRRFvkOZodEUE57Ib8l74d6Yn/6TDUQ==",
|
431 |
+
"dependencies": {
|
432 |
+
"@firebase/component": "0.6.5",
|
433 |
+
"@firebase/logger": "0.4.0",
|
434 |
+
"@firebase/remote-config": "0.4.5",
|
435 |
+
"@firebase/remote-config-types": "0.3.0",
|
436 |
+
"@firebase/util": "1.9.4",
|
437 |
+
"tslib": "^2.1.0"
|
438 |
+
},
|
439 |
+
"peerDependencies": {
|
440 |
+
"@firebase/app-compat": "0.x"
|
441 |
+
}
|
442 |
+
},
|
443 |
+
"node_modules/@firebase/remote-config-types": {
|
444 |
+
"version": "0.3.0",
|
445 |
+
"resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.3.0.tgz",
|
446 |
+
"integrity": "sha512-RtEH4vdcbXZuZWRZbIRmQVBNsE7VDQpet2qFvq6vwKLBIQRQR5Kh58M4ok3A3US8Sr3rubYnaGqZSurCwI8uMA=="
|
447 |
+
},
|
448 |
+
"node_modules/@firebase/storage": {
|
449 |
+
"version": "0.12.1",
|
450 |
+
"resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.12.1.tgz",
|
451 |
+
"integrity": "sha512-KJ5NV7FUh54TeTlEjdkTTX60ciCKOp9EqlbLnpdcXUYRJg0Z4810TXbilPc1z7fTIG4iPjtdi95bGE9n4dBX8A==",
|
452 |
+
"dependencies": {
|
453 |
+
"@firebase/component": "0.6.5",
|
454 |
+
"@firebase/util": "1.9.4",
|
455 |
+
"tslib": "^2.1.0",
|
456 |
+
"undici": "5.26.5"
|
457 |
+
},
|
458 |
+
"peerDependencies": {
|
459 |
+
"@firebase/app": "0.x"
|
460 |
+
}
|
461 |
+
},
|
462 |
+
"node_modules/@firebase/storage-compat": {
|
463 |
+
"version": "0.3.4",
|
464 |
+
"resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.4.tgz",
|
465 |
+
"integrity": "sha512-Y0m5e2gS/wB9Ioth2X/Sgz76vcxvqgQrCmfa9qwhss/N31kxY2Gks6Frv0nrE18AjVfcSmcfDitqUwxcMOTRSg==",
|
466 |
+
"dependencies": {
|
467 |
+
"@firebase/component": "0.6.5",
|
468 |
+
"@firebase/storage": "0.12.1",
|
469 |
+
"@firebase/storage-types": "0.8.0",
|
470 |
+
"@firebase/util": "1.9.4",
|
471 |
+
"tslib": "^2.1.0"
|
472 |
+
},
|
473 |
+
"peerDependencies": {
|
474 |
+
"@firebase/app-compat": "0.x"
|
475 |
+
}
|
476 |
+
},
|
477 |
+
"node_modules/@firebase/storage-types": {
|
478 |
+
"version": "0.8.0",
|
479 |
+
"resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.0.tgz",
|
480 |
+
"integrity": "sha512-isRHcGrTs9kITJC0AVehHfpraWFui39MPaU7Eo8QfWlqW7YPymBmRgjDrlOgFdURh6Cdeg07zmkLP5tzTKRSpg==",
|
481 |
+
"peerDependencies": {
|
482 |
+
"@firebase/app-types": "0.x",
|
483 |
+
"@firebase/util": "1.x"
|
484 |
+
}
|
485 |
+
},
|
486 |
+
"node_modules/@firebase/util": {
|
487 |
+
"version": "1.9.4",
|
488 |
+
"resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.4.tgz",
|
489 |
+
"integrity": "sha512-WLonYmS1FGHT97TsUmRN3qnTh5TeeoJp1Gg5fithzuAgdZOUtsYECfy7/noQ3llaguios8r5BuXSEiK82+UrxQ==",
|
490 |
+
"dependencies": {
|
491 |
+
"tslib": "^2.1.0"
|
492 |
+
}
|
493 |
+
},
|
494 |
+
"node_modules/@firebase/webchannel-wrapper": {
|
495 |
+
"version": "0.10.5",
|
496 |
+
"resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.10.5.tgz",
|
497 |
+
"integrity": "sha512-eSkJsnhBWv5kCTSU1tSUVl9mpFu+5NXXunZc83le8GMjMlsWwQArSc7cJJ4yl+aDFY0NGLi0AjZWMn1axOrkRg=="
|
498 |
+
},
|
499 |
+
"node_modules/@grpc/grpc-js": {
|
500 |
+
"version": "1.9.14",
|
501 |
+
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.14.tgz",
|
502 |
+
"integrity": "sha512-nOpuzZ2G3IuMFN+UPPpKrC6NsLmWsTqSsm66IRfnBt1D4pwTqE27lmbpcPM+l2Ua4gE7PfjRHI6uedAy7hoXUw==",
|
503 |
+
"dependencies": {
|
504 |
+
"@grpc/proto-loader": "^0.7.8",
|
505 |
+
"@types/node": ">=12.12.47"
|
506 |
+
},
|
507 |
+
"engines": {
|
508 |
+
"node": "^8.13.0 || >=10.10.0"
|
509 |
+
}
|
510 |
+
},
|
511 |
+
"node_modules/@grpc/proto-loader": {
|
512 |
+
"version": "0.7.10",
|
513 |
+
"resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.10.tgz",
|
514 |
+
"integrity": "sha512-CAqDfoaQ8ykFd9zqBDn4k6iWT9loLAlc2ETmDFS9JCD70gDcnA4L3AFEo2iV7KyAtAAHFW9ftq1Fz+Vsgq80RQ==",
|
515 |
+
"dependencies": {
|
516 |
+
"lodash.camelcase": "^4.3.0",
|
517 |
+
"long": "^5.0.0",
|
518 |
+
"protobufjs": "^7.2.4",
|
519 |
+
"yargs": "^17.7.2"
|
520 |
+
},
|
521 |
+
"bin": {
|
522 |
+
"proto-loader-gen-types": "build/bin/proto-loader-gen-types.js"
|
523 |
+
},
|
524 |
+
"engines": {
|
525 |
+
"node": ">=6"
|
526 |
+
}
|
527 |
+
},
|
528 |
+
"node_modules/@kurkle/color": {
|
529 |
+
"version": "0.3.2",
|
530 |
+
"resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz",
|
531 |
+
"integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw=="
|
532 |
+
},
|
533 |
+
"node_modules/@protobufjs/aspromise": {
|
534 |
+
"version": "1.1.2",
|
535 |
+
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
536 |
+
"integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
|
537 |
+
},
|
538 |
+
"node_modules/@protobufjs/base64": {
|
539 |
+
"version": "1.1.2",
|
540 |
+
"resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
|
541 |
+
"integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
|
542 |
+
},
|
543 |
+
"node_modules/@protobufjs/codegen": {
|
544 |
+
"version": "2.0.4",
|
545 |
+
"resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
|
546 |
+
"integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
|
547 |
+
},
|
548 |
+
"node_modules/@protobufjs/eventemitter": {
|
549 |
+
"version": "1.1.0",
|
550 |
+
"resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
|
551 |
+
"integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="
|
552 |
+
},
|
553 |
+
"node_modules/@protobufjs/fetch": {
|
554 |
+
"version": "1.1.0",
|
555 |
+
"resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
|
556 |
+
"integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
|
557 |
+
"dependencies": {
|
558 |
+
"@protobufjs/aspromise": "^1.1.1",
|
559 |
+
"@protobufjs/inquire": "^1.1.0"
|
560 |
+
}
|
561 |
+
},
|
562 |
+
"node_modules/@protobufjs/float": {
|
563 |
+
"version": "1.0.2",
|
564 |
+
"resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
|
565 |
+
"integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
|
566 |
+
},
|
567 |
+
"node_modules/@protobufjs/inquire": {
|
568 |
+
"version": "1.1.0",
|
569 |
+
"resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
|
570 |
+
"integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="
|
571 |
+
},
|
572 |
+
"node_modules/@protobufjs/path": {
|
573 |
+
"version": "1.1.2",
|
574 |
+
"resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
|
575 |
+
"integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
|
576 |
+
},
|
577 |
+
"node_modules/@protobufjs/pool": {
|
578 |
+
"version": "1.1.0",
|
579 |
+
"resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
|
580 |
+
"integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
|
581 |
+
},
|
582 |
+
"node_modules/@protobufjs/utf8": {
|
583 |
+
"version": "1.1.0",
|
584 |
+
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
585 |
+
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
|
586 |
+
},
|
587 |
+
"node_modules/@types/node": {
|
588 |
+
"version": "20.11.19",
|
589 |
+
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz",
|
590 |
+
"integrity": "sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==",
|
591 |
+
"dependencies": {
|
592 |
+
"undici-types": "~5.26.4"
|
593 |
+
}
|
594 |
+
},
|
595 |
+
"node_modules/ansi-regex": {
|
596 |
+
"version": "5.0.1",
|
597 |
+
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
598 |
+
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
599 |
+
"engines": {
|
600 |
+
"node": ">=8"
|
601 |
+
}
|
602 |
+
},
|
603 |
+
"node_modules/ansi-styles": {
|
604 |
+
"version": "4.3.0",
|
605 |
+
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
606 |
+
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
607 |
+
"dependencies": {
|
608 |
+
"color-convert": "^2.0.1"
|
609 |
+
},
|
610 |
+
"engines": {
|
611 |
+
"node": ">=8"
|
612 |
+
},
|
613 |
+
"funding": {
|
614 |
+
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
615 |
+
}
|
616 |
+
},
|
617 |
+
"node_modules/chart.js": {
|
618 |
+
"version": "4.4.1",
|
619 |
+
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.1.tgz",
|
620 |
+
"integrity": "sha512-C74QN1bxwV1v2PEujhmKjOZ7iUM4w6BWs23Md/6aOZZSlwMzeCIDGuZay++rBgChYru7/+QFeoQW0fQoP534Dg==",
|
621 |
+
"dependencies": {
|
622 |
+
"@kurkle/color": "^0.3.0"
|
623 |
+
},
|
624 |
+
"engines": {
|
625 |
+
"pnpm": ">=7"
|
626 |
+
}
|
627 |
+
},
|
628 |
+
"node_modules/cliui": {
|
629 |
+
"version": "8.0.1",
|
630 |
+
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
631 |
+
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
632 |
+
"dependencies": {
|
633 |
+
"string-width": "^4.2.0",
|
634 |
+
"strip-ansi": "^6.0.1",
|
635 |
+
"wrap-ansi": "^7.0.0"
|
636 |
+
},
|
637 |
+
"engines": {
|
638 |
+
"node": ">=12"
|
639 |
+
}
|
640 |
+
},
|
641 |
+
"node_modules/color-convert": {
|
642 |
+
"version": "2.0.1",
|
643 |
+
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
644 |
+
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
645 |
+
"dependencies": {
|
646 |
+
"color-name": "~1.1.4"
|
647 |
+
},
|
648 |
+
"engines": {
|
649 |
+
"node": ">=7.0.0"
|
650 |
+
}
|
651 |
+
},
|
652 |
+
"node_modules/color-name": {
|
653 |
+
"version": "1.1.4",
|
654 |
+
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
655 |
+
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
656 |
+
},
|
657 |
+
"node_modules/emoji-regex": {
|
658 |
+
"version": "8.0.0",
|
659 |
+
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
660 |
+
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
661 |
+
},
|
662 |
+
"node_modules/escalade": {
|
663 |
+
"version": "3.1.2",
|
664 |
+
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
|
665 |
+
"integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
|
666 |
+
"engines": {
|
667 |
+
"node": ">=6"
|
668 |
+
}
|
669 |
+
},
|
670 |
+
"node_modules/faye-websocket": {
|
671 |
+
"version": "0.11.4",
|
672 |
+
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz",
|
673 |
+
"integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==",
|
674 |
+
"dependencies": {
|
675 |
+
"websocket-driver": ">=0.5.1"
|
676 |
+
},
|
677 |
+
"engines": {
|
678 |
+
"node": ">=0.8.0"
|
679 |
+
}
|
680 |
+
},
|
681 |
+
"node_modules/firebase": {
|
682 |
+
"version": "10.8.0",
|
683 |
+
"resolved": "https://registry.npmjs.org/firebase/-/firebase-10.8.0.tgz",
|
684 |
+
"integrity": "sha512-UJpC24vw8JFuHEOQyArBGKTUd7+kohLISCzHyn0M/prP0KOTx2io1eyLliEid330QqnWI7FOlPxoU97qecCSfQ==",
|
685 |
+
"dependencies": {
|
686 |
+
"@firebase/analytics": "0.10.1",
|
687 |
+
"@firebase/analytics-compat": "0.2.7",
|
688 |
+
"@firebase/app": "0.9.27",
|
689 |
+
"@firebase/app-check": "0.8.2",
|
690 |
+
"@firebase/app-check-compat": "0.3.9",
|
691 |
+
"@firebase/app-compat": "0.2.27",
|
692 |
+
"@firebase/app-types": "0.9.0",
|
693 |
+
"@firebase/auth": "1.6.0",
|
694 |
+
"@firebase/auth-compat": "0.5.2",
|
695 |
+
"@firebase/database": "1.0.3",
|
696 |
+
"@firebase/database-compat": "1.0.3",
|
697 |
+
"@firebase/firestore": "4.4.2",
|
698 |
+
"@firebase/firestore-compat": "0.3.25",
|
699 |
+
"@firebase/functions": "0.11.1",
|
700 |
+
"@firebase/functions-compat": "0.3.7",
|
701 |
+
"@firebase/installations": "0.6.5",
|
702 |
+
"@firebase/installations-compat": "0.2.5",
|
703 |
+
"@firebase/messaging": "0.12.6",
|
704 |
+
"@firebase/messaging-compat": "0.2.6",
|
705 |
+
"@firebase/performance": "0.6.5",
|
706 |
+
"@firebase/performance-compat": "0.2.5",
|
707 |
+
"@firebase/remote-config": "0.4.5",
|
708 |
+
"@firebase/remote-config-compat": "0.2.5",
|
709 |
+
"@firebase/storage": "0.12.1",
|
710 |
+
"@firebase/storage-compat": "0.3.4",
|
711 |
+
"@firebase/util": "1.9.4"
|
712 |
+
}
|
713 |
+
},
|
714 |
+
"node_modules/get-caller-file": {
|
715 |
+
"version": "2.0.5",
|
716 |
+
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
717 |
+
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
718 |
+
"engines": {
|
719 |
+
"node": "6.* || 8.* || >= 10.*"
|
720 |
+
}
|
721 |
+
},
|
722 |
+
"node_modules/http-parser-js": {
|
723 |
+
"version": "0.5.8",
|
724 |
+
"resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz",
|
725 |
+
"integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q=="
|
726 |
+
},
|
727 |
+
"node_modules/idb": {
|
728 |
+
"version": "7.1.1",
|
729 |
+
"resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz",
|
730 |
+
"integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ=="
|
731 |
+
},
|
732 |
+
"node_modules/is-fullwidth-code-point": {
|
733 |
+
"version": "3.0.0",
|
734 |
+
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
735 |
+
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
736 |
+
"engines": {
|
737 |
+
"node": ">=8"
|
738 |
+
}
|
739 |
+
},
|
740 |
+
"node_modules/js-tokens": {
|
741 |
+
"version": "4.0.0",
|
742 |
+
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
743 |
+
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
744 |
+
"peer": true
|
745 |
+
},
|
746 |
+
"node_modules/lodash.camelcase": {
|
747 |
+
"version": "4.3.0",
|
748 |
+
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
749 |
+
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="
|
750 |
+
},
|
751 |
+
"node_modules/long": {
|
752 |
+
"version": "5.2.3",
|
753 |
+
"resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
|
754 |
+
"integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q=="
|
755 |
+
},
|
756 |
+
"node_modules/loose-envify": {
|
757 |
+
"version": "1.4.0",
|
758 |
+
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
759 |
+
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
760 |
+
"peer": true,
|
761 |
+
"dependencies": {
|
762 |
+
"js-tokens": "^3.0.0 || ^4.0.0"
|
763 |
+
},
|
764 |
+
"bin": {
|
765 |
+
"loose-envify": "cli.js"
|
766 |
+
}
|
767 |
+
},
|
768 |
+
"node_modules/protobufjs": {
|
769 |
+
"version": "7.2.6",
|
770 |
+
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.6.tgz",
|
771 |
+
"integrity": "sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==",
|
772 |
+
"hasInstallScript": true,
|
773 |
+
"dependencies": {
|
774 |
+
"@protobufjs/aspromise": "^1.1.2",
|
775 |
+
"@protobufjs/base64": "^1.1.2",
|
776 |
+
"@protobufjs/codegen": "^2.0.4",
|
777 |
+
"@protobufjs/eventemitter": "^1.1.0",
|
778 |
+
"@protobufjs/fetch": "^1.1.0",
|
779 |
+
"@protobufjs/float": "^1.0.2",
|
780 |
+
"@protobufjs/inquire": "^1.1.0",
|
781 |
+
"@protobufjs/path": "^1.1.2",
|
782 |
+
"@protobufjs/pool": "^1.1.0",
|
783 |
+
"@protobufjs/utf8": "^1.1.0",
|
784 |
+
"@types/node": ">=13.7.0",
|
785 |
+
"long": "^5.0.0"
|
786 |
+
},
|
787 |
+
"engines": {
|
788 |
+
"node": ">=12.0.0"
|
789 |
+
}
|
790 |
+
},
|
791 |
+
"node_modules/react": {
|
792 |
+
"version": "18.2.0",
|
793 |
+
"resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
|
794 |
+
"integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
|
795 |
+
"peer": true,
|
796 |
+
"dependencies": {
|
797 |
+
"loose-envify": "^1.1.0"
|
798 |
+
},
|
799 |
+
"engines": {
|
800 |
+
"node": ">=0.10.0"
|
801 |
+
}
|
802 |
+
},
|
803 |
+
"node_modules/react-chartjs-2": {
|
804 |
+
"version": "5.2.0",
|
805 |
+
"resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.2.0.tgz",
|
806 |
+
"integrity": "sha512-98iN5aguJyVSxp5U3CblRLH67J8gkfyGNbiK3c+l1QI/G4irHMPQw44aEPmjVag+YKTyQ260NcF82GTQ3bdscA==",
|
807 |
+
"peerDependencies": {
|
808 |
+
"chart.js": "^4.1.1",
|
809 |
+
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
810 |
+
}
|
811 |
+
},
|
812 |
+
"node_modules/require-directory": {
|
813 |
+
"version": "2.1.1",
|
814 |
+
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
815 |
+
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
|
816 |
+
"engines": {
|
817 |
+
"node": ">=0.10.0"
|
818 |
+
}
|
819 |
+
},
|
820 |
+
"node_modules/safe-buffer": {
|
821 |
+
"version": "5.2.1",
|
822 |
+
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
823 |
+
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
824 |
+
"funding": [
|
825 |
+
{
|
826 |
+
"type": "github",
|
827 |
+
"url": "https://github.com/sponsors/feross"
|
828 |
+
},
|
829 |
+
{
|
830 |
+
"type": "patreon",
|
831 |
+
"url": "https://www.patreon.com/feross"
|
832 |
+
},
|
833 |
+
{
|
834 |
+
"type": "consulting",
|
835 |
+
"url": "https://feross.org/support"
|
836 |
+
}
|
837 |
+
]
|
838 |
+
},
|
839 |
+
"node_modules/string-width": {
|
840 |
+
"version": "4.2.3",
|
841 |
+
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
842 |
+
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
843 |
+
"dependencies": {
|
844 |
+
"emoji-regex": "^8.0.0",
|
845 |
+
"is-fullwidth-code-point": "^3.0.0",
|
846 |
+
"strip-ansi": "^6.0.1"
|
847 |
+
},
|
848 |
+
"engines": {
|
849 |
+
"node": ">=8"
|
850 |
+
}
|
851 |
+
},
|
852 |
+
"node_modules/strip-ansi": {
|
853 |
+
"version": "6.0.1",
|
854 |
+
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
855 |
+
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
856 |
+
"dependencies": {
|
857 |
+
"ansi-regex": "^5.0.1"
|
858 |
+
},
|
859 |
+
"engines": {
|
860 |
+
"node": ">=8"
|
861 |
+
}
|
862 |
+
},
|
863 |
+
"node_modules/tslib": {
|
864 |
+
"version": "2.6.2",
|
865 |
+
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
866 |
+
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
867 |
+
},
|
868 |
+
"node_modules/undici": {
|
869 |
+
"version": "5.26.5",
|
870 |
+
"resolved": "https://registry.npmjs.org/undici/-/undici-5.26.5.tgz",
|
871 |
+
"integrity": "sha512-cSb4bPFd5qgR7qr2jYAi0hlX9n5YKK2ONKkLFkxl+v/9BvC0sOpZjBHDBSXc5lWAf5ty9oZdRXytBIHzgUcerw==",
|
872 |
+
"dependencies": {
|
873 |
+
"@fastify/busboy": "^2.0.0"
|
874 |
+
},
|
875 |
+
"engines": {
|
876 |
+
"node": ">=14.0"
|
877 |
+
}
|
878 |
+
},
|
879 |
+
"node_modules/undici-types": {
|
880 |
+
"version": "5.26.5",
|
881 |
+
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
882 |
+
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
|
883 |
+
},
|
884 |
+
"node_modules/websocket-driver": {
|
885 |
+
"version": "0.7.4",
|
886 |
+
"resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
|
887 |
+
"integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
|
888 |
+
"dependencies": {
|
889 |
+
"http-parser-js": ">=0.5.1",
|
890 |
+
"safe-buffer": ">=5.1.0",
|
891 |
+
"websocket-extensions": ">=0.1.1"
|
892 |
+
},
|
893 |
+
"engines": {
|
894 |
+
"node": ">=0.8.0"
|
895 |
+
}
|
896 |
+
},
|
897 |
+
"node_modules/websocket-extensions": {
|
898 |
+
"version": "0.1.4",
|
899 |
+
"resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
|
900 |
+
"integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
|
901 |
+
"engines": {
|
902 |
+
"node": ">=0.8.0"
|
903 |
+
}
|
904 |
+
},
|
905 |
+
"node_modules/wrap-ansi": {
|
906 |
+
"version": "7.0.0",
|
907 |
+
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
908 |
+
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
909 |
+
"dependencies": {
|
910 |
+
"ansi-styles": "^4.0.0",
|
911 |
+
"string-width": "^4.1.0",
|
912 |
+
"strip-ansi": "^6.0.0"
|
913 |
+
},
|
914 |
+
"engines": {
|
915 |
+
"node": ">=10"
|
916 |
+
},
|
917 |
+
"funding": {
|
918 |
+
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
919 |
+
}
|
920 |
+
},
|
921 |
+
"node_modules/y18n": {
|
922 |
+
"version": "5.0.8",
|
923 |
+
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
924 |
+
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
925 |
+
"engines": {
|
926 |
+
"node": ">=10"
|
927 |
+
}
|
928 |
+
},
|
929 |
+
"node_modules/yargs": {
|
930 |
+
"version": "17.7.2",
|
931 |
+
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
|
932 |
+
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
|
933 |
+
"dependencies": {
|
934 |
+
"cliui": "^8.0.1",
|
935 |
+
"escalade": "^3.1.1",
|
936 |
+
"get-caller-file": "^2.0.5",
|
937 |
+
"require-directory": "^2.1.1",
|
938 |
+
"string-width": "^4.2.3",
|
939 |
+
"y18n": "^5.0.5",
|
940 |
+
"yargs-parser": "^21.1.1"
|
941 |
+
},
|
942 |
+
"engines": {
|
943 |
+
"node": ">=12"
|
944 |
+
}
|
945 |
+
},
|
946 |
+
"node_modules/yargs-parser": {
|
947 |
+
"version": "21.1.1",
|
948 |
+
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
949 |
+
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
950 |
+
"engines": {
|
951 |
+
"node": ">=12"
|
952 |
+
}
|
953 |
+
}
|
954 |
+
}
|
955 |
+
}
|
node_modules/@fastify/busboy/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Copyright Brian White. All rights reserved.
|
2 |
+
|
3 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4 |
+
of this software and associated documentation files (the "Software"), to
|
5 |
+
deal in the Software without restriction, including without limitation the
|
6 |
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
7 |
+
sell copies of the Software, and to permit persons to whom the Software is
|
8 |
+
furnished to do so, subject to the following conditions:
|
9 |
+
|
10 |
+
The above copyright notice and this permission notice shall be included in
|
11 |
+
all copies or substantial portions of the Software.
|
12 |
+
|
13 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
18 |
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
19 |
+
IN THE SOFTWARE.
|
node_modules/@fastify/busboy/README.md
ADDED
@@ -0,0 +1,271 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# busboy
|
2 |
+
|
3 |
+
<div align="center">
|
4 |
+
|
5 |
+
[![Build Status](https://github.com/fastify/busboy/workflows/ci/badge.svg)](https://github.com/fastify/busboy/actions)
|
6 |
+
[![Coverage Status](https://coveralls.io/repos/fastify/busboy/badge.svg?branch=master)](https://coveralls.io/r/fastify/busboy?branch=master)
|
7 |
+
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://standardjs.com/)
|
8 |
+
[![Security Responsible Disclosure](https://img.shields.io/badge/Security-Responsible%20Disclosure-yellow.svg)](https://github.com/nodejs/security-wg/blob/HEAD/processes/responsible_disclosure_template.md)
|
9 |
+
|
10 |
+
</div>
|
11 |
+
|
12 |
+
<div align="center">
|
13 |
+
|
14 |
+
[![NPM version](https://img.shields.io/npm/v/@fastify/busboy.svg?style=flat)](https://www.npmjs.com/package/@fastify/busboy)
|
15 |
+
[![NPM downloads](https://img.shields.io/npm/dm/@fastify/busboy.svg?style=flat)](https://www.npmjs.com/package/@fastify/busboy)
|
16 |
+
|
17 |
+
</div>
|
18 |
+
|
19 |
+
Description
|
20 |
+
===========
|
21 |
+
|
22 |
+
A Node.js module for parsing incoming HTML form data.
|
23 |
+
|
24 |
+
This is an officially supported fork by [fastify](https://github.com/fastify/) organization of the amazing library [originally created](https://github.com/mscdex/busboy) by Brian White,
|
25 |
+
aimed at addressing long-standing issues with it.
|
26 |
+
|
27 |
+
Benchmark (Mean time for 500 Kb payload, 2000 cycles, 1000 cycle warmup):
|
28 |
+
|
29 |
+
| Library | Version | Mean time in nanoseconds (less is better) |
|
30 |
+
|-----------------------|---------|-------------------------------------------|
|
31 |
+
| busboy | 0.3.1 | `340114` |
|
32 |
+
| @fastify/busboy | 1.0.0 | `270984` |
|
33 |
+
|
34 |
+
[Changelog](https://github.com/fastify/busboy/blob/master/CHANGELOG.md) since busboy 0.31.
|
35 |
+
|
36 |
+
Requirements
|
37 |
+
============
|
38 |
+
|
39 |
+
* [Node.js](http://nodejs.org/) 10+
|
40 |
+
|
41 |
+
|
42 |
+
Install
|
43 |
+
=======
|
44 |
+
|
45 |
+
npm i @fastify/busboy
|
46 |
+
|
47 |
+
|
48 |
+
Examples
|
49 |
+
========
|
50 |
+
|
51 |
+
* Parsing (multipart) with default options:
|
52 |
+
|
53 |
+
```javascript
|
54 |
+
const http = require('node:http');
|
55 |
+
const { inspect } = require('node:util');
|
56 |
+
const Busboy = require('busboy');
|
57 |
+
|
58 |
+
http.createServer((req, res) => {
|
59 |
+
if (req.method === 'POST') {
|
60 |
+
const busboy = new Busboy({ headers: req.headers });
|
61 |
+
busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
|
62 |
+
console.log(`File [${fieldname}]: filename: ${filename}, encoding: ${encoding}, mimetype: ${mimetype}`);
|
63 |
+
file.on('data', data => {
|
64 |
+
console.log(`File [${fieldname}] got ${data.length} bytes`);
|
65 |
+
});
|
66 |
+
file.on('end', () => {
|
67 |
+
console.log(`File [${fieldname}] Finished`);
|
68 |
+
});
|
69 |
+
});
|
70 |
+
busboy.on('field', (fieldname, val, fieldnameTruncated, valTruncated, encoding, mimetype) => {
|
71 |
+
console.log(`Field [${fieldname}]: value: ${inspect(val)}`);
|
72 |
+
});
|
73 |
+
busboy.on('finish', () => {
|
74 |
+
console.log('Done parsing form!');
|
75 |
+
res.writeHead(303, { Connection: 'close', Location: '/' });
|
76 |
+
res.end();
|
77 |
+
});
|
78 |
+
req.pipe(busboy);
|
79 |
+
} else if (req.method === 'GET') {
|
80 |
+
res.writeHead(200, { Connection: 'close' });
|
81 |
+
res.end(`<html><head></head><body>
|
82 |
+
<form method="POST" enctype="multipart/form-data">
|
83 |
+
<input type="text" name="textfield"><br>
|
84 |
+
<input type="file" name="filefield"><br>
|
85 |
+
<input type="submit">
|
86 |
+
</form>
|
87 |
+
</body></html>`);
|
88 |
+
}
|
89 |
+
}).listen(8000, () => {
|
90 |
+
console.log('Listening for requests');
|
91 |
+
});
|
92 |
+
|
93 |
+
// Example output, using http://nodejs.org/images/ryan-speaker.jpg as the file:
|
94 |
+
//
|
95 |
+
// Listening for requests
|
96 |
+
// File [filefield]: filename: ryan-speaker.jpg, encoding: binary
|
97 |
+
// File [filefield] got 11971 bytes
|
98 |
+
// Field [textfield]: value: 'testing! :-)'
|
99 |
+
// File [filefield] Finished
|
100 |
+
// Done parsing form!
|
101 |
+
```
|
102 |
+
|
103 |
+
* Save all incoming files to disk:
|
104 |
+
|
105 |
+
```javascript
|
106 |
+
const http = require('node:http');
|
107 |
+
const path = require('node:path');
|
108 |
+
const os = require('node:os');
|
109 |
+
const fs = require('node:fs');
|
110 |
+
|
111 |
+
const Busboy = require('busboy');
|
112 |
+
|
113 |
+
http.createServer(function(req, res) {
|
114 |
+
if (req.method === 'POST') {
|
115 |
+
const busboy = new Busboy({ headers: req.headers });
|
116 |
+
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
|
117 |
+
var saveTo = path.join(os.tmpdir(), path.basename(fieldname));
|
118 |
+
file.pipe(fs.createWriteStream(saveTo));
|
119 |
+
});
|
120 |
+
busboy.on('finish', function() {
|
121 |
+
res.writeHead(200, { 'Connection': 'close' });
|
122 |
+
res.end("That's all folks!");
|
123 |
+
});
|
124 |
+
return req.pipe(busboy);
|
125 |
+
}
|
126 |
+
res.writeHead(404);
|
127 |
+
res.end();
|
128 |
+
}).listen(8000, function() {
|
129 |
+
console.log('Listening for requests');
|
130 |
+
});
|
131 |
+
```
|
132 |
+
|
133 |
+
* Parsing (urlencoded) with default options:
|
134 |
+
|
135 |
+
```javascript
|
136 |
+
const http = require('node:http');
|
137 |
+
const { inspect } = require('node:util');
|
138 |
+
|
139 |
+
const Busboy = require('busboy');
|
140 |
+
|
141 |
+
http.createServer(function(req, res) {
|
142 |
+
if (req.method === 'POST') {
|
143 |
+
const busboy = new Busboy({ headers: req.headers });
|
144 |
+
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
|
145 |
+
console.log('File [' + fieldname + ']: filename: ' + filename);
|
146 |
+
file.on('data', function(data) {
|
147 |
+
console.log('File [' + fieldname + '] got ' + data.length + ' bytes');
|
148 |
+
});
|
149 |
+
file.on('end', function() {
|
150 |
+
console.log('File [' + fieldname + '] Finished');
|
151 |
+
});
|
152 |
+
});
|
153 |
+
busboy.on('field', function(fieldname, val, fieldnameTruncated, valTruncated) {
|
154 |
+
console.log('Field [' + fieldname + ']: value: ' + inspect(val));
|
155 |
+
});
|
156 |
+
busboy.on('finish', function() {
|
157 |
+
console.log('Done parsing form!');
|
158 |
+
res.writeHead(303, { Connection: 'close', Location: '/' });
|
159 |
+
res.end();
|
160 |
+
});
|
161 |
+
req.pipe(busboy);
|
162 |
+
} else if (req.method === 'GET') {
|
163 |
+
res.writeHead(200, { Connection: 'close' });
|
164 |
+
res.end('<html><head></head><body>\
|
165 |
+
<form method="POST">\
|
166 |
+
<input type="text" name="textfield"><br />\
|
167 |
+
<select name="selectfield">\
|
168 |
+
<option value="1">1</option>\
|
169 |
+
<option value="10">10</option>\
|
170 |
+
<option value="100">100</option>\
|
171 |
+
<option value="9001">9001</option>\
|
172 |
+
</select><br />\
|
173 |
+
<input type="checkbox" name="checkfield">Node.js rules!<br />\
|
174 |
+
<input type="submit">\
|
175 |
+
</form>\
|
176 |
+
</body></html>');
|
177 |
+
}
|
178 |
+
}).listen(8000, function() {
|
179 |
+
console.log('Listening for requests');
|
180 |
+
});
|
181 |
+
|
182 |
+
// Example output:
|
183 |
+
//
|
184 |
+
// Listening for requests
|
185 |
+
// Field [textfield]: value: 'testing! :-)'
|
186 |
+
// Field [selectfield]: value: '9001'
|
187 |
+
// Field [checkfield]: value: 'on'
|
188 |
+
// Done parsing form!
|
189 |
+
```
|
190 |
+
|
191 |
+
|
192 |
+
API
|
193 |
+
===
|
194 |
+
|
195 |
+
_Busboy_ is a _Writable_ stream
|
196 |
+
|
197 |
+
Busboy (special) events
|
198 |
+
-----------------------
|
199 |
+
|
200 |
+
* **file**(< _string_ >fieldname, < _ReadableStream_ >stream, < _string_ >filename, < _string_ >transferEncoding, < _string_ >mimeType) - Emitted for each new file form field found. `transferEncoding` contains the 'Content-Transfer-Encoding' value for the file stream. `mimeType` contains the 'Content-Type' value for the file stream.
|
201 |
+
* Note: if you listen for this event, you should always handle the `stream` no matter if you care about the file contents or not (e.g. you can simply just do `stream.resume();` if you want to discard the contents), otherwise the 'finish' event will never fire on the Busboy instance. However, if you don't care about **any** incoming files, you can simply not listen for the 'file' event at all and any/all files will be automatically and safely discarded (these discarded files do still count towards `files` and `parts` limits).
|
202 |
+
* If a configured file size limit was reached, `stream` will both have a boolean property `truncated` (best checked at the end of the stream) and emit a 'limit' event to notify you when this happens.
|
203 |
+
* The property `bytesRead` informs about the number of bytes that have been read so far.
|
204 |
+
|
205 |
+
* **field**(< _string_ >fieldname, < _string_ >value, < _boolean_ >fieldnameTruncated, < _boolean_ >valueTruncated, < _string_ >transferEncoding, < _string_ >mimeType) - Emitted for each new non-file field found.
|
206 |
+
|
207 |
+
* **partsLimit**() - Emitted when specified `parts` limit has been reached. No more 'file' or 'field' events will be emitted.
|
208 |
+
|
209 |
+
* **filesLimit**() - Emitted when specified `files` limit has been reached. No more 'file' events will be emitted.
|
210 |
+
|
211 |
+
* **fieldsLimit**() - Emitted when specified `fields` limit has been reached. No more 'field' events will be emitted.
|
212 |
+
|
213 |
+
|
214 |
+
Busboy methods
|
215 |
+
--------------
|
216 |
+
|
217 |
+
* **(constructor)**(< _object_ >config) - Creates and returns a new Busboy instance.
|
218 |
+
|
219 |
+
* The constructor takes the following valid `config` settings:
|
220 |
+
|
221 |
+
* **headers** - _object_ - These are the HTTP headers of the incoming request, which are used by individual parsers.
|
222 |
+
|
223 |
+
* **autoDestroy** - _boolean_ - Whether this stream should automatically call .destroy() on itself after ending. (Default: false).
|
224 |
+
|
225 |
+
* **highWaterMark** - _integer_ - highWaterMark to use for this Busboy instance (Default: WritableStream default).
|
226 |
+
|
227 |
+
* **fileHwm** - _integer_ - highWaterMark to use for file streams (Default: ReadableStream default).
|
228 |
+
|
229 |
+
* **defCharset** - _string_ - Default character set to use when one isn't defined (Default: 'utf8').
|
230 |
+
|
231 |
+
* **preservePath** - _boolean_ - If paths in the multipart 'filename' field shall be preserved. (Default: false).
|
232 |
+
|
233 |
+
* **isPartAFile** - __function__ - Use this function to override the default file detection functionality. It has following parameters:
|
234 |
+
|
235 |
+
* fieldName - __string__ The name of the field.
|
236 |
+
|
237 |
+
* contentType - __string__ The content-type of the part, e.g. `text/plain`, `image/jpeg`, `application/octet-stream`
|
238 |
+
|
239 |
+
* fileName - __string__ The name of a file supplied by the part.
|
240 |
+
|
241 |
+
(Default: `(fieldName, contentType, fileName) => (contentType === 'application/octet-stream' || fileName !== undefined)`)
|
242 |
+
|
243 |
+
* **limits** - _object_ - Various limits on incoming data. Valid properties are:
|
244 |
+
|
245 |
+
* **fieldNameSize** - _integer_ - Max field name size (in bytes) (Default: 100 bytes).
|
246 |
+
|
247 |
+
* **fieldSize** - _integer_ - Max field value size (in bytes) (Default: 1 MiB, which is 1024 x 1024 bytes).
|
248 |
+
|
249 |
+
* **fields** - _integer_ - Max number of non-file fields (Default: Infinity).
|
250 |
+
|
251 |
+
* **fileSize** - _integer_ - For multipart forms, the max file size (in bytes) (Default: Infinity).
|
252 |
+
|
253 |
+
* **files** - _integer_ - For multipart forms, the max number of file fields (Default: Infinity).
|
254 |
+
|
255 |
+
* **parts** - _integer_ - For multipart forms, the max number of parts (fields + files) (Default: Infinity).
|
256 |
+
|
257 |
+
* **headerPairs** - _integer_ - For multipart forms, the max number of header key=>value pairs to parse **Default:** 2000
|
258 |
+
|
259 |
+
* **headerSize** - _integer_ - For multipart forms, the max size of a multipart header **Default:** 81920.
|
260 |
+
|
261 |
+
* The constructor can throw errors:
|
262 |
+
|
263 |
+
* **Busboy expected an options-Object.** - Busboy expected an Object as first parameters.
|
264 |
+
|
265 |
+
* **Busboy expected an options-Object with headers-attribute.** - The first parameter is lacking of a headers-attribute.
|
266 |
+
|
267 |
+
* **Limit $limit is not a valid number** - Busboy expected the desired limit to be of type number. Busboy throws this Error to prevent a potential security issue by falling silently back to the Busboy-defaults. Potential source for this Error can be the direct use of environment variables without transforming them to the type number.
|
268 |
+
|
269 |
+
* **Unsupported Content-Type.** - The `Content-Type` isn't one Busboy can parse.
|
270 |
+
|
271 |
+
* **Missing Content-Type-header.** - The provided headers don't include `Content-Type` at all.
|
node_modules/@fastify/busboy/deps/dicer/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Copyright Brian White. All rights reserved.
|
2 |
+
|
3 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4 |
+
of this software and associated documentation files (the "Software"), to
|
5 |
+
deal in the Software without restriction, including without limitation the
|
6 |
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
7 |
+
sell copies of the Software, and to permit persons to whom the Software is
|
8 |
+
furnished to do so, subject to the following conditions:
|
9 |
+
|
10 |
+
The above copyright notice and this permission notice shall be included in
|
11 |
+
all copies or substantial portions of the Software.
|
12 |
+
|
13 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
18 |
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
19 |
+
IN THE SOFTWARE.
|
node_modules/@fastify/busboy/deps/dicer/lib/Dicer.js
ADDED
@@ -0,0 +1,207 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
'use strict'
|
2 |
+
|
3 |
+
const WritableStream = require('node:stream').Writable
|
4 |
+
const inherits = require('node:util').inherits
|
5 |
+
|
6 |
+
const StreamSearch = require('../../streamsearch/sbmh')
|
7 |
+
|
8 |
+
const PartStream = require('./PartStream')
|
9 |
+
const HeaderParser = require('./HeaderParser')
|
10 |
+
|
11 |
+
const DASH = 45
|
12 |
+
const B_ONEDASH = Buffer.from('-')
|
13 |
+
const B_CRLF = Buffer.from('\r\n')
|
14 |
+
const EMPTY_FN = function () {}
|
15 |
+
|
16 |
+
function Dicer (cfg) {
|
17 |
+
if (!(this instanceof Dicer)) { return new Dicer(cfg) }
|
18 |
+
WritableStream.call(this, cfg)
|
19 |
+
|
20 |
+
if (!cfg || (!cfg.headerFirst && typeof cfg.boundary !== 'string')) { throw new TypeError('Boundary required') }
|
21 |
+
|
22 |
+
if (typeof cfg.boundary === 'string') { this.setBoundary(cfg.boundary) } else { this._bparser = undefined }
|
23 |
+
|
24 |
+
this._headerFirst = cfg.headerFirst
|
25 |
+
|
26 |
+
this._dashes = 0
|
27 |
+
this._parts = 0
|
28 |
+
this._finished = false
|
29 |
+
this._realFinish = false
|
30 |
+
this._isPreamble = true
|
31 |
+
this._justMatched = false
|
32 |
+
this._firstWrite = true
|
33 |
+
this._inHeader = true
|
34 |
+
this._part = undefined
|
35 |
+
this._cb = undefined
|
36 |
+
this._ignoreData = false
|
37 |
+
this._partOpts = { highWaterMark: cfg.partHwm }
|
38 |
+
this._pause = false
|
39 |
+
|
40 |
+
const self = this
|
41 |
+
this._hparser = new HeaderParser(cfg)
|
42 |
+
this._hparser.on('header', function (header) {
|
43 |
+
self._inHeader = false
|
44 |
+
self._part.emit('header', header)
|
45 |
+
})
|
46 |
+
}
|
47 |
+
inherits(Dicer, WritableStream)
|
48 |
+
|
49 |
+
Dicer.prototype.emit = function (ev) {
|
50 |
+
if (ev === 'finish' && !this._realFinish) {
|
51 |
+
if (!this._finished) {
|
52 |
+
const self = this
|
53 |
+
process.nextTick(function () {
|
54 |
+
self.emit('error', new Error('Unexpected end of multipart data'))
|
55 |
+
if (self._part && !self._ignoreData) {
|
56 |
+
const type = (self._isPreamble ? 'Preamble' : 'Part')
|
57 |
+
self._part.emit('error', new Error(type + ' terminated early due to unexpected end of multipart data'))
|
58 |
+
self._part.push(null)
|
59 |
+
process.nextTick(function () {
|
60 |
+
self._realFinish = true
|
61 |
+
self.emit('finish')
|
62 |
+
self._realFinish = false
|
63 |
+
})
|
64 |
+
return
|
65 |
+
}
|
66 |
+
self._realFinish = true
|
67 |
+
self.emit('finish')
|
68 |
+
self._realFinish = false
|
69 |
+
})
|
70 |
+
}
|
71 |
+
} else { WritableStream.prototype.emit.apply(this, arguments) }
|
72 |
+
}
|
73 |
+
|
74 |
+
Dicer.prototype._write = function (data, encoding, cb) {
|
75 |
+
// ignore unexpected data (e.g. extra trailer data after finished)
|
76 |
+
if (!this._hparser && !this._bparser) { return cb() }
|
77 |
+
|
78 |
+
if (this._headerFirst && this._isPreamble) {
|
79 |
+
if (!this._part) {
|
80 |
+
this._part = new PartStream(this._partOpts)
|
81 |
+
if (this._events.preamble) { this.emit('preamble', this._part) } else { this._ignore() }
|
82 |
+
}
|
83 |
+
const r = this._hparser.push(data)
|
84 |
+
if (!this._inHeader && r !== undefined && r < data.length) { data = data.slice(r) } else { return cb() }
|
85 |
+
}
|
86 |
+
|
87 |
+
// allows for "easier" testing
|
88 |
+
if (this._firstWrite) {
|
89 |
+
this._bparser.push(B_CRLF)
|
90 |
+
this._firstWrite = false
|
91 |
+
}
|
92 |
+
|
93 |
+
this._bparser.push(data)
|
94 |
+
|
95 |
+
if (this._pause) { this._cb = cb } else { cb() }
|
96 |
+
}
|
97 |
+
|
98 |
+
Dicer.prototype.reset = function () {
|
99 |
+
this._part = undefined
|
100 |
+
this._bparser = undefined
|
101 |
+
this._hparser = undefined
|
102 |
+
}
|
103 |
+
|
104 |
+
Dicer.prototype.setBoundary = function (boundary) {
|
105 |
+
const self = this
|
106 |
+
this._bparser = new StreamSearch('\r\n--' + boundary)
|
107 |
+
this._bparser.on('info', function (isMatch, data, start, end) {
|
108 |
+
self._oninfo(isMatch, data, start, end)
|
109 |
+
})
|
110 |
+
}
|
111 |
+
|
112 |
+
Dicer.prototype._ignore = function () {
|
113 |
+
if (this._part && !this._ignoreData) {
|
114 |
+
this._ignoreData = true
|
115 |
+
this._part.on('error', EMPTY_FN)
|
116 |
+
// we must perform some kind of read on the stream even though we are
|
117 |
+
// ignoring the data, otherwise node's Readable stream will not emit 'end'
|
118 |
+
// after pushing null to the stream
|
119 |
+
this._part.resume()
|
120 |
+
}
|
121 |
+
}
|
122 |
+
|
123 |
+
Dicer.prototype._oninfo = function (isMatch, data, start, end) {
|
124 |
+
let buf; const self = this; let i = 0; let r; let shouldWriteMore = true
|
125 |
+
|
126 |
+
if (!this._part && this._justMatched && data) {
|
127 |
+
while (this._dashes < 2 && (start + i) < end) {
|
128 |
+
if (data[start + i] === DASH) {
|
129 |
+
++i
|
130 |
+
++this._dashes
|
131 |
+
} else {
|
132 |
+
if (this._dashes) { buf = B_ONEDASH }
|
133 |
+
this._dashes = 0
|
134 |
+
break
|
135 |
+
}
|
136 |
+
}
|
137 |
+
if (this._dashes === 2) {
|
138 |
+
if ((start + i) < end && this._events.trailer) { this.emit('trailer', data.slice(start + i, end)) }
|
139 |
+
this.reset()
|
140 |
+
this._finished = true
|
141 |
+
// no more parts will be added
|
142 |
+
if (self._parts === 0) {
|
143 |
+
self._realFinish = true
|
144 |
+
self.emit('finish')
|
145 |
+
self._realFinish = false
|
146 |
+
}
|
147 |
+
}
|
148 |
+
if (this._dashes) { return }
|
149 |
+
}
|
150 |
+
if (this._justMatched) { this._justMatched = false }
|
151 |
+
if (!this._part) {
|
152 |
+
this._part = new PartStream(this._partOpts)
|
153 |
+
this._part._read = function (n) {
|
154 |
+
self._unpause()
|
155 |
+
}
|
156 |
+
if (this._isPreamble && this._events.preamble) { this.emit('preamble', this._part) } else if (this._isPreamble !== true && this._events.part) { this.emit('part', this._part) } else { this._ignore() }
|
157 |
+
if (!this._isPreamble) { this._inHeader = true }
|
158 |
+
}
|
159 |
+
if (data && start < end && !this._ignoreData) {
|
160 |
+
if (this._isPreamble || !this._inHeader) {
|
161 |
+
if (buf) { shouldWriteMore = this._part.push(buf) }
|
162 |
+
shouldWriteMore = this._part.push(data.slice(start, end))
|
163 |
+
if (!shouldWriteMore) { this._pause = true }
|
164 |
+
} else if (!this._isPreamble && this._inHeader) {
|
165 |
+
if (buf) { this._hparser.push(buf) }
|
166 |
+
r = this._hparser.push(data.slice(start, end))
|
167 |
+
if (!this._inHeader && r !== undefined && r < end) { this._oninfo(false, data, start + r, end) }
|
168 |
+
}
|
169 |
+
}
|
170 |
+
if (isMatch) {
|
171 |
+
this._hparser.reset()
|
172 |
+
if (this._isPreamble) { this._isPreamble = false } else {
|
173 |
+
if (start !== end) {
|
174 |
+
++this._parts
|
175 |
+
this._part.on('end', function () {
|
176 |
+
if (--self._parts === 0) {
|
177 |
+
if (self._finished) {
|
178 |
+
self._realFinish = true
|
179 |
+
self.emit('finish')
|
180 |
+
self._realFinish = false
|
181 |
+
} else {
|
182 |
+
self._unpause()
|
183 |
+
}
|
184 |
+
}
|
185 |
+
})
|
186 |
+
}
|
187 |
+
}
|
188 |
+
this._part.push(null)
|
189 |
+
this._part = undefined
|
190 |
+
this._ignoreData = false
|
191 |
+
this._justMatched = true
|
192 |
+
this._dashes = 0
|
193 |
+
}
|
194 |
+
}
|
195 |
+
|
196 |
+
Dicer.prototype._unpause = function () {
|
197 |
+
if (!this._pause) { return }
|
198 |
+
|
199 |
+
this._pause = false
|
200 |
+
if (this._cb) {
|
201 |
+
const cb = this._cb
|
202 |
+
this._cb = undefined
|
203 |
+
cb()
|
204 |
+
}
|
205 |
+
}
|
206 |
+
|
207 |
+
module.exports = Dicer
|
node_modules/@fastify/busboy/deps/dicer/lib/HeaderParser.js
ADDED
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
'use strict'
|
2 |
+
|
3 |
+
const EventEmitter = require('node:events').EventEmitter
|
4 |
+
const inherits = require('node:util').inherits
|
5 |
+
const getLimit = require('../../../lib/utils/getLimit')
|
6 |
+
|
7 |
+
const StreamSearch = require('../../streamsearch/sbmh')
|
8 |
+
|
9 |
+
const B_DCRLF = Buffer.from('\r\n\r\n')
|
10 |
+
const RE_CRLF = /\r\n/g
|
11 |
+
const RE_HDR = /^([^:]+):[ \t]?([\x00-\xFF]+)?$/ // eslint-disable-line no-control-regex
|
12 |
+
|
13 |
+
function HeaderParser (cfg) {
|
14 |
+
EventEmitter.call(this)
|
15 |
+
|
16 |
+
cfg = cfg || {}
|
17 |
+
const self = this
|
18 |
+
this.nread = 0
|
19 |
+
this.maxed = false
|
20 |
+
this.npairs = 0
|
21 |
+
this.maxHeaderPairs = getLimit(cfg, 'maxHeaderPairs', 2000)
|
22 |
+
this.maxHeaderSize = getLimit(cfg, 'maxHeaderSize', 80 * 1024)
|
23 |
+
this.buffer = ''
|
24 |
+
this.header = {}
|
25 |
+
this.finished = false
|
26 |
+
this.ss = new StreamSearch(B_DCRLF)
|
27 |
+
this.ss.on('info', function (isMatch, data, start, end) {
|
28 |
+
if (data && !self.maxed) {
|
29 |
+
if (self.nread + end - start >= self.maxHeaderSize) {
|
30 |
+
end = self.maxHeaderSize - self.nread + start
|
31 |
+
self.nread = self.maxHeaderSize
|
32 |
+
self.maxed = true
|
33 |
+
} else { self.nread += (end - start) }
|
34 |
+
|
35 |
+
self.buffer += data.toString('binary', start, end)
|
36 |
+
}
|
37 |
+
if (isMatch) { self._finish() }
|
38 |
+
})
|
39 |
+
}
|
40 |
+
inherits(HeaderParser, EventEmitter)
|
41 |
+
|
42 |
+
HeaderParser.prototype.push = function (data) {
|
43 |
+
const r = this.ss.push(data)
|
44 |
+
if (this.finished) { return r }
|
45 |
+
}
|
46 |
+
|
47 |
+
HeaderParser.prototype.reset = function () {
|
48 |
+
this.finished = false
|
49 |
+
this.buffer = ''
|
50 |
+
this.header = {}
|
51 |
+
this.ss.reset()
|
52 |
+
}
|
53 |
+
|
54 |
+
HeaderParser.prototype._finish = function () {
|
55 |
+
if (this.buffer) { this._parseHeader() }
|
56 |
+
this.ss.matches = this.ss.maxMatches
|
57 |
+
const header = this.header
|
58 |
+
this.header = {}
|
59 |
+
this.buffer = ''
|
60 |
+
this.finished = true
|
61 |
+
this.nread = this.npairs = 0
|
62 |
+
this.maxed = false
|
63 |
+
this.emit('header', header)
|
64 |
+
}
|
65 |
+
|
66 |
+
HeaderParser.prototype._parseHeader = function () {
|
67 |
+
if (this.npairs === this.maxHeaderPairs) { return }
|
68 |
+
|
69 |
+
const lines = this.buffer.split(RE_CRLF)
|
70 |
+
const len = lines.length
|
71 |
+
let m, h
|
72 |
+
|
73 |
+
for (var i = 0; i < len; ++i) { // eslint-disable-line no-var
|
74 |
+
if (lines[i].length === 0) { continue }
|
75 |
+
if (lines[i][0] === '\t' || lines[i][0] === ' ') {
|
76 |
+
// folded header content
|
77 |
+
// RFC2822 says to just remove the CRLF and not the whitespace following
|
78 |
+
// it, so we follow the RFC and include the leading whitespace ...
|
79 |
+
if (h) {
|
80 |
+
this.header[h][this.header[h].length - 1] += lines[i]
|
81 |
+
continue
|
82 |
+
}
|
83 |
+
}
|
84 |
+
|
85 |
+
const posColon = lines[i].indexOf(':')
|
86 |
+
if (
|
87 |
+
posColon === -1 ||
|
88 |
+
posColon === 0
|
89 |
+
) {
|
90 |
+
return
|
91 |
+
}
|
92 |
+
m = RE_HDR.exec(lines[i])
|
93 |
+
h = m[1].toLowerCase()
|
94 |
+
this.header[h] = this.header[h] || []
|
95 |
+
this.header[h].push((m[2] || ''))
|
96 |
+
if (++this.npairs === this.maxHeaderPairs) { break }
|
97 |
+
}
|
98 |
+
}
|
99 |
+
|
100 |
+
module.exports = HeaderParser
|
node_modules/@fastify/busboy/deps/dicer/lib/PartStream.js
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
'use strict'
|
2 |
+
|
3 |
+
const inherits = require('node:util').inherits
|
4 |
+
const ReadableStream = require('node:stream').Readable
|
5 |
+
|
6 |
+
function PartStream (opts) {
|
7 |
+
ReadableStream.call(this, opts)
|
8 |
+
}
|
9 |
+
inherits(PartStream, ReadableStream)
|
10 |
+
|
11 |
+
PartStream.prototype._read = function (n) {}
|
12 |
+
|
13 |
+
module.exports = PartStream
|
node_modules/@fastify/busboy/deps/dicer/lib/dicer.d.ts
ADDED
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Type definitions for dicer 0.2
|
2 |
+
// Project: https://github.com/mscdex/dicer
|
3 |
+
// Definitions by: BendingBender <https://github.com/BendingBender>
|
4 |
+
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
5 |
+
// TypeScript Version: 2.2
|
6 |
+
/// <reference types="node" />
|
7 |
+
|
8 |
+
import stream = require("stream");
|
9 |
+
|
10 |
+
// tslint:disable:unified-signatures
|
11 |
+
|
12 |
+
/**
|
13 |
+
* A very fast streaming multipart parser for node.js.
|
14 |
+
* Dicer is a WritableStream
|
15 |
+
*
|
16 |
+
* Dicer (special) events:
|
17 |
+
* - on('finish', ()) - Emitted when all parts have been parsed and the Dicer instance has been ended.
|
18 |
+
* - on('part', (stream: PartStream)) - Emitted when a new part has been found.
|
19 |
+
* - on('preamble', (stream: PartStream)) - Emitted for preamble if you should happen to need it (can usually be ignored).
|
20 |
+
* - on('trailer', (data: Buffer)) - Emitted when trailing data was found after the terminating boundary (as with the preamble, this can usually be ignored too).
|
21 |
+
*/
|
22 |
+
export class Dicer extends stream.Writable {
|
23 |
+
/**
|
24 |
+
* Creates and returns a new Dicer instance with the following valid config settings:
|
25 |
+
*
|
26 |
+
* @param config The configuration to use
|
27 |
+
*/
|
28 |
+
constructor(config: Dicer.Config);
|
29 |
+
/**
|
30 |
+
* Sets the boundary to use for parsing and performs some initialization needed for parsing.
|
31 |
+
* You should only need to use this if you set headerFirst to true in the constructor and are parsing the boundary from the preamble header.
|
32 |
+
*
|
33 |
+
* @param boundary The boundary to use
|
34 |
+
*/
|
35 |
+
setBoundary(boundary: string): void;
|
36 |
+
addListener(event: "finish", listener: () => void): this;
|
37 |
+
addListener(event: "part", listener: (stream: Dicer.PartStream) => void): this;
|
38 |
+
addListener(event: "preamble", listener: (stream: Dicer.PartStream) => void): this;
|
39 |
+
addListener(event: "trailer", listener: (data: Buffer) => void): this;
|
40 |
+
addListener(event: "close", listener: () => void): this;
|
41 |
+
addListener(event: "drain", listener: () => void): this;
|
42 |
+
addListener(event: "error", listener: (err: Error) => void): this;
|
43 |
+
addListener(event: "pipe", listener: (src: stream.Readable) => void): this;
|
44 |
+
addListener(event: "unpipe", listener: (src: stream.Readable) => void): this;
|
45 |
+
addListener(event: string, listener: (...args: any[]) => void): this;
|
46 |
+
on(event: "finish", listener: () => void): this;
|
47 |
+
on(event: "part", listener: (stream: Dicer.PartStream) => void): this;
|
48 |
+
on(event: "preamble", listener: (stream: Dicer.PartStream) => void): this;
|
49 |
+
on(event: "trailer", listener: (data: Buffer) => void): this;
|
50 |
+
on(event: "close", listener: () => void): this;
|
51 |
+
on(event: "drain", listener: () => void): this;
|
52 |
+
on(event: "error", listener: (err: Error) => void): this;
|
53 |
+
on(event: "pipe", listener: (src: stream.Readable) => void): this;
|
54 |
+
on(event: "unpipe", listener: (src: stream.Readable) => void): this;
|
55 |
+
on(event: string, listener: (...args: any[]) => void): this;
|
56 |
+
once(event: "finish", listener: () => void): this;
|
57 |
+
once(event: "part", listener: (stream: Dicer.PartStream) => void): this;
|
58 |
+
once(event: "preamble", listener: (stream: Dicer.PartStream) => void): this;
|
59 |
+
once(event: "trailer", listener: (data: Buffer) => void): this;
|
60 |
+
once(event: "close", listener: () => void): this;
|
61 |
+
once(event: "drain", listener: () => void): this;
|
62 |
+
once(event: "error", listener: (err: Error) => void): this;
|
63 |
+
once(event: "pipe", listener: (src: stream.Readable) => void): this;
|
64 |
+
once(event: "unpipe", listener: (src: stream.Readable) => void): this;
|
65 |
+
once(event: string, listener: (...args: any[]) => void): this;
|
66 |
+
prependListener(event: "finish", listener: () => void): this;
|
67 |
+
prependListener(event: "part", listener: (stream: Dicer.PartStream) => void): this;
|
68 |
+
prependListener(event: "preamble", listener: (stream: Dicer.PartStream) => void): this;
|
69 |
+
prependListener(event: "trailer", listener: (data: Buffer) => void): this;
|
70 |
+
prependListener(event: "close", listener: () => void): this;
|
71 |
+
prependListener(event: "drain", listener: () => void): this;
|
72 |
+
prependListener(event: "error", listener: (err: Error) => void): this;
|
73 |
+
prependListener(event: "pipe", listener: (src: stream.Readable) => void): this;
|
74 |
+
prependListener(event: "unpipe", listener: (src: stream.Readable) => void): this;
|
75 |
+
prependListener(event: string, listener: (...args: any[]) => void): this;
|
76 |
+
prependOnceListener(event: "finish", listener: () => void): this;
|
77 |
+
prependOnceListener(event: "part", listener: (stream: Dicer.PartStream) => void): this;
|
78 |
+
prependOnceListener(event: "preamble", listener: (stream: Dicer.PartStream) => void): this;
|
79 |
+
prependOnceListener(event: "trailer", listener: (data: Buffer) => void): this;
|
80 |
+
prependOnceListener(event: "close", listener: () => void): this;
|
81 |
+
prependOnceListener(event: "drain", listener: () => void): this;
|
82 |
+
prependOnceListener(event: "error", listener: (err: Error) => void): this;
|
83 |
+
prependOnceListener(event: "pipe", listener: (src: stream.Readable) => void): this;
|
84 |
+
prependOnceListener(event: "unpipe", listener: (src: stream.Readable) => void): this;
|
85 |
+
prependOnceListener(event: string, listener: (...args: any[]) => void): this;
|
86 |
+
removeListener(event: "finish", listener: () => void): this;
|
87 |
+
removeListener(event: "part", listener: (stream: Dicer.PartStream) => void): this;
|
88 |
+
removeListener(event: "preamble", listener: (stream: Dicer.PartStream) => void): this;
|
89 |
+
removeListener(event: "trailer", listener: (data: Buffer) => void): this;
|
90 |
+
removeListener(event: "close", listener: () => void): this;
|
91 |
+
removeListener(event: "drain", listener: () => void): this;
|
92 |
+
removeListener(event: "error", listener: (err: Error) => void): this;
|
93 |
+
removeListener(event: "pipe", listener: (src: stream.Readable) => void): this;
|
94 |
+
removeListener(event: "unpipe", listener: (src: stream.Readable) => void): this;
|
95 |
+
removeListener(event: string, listener: (...args: any[]) => void): this;
|
96 |
+
}
|
97 |
+
|
98 |
+
declare namespace Dicer {
|
99 |
+
interface Config {
|
100 |
+
/**
|
101 |
+
* This is the boundary used to detect the beginning of a new part.
|
102 |
+
*/
|
103 |
+
boundary?: string | undefined;
|
104 |
+
/**
|
105 |
+
* If true, preamble header parsing will be performed first.
|
106 |
+
*/
|
107 |
+
headerFirst?: boolean | undefined;
|
108 |
+
/**
|
109 |
+
* The maximum number of header key=>value pairs to parse Default: 2000 (same as node's http).
|
110 |
+
*/
|
111 |
+
maxHeaderPairs?: number | undefined;
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* PartStream is a _ReadableStream_
|
116 |
+
*
|
117 |
+
* PartStream (special) events:
|
118 |
+
* - on('header', (header: object)) - An object containing the header for this particular part. Each property value is an array of one or more string values.
|
119 |
+
*/
|
120 |
+
interface PartStream extends stream.Readable {
|
121 |
+
addListener(event: "header", listener: (header: object) => void): this;
|
122 |
+
addListener(event: "close", listener: () => void): this;
|
123 |
+
addListener(event: "data", listener: (chunk: Buffer | string) => void): this;
|
124 |
+
addListener(event: "end", listener: () => void): this;
|
125 |
+
addListener(event: "readable", listener: () => void): this;
|
126 |
+
addListener(event: "error", listener: (err: Error) => void): this;
|
127 |
+
addListener(event: string, listener: (...args: any[]) => void): this;
|
128 |
+
on(event: "header", listener: (header: object) => void): this;
|
129 |
+
on(event: "close", listener: () => void): this;
|
130 |
+
on(event: "data", listener: (chunk: Buffer | string) => void): this;
|
131 |
+
on(event: "end", listener: () => void): this;
|
132 |
+
on(event: "readable", listener: () => void): this;
|
133 |
+
on(event: "error", listener: (err: Error) => void): this;
|
134 |
+
on(event: string, listener: (...args: any[]) => void): this;
|
135 |
+
once(event: "header", listener: (header: object) => void): this;
|
136 |
+
once(event: "close", listener: () => void): this;
|
137 |
+
once(event: "data", listener: (chunk: Buffer | string) => void): this;
|
138 |
+
once(event: "end", listener: () => void): this;
|
139 |
+
once(event: "readable", listener: () => void): this;
|
140 |
+
once(event: "error", listener: (err: Error) => void): this;
|
141 |
+
once(event: string, listener: (...args: any[]) => void): this;
|
142 |
+
prependListener(event: "header", listener: (header: object) => void): this;
|
143 |
+
prependListener(event: "close", listener: () => void): this;
|
144 |
+
prependListener(event: "data", listener: (chunk: Buffer | string) => void): this;
|
145 |
+
prependListener(event: "end", listener: () => void): this;
|
146 |
+
prependListener(event: "readable", listener: () => void): this;
|
147 |
+
prependListener(event: "error", listener: (err: Error) => void): this;
|
148 |
+
prependListener(event: string, listener: (...args: any[]) => void): this;
|
149 |
+
prependOnceListener(event: "header", listener: (header: object) => void): this;
|
150 |
+
prependOnceListener(event: "close", listener: () => void): this;
|
151 |
+
prependOnceListener(event: "data", listener: (chunk: Buffer | string) => void): this;
|
152 |
+
prependOnceListener(event: "end", listener: () => void): this;
|
153 |
+
prependOnceListener(event: "readable", listener: () => void): this;
|
154 |
+
prependOnceListener(event: "error", listener: (err: Error) => void): this;
|
155 |
+
prependOnceListener(event: string, listener: (...args: any[]) => void): this;
|
156 |
+
removeListener(event: "header", listener: (header: object) => void): this;
|
157 |
+
removeListener(event: "close", listener: () => void): this;
|
158 |
+
removeListener(event: "data", listener: (chunk: Buffer | string) => void): this;
|
159 |
+
removeListener(event: "end", listener: () => void): this;
|
160 |
+
removeListener(event: "readable", listener: () => void): this;
|
161 |
+
removeListener(event: "error", listener: (err: Error) => void): this;
|
162 |
+
removeListener(event: string, listener: (...args: any[]) => void): this;
|
163 |
+
}
|
164 |
+
}
|