jbilcke-hf HF staff commited on
Commit
5b3c62d
0 Parent(s):

initial commit

Browse files
.dockerignore ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ node_modules
2
+ npm-debug.log
3
+ sandbox
.gitignore ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ node_modules
2
+ *.log
3
+ *.bin
4
+ .DS_Store
5
+ .venv
6
+ *.mp4
7
+ sandbox
8
+ scripts
.nvmrc ADDED
@@ -0,0 +1 @@
 
 
1
+ v18.16.0
Dockerfile ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM nvidia/cuda:12.2.0-devel-ubuntu22.04
2
+
3
+ LABEL maintainer="Hugging Face"
4
+
5
+ ARG COLMAP_GIT_COMMIT=main
6
+ ARG CUDA_ARCHITECTURES=native
7
+ ENV QT_XCB_GL_INTEGRATION=xcb_egl
8
+
9
+ # Prevent stop building ubuntu at time zone selection.
10
+ ENV DEBIAN_FRONTEND=noninteractive
11
+
12
+ RUN echo "Build started at: $(date "+%Y-%m-%d %H:%M")"
13
+
14
+ RUN apt-get update
15
+
16
+ RUN apt-get install -y \
17
+ wget \
18
+ curl \
19
+ git \
20
+ git-lfs \
21
+ unzip
22
+
23
+ RUN git lfs install
24
+
25
+ # Prepare and empty machine for building.
26
+ RUN apt-get install -y \
27
+ cmake \
28
+ ninja-build \
29
+ build-essential \
30
+ libboost-program-options-dev \
31
+ libboost-filesystem-dev \
32
+ libboost-graph-dev \
33
+ libboost-system-dev \
34
+ libeigen3-dev \
35
+ libflann-dev \
36
+ libfreeimage-dev \
37
+ libmetis-dev \
38
+ libgoogle-glog-dev \
39
+ libgtest-dev \
40
+ libsqlite3-dev \
41
+ libglew-dev \
42
+ qtbase5-dev \
43
+ libqt5opengl5-dev \
44
+ libcgal-dev \
45
+ libceres-dev
46
+
47
+ # Build and install COLMAP.
48
+ RUN git clone https://github.com/colmap/colmap.git
49
+ RUN cd colmap && \
50
+ git fetch https://github.com/colmap/colmap.git ${COLMAP_GIT_COMMIT} && \
51
+ git checkout FETCH_HEAD && \
52
+ mkdir build && \
53
+ cd build && \
54
+ cmake .. -GNinja -DCMAKE_CUDA_ARCHITECTURES=${CUDA_ARCHITECTURES} && \
55
+ ninja && \
56
+ ninja install && \
57
+ cd .. && rm -rf colmap
58
+
59
+ # NodeJS - NEW, MORE ANNOYING WAY
60
+ RUN apt --yes install -y ca-certificates gnupg
61
+ RUN mkdir -p /etc/apt/keyrings
62
+ RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
63
+ ENV NODE_MAJOR=18
64
+ RUN echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list
65
+ RUN apt update
66
+ RUN apt --yes install nodejs
67
+
68
+ # Python
69
+ RUN apt --yes install python3 python3-pip
70
+ RUN python3 -m pip install --no-cache-dir --upgrade pip
71
+
72
+ # Set up a new user named "user" with user ID 1000
73
+ RUN useradd -o -u 1000 user
74
+
75
+ # Switch to the "user" user
76
+ USER user
77
+
78
+ ENV PYTHON_BIN /usr/bin/python3
79
+
80
+ #ENV PATH /usr/local/cuda-12.2/bin:$PATH
81
+ #ENV LD_LIBRARY_PATH /usr/local/cuda-12.2/lib64:$LD_LIBRARY_PATH
82
+ # Let's try to downgrade
83
+ ENV PATH /usr/local/cuda-11.8/bin:$PATH
84
+ ENV LD_LIBRARY_PATH /usr/local/cuda-11.8/lib64:$LD_LIBRARY_PATH
85
+
86
+
87
+ # Set home to the user's home directory
88
+ ENV HOME=/home/user \
89
+ PATH=/home/user/.local/bin:$PATH
90
+
91
+ # Set the working directory to the user's home directory
92
+ WORKDIR $HOME/app
93
+
94
+ # Install app dependencies
95
+ # A wildcard is used to ensure both package.json AND package-lock.json are copied
96
+ # where available (npm@5+)
97
+ COPY --chown=user package*.json $HOME/app
98
+
99
+ RUN npm install
100
+
101
+ # Copy the current directory contents into the container at $HOME/app setting the owner to the user
102
+ COPY --chown=user . $HOME/app
103
+
104
+ RUN echo "Build ended at: $(date "+%Y-%m-%d %H:%M")"
105
+
106
+ EXPOSE 7860
107
+
108
+ # we can't use this (it time out)
109
+ # CMD [ "xvfb-run", "-s", "-ac -screen 0 1920x1080x24", "npm", "run", "start" ]
110
+ CMD [ "npm", "run", "start" ]
LICENSE.txt ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright [yyyy] [name of copyright owner]
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
README.md ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Campose API
3
+ emoji: 📷
4
+ colorFrom: green
5
+ colorTo: yellow
6
+ sdk: docker
7
+ pinned: true
8
+ app_port: 7860
9
+ ---
10
+
11
+ ## Presentation
12
+
13
+ ### What is this project?
14
+
15
+ WARNING - This project is not finished!
16
+
17
+ Campose API is a REST API to generate camera pose data from a set of images or a video.
18
+
19
+ ### TODO
20
+
21
+ - [x] Compile colmap with Docker
22
+ - [ ] Support upload of assets
23
+ - [ ] Support download of scenes
24
+
25
+ ## Running on your machine
26
+
27
+ ### Prerequisites
28
+
29
+ You need a machine with CUDA, a GPU etc
30
+
31
+ ### Environment variables
32
+
33
+ - `STORAGE_PATH`: on HF use `/data`, on a local you can use `.sandbox/`
34
+
35
+ ### Deployment to Hugging Face
package-lock.json ADDED
@@ -0,0 +1,1993 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "@jbilcke-hf/campose-api",
3
+ "version": "1.0.0",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "@jbilcke-hf/campose-api",
9
+ "version": "1.0.0",
10
+ "license": "Apache License",
11
+ "dependencies": {
12
+ "@gorgonjs/file-provider": "^1.4.1",
13
+ "@gorgonjs/gorgon": "^1.4.1",
14
+ "@types/express": "^4.17.17",
15
+ "@types/uuid": "^9.0.2",
16
+ "archiver": "^6.0.1",
17
+ "eventsource-parser": "^1.0.0",
18
+ "express": "^4.18.2",
19
+ "express-fileupload": "^1.4.0",
20
+ "extract-zip": "^2.0.1",
21
+ "fluent-ffmpeg": "^2.1.2",
22
+ "fs-extra": "^11.1.1",
23
+ "node-fetch": "^3.3.1",
24
+ "resize-base64": "^1.0.12",
25
+ "sharp": "^0.32.4",
26
+ "temp-dir": "^3.0.0",
27
+ "ts-node": "^10.9.1",
28
+ "uuid": "^9.0.0",
29
+ "yaml": "^2.3.1"
30
+ }
31
+ },
32
+ "node_modules/@cspotcode/source-map-support": {
33
+ "version": "0.8.1",
34
+ "license": "MIT",
35
+ "dependencies": {
36
+ "@jridgewell/trace-mapping": "0.3.9"
37
+ },
38
+ "engines": {
39
+ "node": ">=12"
40
+ }
41
+ },
42
+ "node_modules/@gorgonjs/file-provider": {
43
+ "version": "1.5.0",
44
+ "license": "MIT",
45
+ "dependencies": {
46
+ "fast-glob": "^3.3.0"
47
+ },
48
+ "peerDependencies": {
49
+ "@gorgonjs/gorgon": "^1.5.0"
50
+ }
51
+ },
52
+ "node_modules/@gorgonjs/gorgon": {
53
+ "version": "1.5.0",
54
+ "license": "MIT"
55
+ },
56
+ "node_modules/@jridgewell/resolve-uri": {
57
+ "version": "3.1.1",
58
+ "license": "MIT",
59
+ "engines": {
60
+ "node": ">=6.0.0"
61
+ }
62
+ },
63
+ "node_modules/@jridgewell/sourcemap-codec": {
64
+ "version": "1.4.15",
65
+ "license": "MIT"
66
+ },
67
+ "node_modules/@jridgewell/trace-mapping": {
68
+ "version": "0.3.9",
69
+ "license": "MIT",
70
+ "dependencies": {
71
+ "@jridgewell/resolve-uri": "^3.0.3",
72
+ "@jridgewell/sourcemap-codec": "^1.4.10"
73
+ }
74
+ },
75
+ "node_modules/@nodelib/fs.scandir": {
76
+ "version": "2.1.5",
77
+ "license": "MIT",
78
+ "dependencies": {
79
+ "@nodelib/fs.stat": "2.0.5",
80
+ "run-parallel": "^1.1.9"
81
+ },
82
+ "engines": {
83
+ "node": ">= 8"
84
+ }
85
+ },
86
+ "node_modules/@nodelib/fs.stat": {
87
+ "version": "2.0.5",
88
+ "license": "MIT",
89
+ "engines": {
90
+ "node": ">= 8"
91
+ }
92
+ },
93
+ "node_modules/@nodelib/fs.walk": {
94
+ "version": "1.2.8",
95
+ "license": "MIT",
96
+ "dependencies": {
97
+ "@nodelib/fs.scandir": "2.1.5",
98
+ "fastq": "^1.6.0"
99
+ },
100
+ "engines": {
101
+ "node": ">= 8"
102
+ }
103
+ },
104
+ "node_modules/@tsconfig/node10": {
105
+ "version": "1.0.9",
106
+ "license": "MIT"
107
+ },
108
+ "node_modules/@tsconfig/node12": {
109
+ "version": "1.0.11",
110
+ "license": "MIT"
111
+ },
112
+ "node_modules/@tsconfig/node14": {
113
+ "version": "1.0.3",
114
+ "license": "MIT"
115
+ },
116
+ "node_modules/@tsconfig/node16": {
117
+ "version": "1.0.4",
118
+ "license": "MIT"
119
+ },
120
+ "node_modules/@types/body-parser": {
121
+ "version": "1.19.3",
122
+ "license": "MIT",
123
+ "dependencies": {
124
+ "@types/connect": "*",
125
+ "@types/node": "*"
126
+ }
127
+ },
128
+ "node_modules/@types/connect": {
129
+ "version": "3.4.36",
130
+ "license": "MIT",
131
+ "dependencies": {
132
+ "@types/node": "*"
133
+ }
134
+ },
135
+ "node_modules/@types/express": {
136
+ "version": "4.17.17",
137
+ "license": "MIT",
138
+ "dependencies": {
139
+ "@types/body-parser": "*",
140
+ "@types/express-serve-static-core": "^4.17.33",
141
+ "@types/qs": "*",
142
+ "@types/serve-static": "*"
143
+ }
144
+ },
145
+ "node_modules/@types/express-serve-static-core": {
146
+ "version": "4.17.36",
147
+ "license": "MIT",
148
+ "dependencies": {
149
+ "@types/node": "*",
150
+ "@types/qs": "*",
151
+ "@types/range-parser": "*",
152
+ "@types/send": "*"
153
+ }
154
+ },
155
+ "node_modules/@types/http-errors": {
156
+ "version": "2.0.2",
157
+ "license": "MIT"
158
+ },
159
+ "node_modules/@types/mime": {
160
+ "version": "1.3.2",
161
+ "license": "MIT"
162
+ },
163
+ "node_modules/@types/node": {
164
+ "version": "20.6.2",
165
+ "license": "MIT"
166
+ },
167
+ "node_modules/@types/qs": {
168
+ "version": "6.9.8",
169
+ "license": "MIT"
170
+ },
171
+ "node_modules/@types/range-parser": {
172
+ "version": "1.2.4",
173
+ "license": "MIT"
174
+ },
175
+ "node_modules/@types/send": {
176
+ "version": "0.17.1",
177
+ "license": "MIT",
178
+ "dependencies": {
179
+ "@types/mime": "^1",
180
+ "@types/node": "*"
181
+ }
182
+ },
183
+ "node_modules/@types/serve-static": {
184
+ "version": "1.15.2",
185
+ "license": "MIT",
186
+ "dependencies": {
187
+ "@types/http-errors": "*",
188
+ "@types/mime": "*",
189
+ "@types/node": "*"
190
+ }
191
+ },
192
+ "node_modules/@types/uuid": {
193
+ "version": "9.0.4",
194
+ "license": "MIT"
195
+ },
196
+ "node_modules/@types/yauzl": {
197
+ "version": "2.10.0",
198
+ "license": "MIT",
199
+ "optional": true,
200
+ "dependencies": {
201
+ "@types/node": "*"
202
+ }
203
+ },
204
+ "node_modules/accepts": {
205
+ "version": "1.3.8",
206
+ "license": "MIT",
207
+ "dependencies": {
208
+ "mime-types": "~2.1.34",
209
+ "negotiator": "0.6.3"
210
+ },
211
+ "engines": {
212
+ "node": ">= 0.6"
213
+ }
214
+ },
215
+ "node_modules/acorn": {
216
+ "version": "8.10.0",
217
+ "license": "MIT",
218
+ "bin": {
219
+ "acorn": "bin/acorn"
220
+ },
221
+ "engines": {
222
+ "node": ">=0.4.0"
223
+ }
224
+ },
225
+ "node_modules/acorn-walk": {
226
+ "version": "8.2.0",
227
+ "license": "MIT",
228
+ "engines": {
229
+ "node": ">=0.4.0"
230
+ }
231
+ },
232
+ "node_modules/archiver": {
233
+ "version": "6.0.1",
234
+ "license": "MIT",
235
+ "dependencies": {
236
+ "archiver-utils": "^4.0.1",
237
+ "async": "^3.2.4",
238
+ "buffer-crc32": "^0.2.1",
239
+ "readable-stream": "^3.6.0",
240
+ "readdir-glob": "^1.1.2",
241
+ "tar-stream": "^3.0.0",
242
+ "zip-stream": "^5.0.1"
243
+ },
244
+ "engines": {
245
+ "node": ">= 12.0.0"
246
+ }
247
+ },
248
+ "node_modules/archiver-utils": {
249
+ "version": "4.0.1",
250
+ "license": "MIT",
251
+ "dependencies": {
252
+ "glob": "^8.0.0",
253
+ "graceful-fs": "^4.2.0",
254
+ "lazystream": "^1.0.0",
255
+ "lodash": "^4.17.15",
256
+ "normalize-path": "^3.0.0",
257
+ "readable-stream": "^3.6.0"
258
+ },
259
+ "engines": {
260
+ "node": ">= 12.0.0"
261
+ }
262
+ },
263
+ "node_modules/arg": {
264
+ "version": "4.1.3",
265
+ "license": "MIT"
266
+ },
267
+ "node_modules/array-flatten": {
268
+ "version": "1.1.1",
269
+ "license": "MIT"
270
+ },
271
+ "node_modules/async": {
272
+ "version": "3.2.4",
273
+ "license": "MIT"
274
+ },
275
+ "node_modules/b4a": {
276
+ "version": "1.6.4",
277
+ "license": "ISC"
278
+ },
279
+ "node_modules/balanced-match": {
280
+ "version": "1.0.2",
281
+ "license": "MIT"
282
+ },
283
+ "node_modules/base64-js": {
284
+ "version": "1.5.1",
285
+ "funding": [
286
+ {
287
+ "type": "github",
288
+ "url": "https://github.com/sponsors/feross"
289
+ },
290
+ {
291
+ "type": "patreon",
292
+ "url": "https://www.patreon.com/feross"
293
+ },
294
+ {
295
+ "type": "consulting",
296
+ "url": "https://feross.org/support"
297
+ }
298
+ ],
299
+ "license": "MIT"
300
+ },
301
+ "node_modules/bl": {
302
+ "version": "4.1.0",
303
+ "license": "MIT",
304
+ "dependencies": {
305
+ "buffer": "^5.5.0",
306
+ "inherits": "^2.0.4",
307
+ "readable-stream": "^3.4.0"
308
+ }
309
+ },
310
+ "node_modules/bluebird": {
311
+ "version": "3.7.2",
312
+ "license": "MIT"
313
+ },
314
+ "node_modules/body-parser": {
315
+ "version": "1.20.1",
316
+ "license": "MIT",
317
+ "dependencies": {
318
+ "bytes": "3.1.2",
319
+ "content-type": "~1.0.4",
320
+ "debug": "2.6.9",
321
+ "depd": "2.0.0",
322
+ "destroy": "1.2.0",
323
+ "http-errors": "2.0.0",
324
+ "iconv-lite": "0.4.24",
325
+ "on-finished": "2.4.1",
326
+ "qs": "6.11.0",
327
+ "raw-body": "2.5.1",
328
+ "type-is": "~1.6.18",
329
+ "unpipe": "1.0.0"
330
+ },
331
+ "engines": {
332
+ "node": ">= 0.8",
333
+ "npm": "1.2.8000 || >= 1.4.16"
334
+ }
335
+ },
336
+ "node_modules/brace-expansion": {
337
+ "version": "2.0.1",
338
+ "license": "MIT",
339
+ "dependencies": {
340
+ "balanced-match": "^1.0.0"
341
+ }
342
+ },
343
+ "node_modules/braces": {
344
+ "version": "3.0.2",
345
+ "license": "MIT",
346
+ "dependencies": {
347
+ "fill-range": "^7.0.1"
348
+ },
349
+ "engines": {
350
+ "node": ">=8"
351
+ }
352
+ },
353
+ "node_modules/buffer": {
354
+ "version": "5.7.1",
355
+ "funding": [
356
+ {
357
+ "type": "github",
358
+ "url": "https://github.com/sponsors/feross"
359
+ },
360
+ {
361
+ "type": "patreon",
362
+ "url": "https://www.patreon.com/feross"
363
+ },
364
+ {
365
+ "type": "consulting",
366
+ "url": "https://feross.org/support"
367
+ }
368
+ ],
369
+ "license": "MIT",
370
+ "dependencies": {
371
+ "base64-js": "^1.3.1",
372
+ "ieee754": "^1.1.13"
373
+ }
374
+ },
375
+ "node_modules/buffer-crc32": {
376
+ "version": "0.2.13",
377
+ "license": "MIT",
378
+ "engines": {
379
+ "node": "*"
380
+ }
381
+ },
382
+ "node_modules/busboy": {
383
+ "version": "1.6.0",
384
+ "dependencies": {
385
+ "streamsearch": "^1.1.0"
386
+ },
387
+ "engines": {
388
+ "node": ">=10.16.0"
389
+ }
390
+ },
391
+ "node_modules/bytes": {
392
+ "version": "3.1.2",
393
+ "license": "MIT",
394
+ "engines": {
395
+ "node": ">= 0.8"
396
+ }
397
+ },
398
+ "node_modules/call-bind": {
399
+ "version": "1.0.2",
400
+ "license": "MIT",
401
+ "dependencies": {
402
+ "function-bind": "^1.1.1",
403
+ "get-intrinsic": "^1.0.2"
404
+ },
405
+ "funding": {
406
+ "url": "https://github.com/sponsors/ljharb"
407
+ }
408
+ },
409
+ "node_modules/chownr": {
410
+ "version": "1.1.4",
411
+ "license": "ISC"
412
+ },
413
+ "node_modules/color": {
414
+ "version": "4.2.3",
415
+ "license": "MIT",
416
+ "dependencies": {
417
+ "color-convert": "^2.0.1",
418
+ "color-string": "^1.9.0"
419
+ },
420
+ "engines": {
421
+ "node": ">=12.5.0"
422
+ }
423
+ },
424
+ "node_modules/color-convert": {
425
+ "version": "2.0.1",
426
+ "license": "MIT",
427
+ "dependencies": {
428
+ "color-name": "~1.1.4"
429
+ },
430
+ "engines": {
431
+ "node": ">=7.0.0"
432
+ }
433
+ },
434
+ "node_modules/color-name": {
435
+ "version": "1.1.4",
436
+ "license": "MIT"
437
+ },
438
+ "node_modules/color-string": {
439
+ "version": "1.9.1",
440
+ "license": "MIT",
441
+ "dependencies": {
442
+ "color-name": "^1.0.0",
443
+ "simple-swizzle": "^0.2.2"
444
+ }
445
+ },
446
+ "node_modules/commander": {
447
+ "version": "2.20.3",
448
+ "license": "MIT"
449
+ },
450
+ "node_modules/compress-commons": {
451
+ "version": "5.0.1",
452
+ "license": "MIT",
453
+ "dependencies": {
454
+ "crc-32": "^1.2.0",
455
+ "crc32-stream": "^5.0.0",
456
+ "normalize-path": "^3.0.0",
457
+ "readable-stream": "^3.6.0"
458
+ },
459
+ "engines": {
460
+ "node": ">= 12.0.0"
461
+ }
462
+ },
463
+ "node_modules/content-disposition": {
464
+ "version": "0.5.4",
465
+ "license": "MIT",
466
+ "dependencies": {
467
+ "safe-buffer": "5.2.1"
468
+ },
469
+ "engines": {
470
+ "node": ">= 0.6"
471
+ }
472
+ },
473
+ "node_modules/content-type": {
474
+ "version": "1.0.5",
475
+ "license": "MIT",
476
+ "engines": {
477
+ "node": ">= 0.6"
478
+ }
479
+ },
480
+ "node_modules/cookie": {
481
+ "version": "0.5.0",
482
+ "license": "MIT",
483
+ "engines": {
484
+ "node": ">= 0.6"
485
+ }
486
+ },
487
+ "node_modules/cookie-signature": {
488
+ "version": "1.0.6",
489
+ "license": "MIT"
490
+ },
491
+ "node_modules/core-util-is": {
492
+ "version": "1.0.3",
493
+ "license": "MIT"
494
+ },
495
+ "node_modules/crc-32": {
496
+ "version": "1.2.2",
497
+ "license": "Apache-2.0",
498
+ "bin": {
499
+ "crc32": "bin/crc32.njs"
500
+ },
501
+ "engines": {
502
+ "node": ">=0.8"
503
+ }
504
+ },
505
+ "node_modules/crc32-stream": {
506
+ "version": "5.0.0",
507
+ "license": "MIT",
508
+ "dependencies": {
509
+ "crc-32": "^1.2.0",
510
+ "readable-stream": "^3.4.0"
511
+ },
512
+ "engines": {
513
+ "node": ">= 12.0.0"
514
+ }
515
+ },
516
+ "node_modules/create-readme": {
517
+ "version": "1.2.0",
518
+ "license": "MIT",
519
+ "dependencies": {
520
+ "bluebird": "^3.1.1",
521
+ "commander": "^2.9.0",
522
+ "debug": "^4.1.0",
523
+ "github-url-to-object": "^4.0.4",
524
+ "mustache": "^3.0.0",
525
+ "require-all": "^3.0.0"
526
+ },
527
+ "bin": {
528
+ "create-readme": "bin/create-readme.js"
529
+ }
530
+ },
531
+ "node_modules/create-readme/node_modules/debug": {
532
+ "version": "4.3.4",
533
+ "license": "MIT",
534
+ "dependencies": {
535
+ "ms": "2.1.2"
536
+ },
537
+ "engines": {
538
+ "node": ">=6.0"
539
+ },
540
+ "peerDependenciesMeta": {
541
+ "supports-color": {
542
+ "optional": true
543
+ }
544
+ }
545
+ },
546
+ "node_modules/create-readme/node_modules/ms": {
547
+ "version": "2.1.2",
548
+ "license": "MIT"
549
+ },
550
+ "node_modules/create-require": {
551
+ "version": "1.1.1",
552
+ "license": "MIT"
553
+ },
554
+ "node_modules/data-uri-to-buffer": {
555
+ "version": "4.0.1",
556
+ "license": "MIT",
557
+ "engines": {
558
+ "node": ">= 12"
559
+ }
560
+ },
561
+ "node_modules/debug": {
562
+ "version": "2.6.9",
563
+ "license": "MIT",
564
+ "dependencies": {
565
+ "ms": "2.0.0"
566
+ }
567
+ },
568
+ "node_modules/decompress-response": {
569
+ "version": "6.0.0",
570
+ "license": "MIT",
571
+ "dependencies": {
572
+ "mimic-response": "^3.1.0"
573
+ },
574
+ "engines": {
575
+ "node": ">=10"
576
+ },
577
+ "funding": {
578
+ "url": "https://github.com/sponsors/sindresorhus"
579
+ }
580
+ },
581
+ "node_modules/deep-extend": {
582
+ "version": "0.6.0",
583
+ "license": "MIT",
584
+ "engines": {
585
+ "node": ">=4.0.0"
586
+ }
587
+ },
588
+ "node_modules/depd": {
589
+ "version": "2.0.0",
590
+ "license": "MIT",
591
+ "engines": {
592
+ "node": ">= 0.8"
593
+ }
594
+ },
595
+ "node_modules/destroy": {
596
+ "version": "1.2.0",
597
+ "license": "MIT",
598
+ "engines": {
599
+ "node": ">= 0.8",
600
+ "npm": "1.2.8000 || >= 1.4.16"
601
+ }
602
+ },
603
+ "node_modules/detect-libc": {
604
+ "version": "2.0.2",
605
+ "license": "Apache-2.0",
606
+ "engines": {
607
+ "node": ">=8"
608
+ }
609
+ },
610
+ "node_modules/diff": {
611
+ "version": "4.0.2",
612
+ "license": "BSD-3-Clause",
613
+ "engines": {
614
+ "node": ">=0.3.1"
615
+ }
616
+ },
617
+ "node_modules/ee-first": {
618
+ "version": "1.1.1",
619
+ "license": "MIT"
620
+ },
621
+ "node_modules/encodeurl": {
622
+ "version": "1.0.2",
623
+ "license": "MIT",
624
+ "engines": {
625
+ "node": ">= 0.8"
626
+ }
627
+ },
628
+ "node_modules/end-of-stream": {
629
+ "version": "1.4.4",
630
+ "license": "MIT",
631
+ "dependencies": {
632
+ "once": "^1.4.0"
633
+ }
634
+ },
635
+ "node_modules/escape-html": {
636
+ "version": "1.0.3",
637
+ "license": "MIT"
638
+ },
639
+ "node_modules/etag": {
640
+ "version": "1.8.1",
641
+ "license": "MIT",
642
+ "engines": {
643
+ "node": ">= 0.6"
644
+ }
645
+ },
646
+ "node_modules/eventsource-parser": {
647
+ "version": "1.0.0",
648
+ "license": "MIT",
649
+ "engines": {
650
+ "node": ">=14.18"
651
+ }
652
+ },
653
+ "node_modules/expand-template": {
654
+ "version": "2.0.3",
655
+ "license": "(MIT OR WTFPL)",
656
+ "engines": {
657
+ "node": ">=6"
658
+ }
659
+ },
660
+ "node_modules/express": {
661
+ "version": "4.18.2",
662
+ "license": "MIT",
663
+ "dependencies": {
664
+ "accepts": "~1.3.8",
665
+ "array-flatten": "1.1.1",
666
+ "body-parser": "1.20.1",
667
+ "content-disposition": "0.5.4",
668
+ "content-type": "~1.0.4",
669
+ "cookie": "0.5.0",
670
+ "cookie-signature": "1.0.6",
671
+ "debug": "2.6.9",
672
+ "depd": "2.0.0",
673
+ "encodeurl": "~1.0.2",
674
+ "escape-html": "~1.0.3",
675
+ "etag": "~1.8.1",
676
+ "finalhandler": "1.2.0",
677
+ "fresh": "0.5.2",
678
+ "http-errors": "2.0.0",
679
+ "merge-descriptors": "1.0.1",
680
+ "methods": "~1.1.2",
681
+ "on-finished": "2.4.1",
682
+ "parseurl": "~1.3.3",
683
+ "path-to-regexp": "0.1.7",
684
+ "proxy-addr": "~2.0.7",
685
+ "qs": "6.11.0",
686
+ "range-parser": "~1.2.1",
687
+ "safe-buffer": "5.2.1",
688
+ "send": "0.18.0",
689
+ "serve-static": "1.15.0",
690
+ "setprototypeof": "1.2.0",
691
+ "statuses": "2.0.1",
692
+ "type-is": "~1.6.18",
693
+ "utils-merge": "1.0.1",
694
+ "vary": "~1.1.2"
695
+ },
696
+ "engines": {
697
+ "node": ">= 0.10.0"
698
+ }
699
+ },
700
+ "node_modules/express-fileupload": {
701
+ "version": "1.4.0",
702
+ "license": "MIT",
703
+ "dependencies": {
704
+ "busboy": "^1.6.0"
705
+ },
706
+ "engines": {
707
+ "node": ">=12.0.0"
708
+ }
709
+ },
710
+ "node_modules/extract-zip": {
711
+ "version": "2.0.1",
712
+ "license": "BSD-2-Clause",
713
+ "dependencies": {
714
+ "debug": "^4.1.1",
715
+ "get-stream": "^5.1.0",
716
+ "yauzl": "^2.10.0"
717
+ },
718
+ "bin": {
719
+ "extract-zip": "cli.js"
720
+ },
721
+ "engines": {
722
+ "node": ">= 10.17.0"
723
+ },
724
+ "optionalDependencies": {
725
+ "@types/yauzl": "^2.9.1"
726
+ }
727
+ },
728
+ "node_modules/extract-zip/node_modules/debug": {
729
+ "version": "4.3.4",
730
+ "license": "MIT",
731
+ "dependencies": {
732
+ "ms": "2.1.2"
733
+ },
734
+ "engines": {
735
+ "node": ">=6.0"
736
+ },
737
+ "peerDependenciesMeta": {
738
+ "supports-color": {
739
+ "optional": true
740
+ }
741
+ }
742
+ },
743
+ "node_modules/extract-zip/node_modules/ms": {
744
+ "version": "2.1.2",
745
+ "license": "MIT"
746
+ },
747
+ "node_modules/fast-fifo": {
748
+ "version": "1.3.2",
749
+ "license": "MIT"
750
+ },
751
+ "node_modules/fast-glob": {
752
+ "version": "3.3.1",
753
+ "license": "MIT",
754
+ "dependencies": {
755
+ "@nodelib/fs.stat": "^2.0.2",
756
+ "@nodelib/fs.walk": "^1.2.3",
757
+ "glob-parent": "^5.1.2",
758
+ "merge2": "^1.3.0",
759
+ "micromatch": "^4.0.4"
760
+ },
761
+ "engines": {
762
+ "node": ">=8.6.0"
763
+ }
764
+ },
765
+ "node_modules/fastq": {
766
+ "version": "1.15.0",
767
+ "license": "ISC",
768
+ "dependencies": {
769
+ "reusify": "^1.0.4"
770
+ }
771
+ },
772
+ "node_modules/fd-slicer": {
773
+ "version": "1.1.0",
774
+ "license": "MIT",
775
+ "dependencies": {
776
+ "pend": "~1.2.0"
777
+ }
778
+ },
779
+ "node_modules/fetch-blob": {
780
+ "version": "3.2.0",
781
+ "funding": [
782
+ {
783
+ "type": "github",
784
+ "url": "https://github.com/sponsors/jimmywarting"
785
+ },
786
+ {
787
+ "type": "paypal",
788
+ "url": "https://paypal.me/jimmywarting"
789
+ }
790
+ ],
791
+ "license": "MIT",
792
+ "dependencies": {
793
+ "node-domexception": "^1.0.0",
794
+ "web-streams-polyfill": "^3.0.3"
795
+ },
796
+ "engines": {
797
+ "node": "^12.20 || >= 14.13"
798
+ }
799
+ },
800
+ "node_modules/fill-range": {
801
+ "version": "7.0.1",
802
+ "license": "MIT",
803
+ "dependencies": {
804
+ "to-regex-range": "^5.0.1"
805
+ },
806
+ "engines": {
807
+ "node": ">=8"
808
+ }
809
+ },
810
+ "node_modules/finalhandler": {
811
+ "version": "1.2.0",
812
+ "license": "MIT",
813
+ "dependencies": {
814
+ "debug": "2.6.9",
815
+ "encodeurl": "~1.0.2",
816
+ "escape-html": "~1.0.3",
817
+ "on-finished": "2.4.1",
818
+ "parseurl": "~1.3.3",
819
+ "statuses": "2.0.1",
820
+ "unpipe": "~1.0.0"
821
+ },
822
+ "engines": {
823
+ "node": ">= 0.8"
824
+ }
825
+ },
826
+ "node_modules/fluent-ffmpeg": {
827
+ "version": "2.1.2",
828
+ "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz",
829
+ "integrity": "sha512-IZTB4kq5GK0DPp7sGQ0q/BWurGHffRtQQwVkiqDgeO6wYJLLV5ZhgNOQ65loZxxuPMKZKZcICCUnaGtlxBiR0Q==",
830
+ "dependencies": {
831
+ "async": ">=0.2.9",
832
+ "which": "^1.1.1"
833
+ },
834
+ "engines": {
835
+ "node": ">=0.8.0"
836
+ }
837
+ },
838
+ "node_modules/formdata-polyfill": {
839
+ "version": "4.0.10",
840
+ "license": "MIT",
841
+ "dependencies": {
842
+ "fetch-blob": "^3.1.2"
843
+ },
844
+ "engines": {
845
+ "node": ">=12.20.0"
846
+ }
847
+ },
848
+ "node_modules/forwarded": {
849
+ "version": "0.2.0",
850
+ "license": "MIT",
851
+ "engines": {
852
+ "node": ">= 0.6"
853
+ }
854
+ },
855
+ "node_modules/fresh": {
856
+ "version": "0.5.2",
857
+ "license": "MIT",
858
+ "engines": {
859
+ "node": ">= 0.6"
860
+ }
861
+ },
862
+ "node_modules/fs-constants": {
863
+ "version": "1.0.0",
864
+ "license": "MIT"
865
+ },
866
+ "node_modules/fs-extra": {
867
+ "version": "11.1.1",
868
+ "license": "MIT",
869
+ "dependencies": {
870
+ "graceful-fs": "^4.2.0",
871
+ "jsonfile": "^6.0.1",
872
+ "universalify": "^2.0.0"
873
+ },
874
+ "engines": {
875
+ "node": ">=14.14"
876
+ }
877
+ },
878
+ "node_modules/fs.realpath": {
879
+ "version": "1.0.0",
880
+ "license": "ISC"
881
+ },
882
+ "node_modules/function-bind": {
883
+ "version": "1.1.1",
884
+ "license": "MIT"
885
+ },
886
+ "node_modules/get-intrinsic": {
887
+ "version": "1.2.1",
888
+ "license": "MIT",
889
+ "dependencies": {
890
+ "function-bind": "^1.1.1",
891
+ "has": "^1.0.3",
892
+ "has-proto": "^1.0.1",
893
+ "has-symbols": "^1.0.3"
894
+ },
895
+ "funding": {
896
+ "url": "https://github.com/sponsors/ljharb"
897
+ }
898
+ },
899
+ "node_modules/get-stream": {
900
+ "version": "5.2.0",
901
+ "license": "MIT",
902
+ "dependencies": {
903
+ "pump": "^3.0.0"
904
+ },
905
+ "engines": {
906
+ "node": ">=8"
907
+ },
908
+ "funding": {
909
+ "url": "https://github.com/sponsors/sindresorhus"
910
+ }
911
+ },
912
+ "node_modules/github-from-package": {
913
+ "version": "0.0.0",
914
+ "license": "MIT"
915
+ },
916
+ "node_modules/github-url-to-object": {
917
+ "version": "4.0.6",
918
+ "license": "MIT",
919
+ "dependencies": {
920
+ "is-url": "^1.1.0"
921
+ }
922
+ },
923
+ "node_modules/glob": {
924
+ "version": "8.1.0",
925
+ "license": "ISC",
926
+ "dependencies": {
927
+ "fs.realpath": "^1.0.0",
928
+ "inflight": "^1.0.4",
929
+ "inherits": "2",
930
+ "minimatch": "^5.0.1",
931
+ "once": "^1.3.0"
932
+ },
933
+ "engines": {
934
+ "node": ">=12"
935
+ },
936
+ "funding": {
937
+ "url": "https://github.com/sponsors/isaacs"
938
+ }
939
+ },
940
+ "node_modules/glob-parent": {
941
+ "version": "5.1.2",
942
+ "license": "ISC",
943
+ "dependencies": {
944
+ "is-glob": "^4.0.1"
945
+ },
946
+ "engines": {
947
+ "node": ">= 6"
948
+ }
949
+ },
950
+ "node_modules/graceful-fs": {
951
+ "version": "4.2.11",
952
+ "license": "ISC"
953
+ },
954
+ "node_modules/has": {
955
+ "version": "1.0.3",
956
+ "license": "MIT",
957
+ "dependencies": {
958
+ "function-bind": "^1.1.1"
959
+ },
960
+ "engines": {
961
+ "node": ">= 0.4.0"
962
+ }
963
+ },
964
+ "node_modules/has-proto": {
965
+ "version": "1.0.1",
966
+ "license": "MIT",
967
+ "engines": {
968
+ "node": ">= 0.4"
969
+ },
970
+ "funding": {
971
+ "url": "https://github.com/sponsors/ljharb"
972
+ }
973
+ },
974
+ "node_modules/has-symbols": {
975
+ "version": "1.0.3",
976
+ "license": "MIT",
977
+ "engines": {
978
+ "node": ">= 0.4"
979
+ },
980
+ "funding": {
981
+ "url": "https://github.com/sponsors/ljharb"
982
+ }
983
+ },
984
+ "node_modules/http-errors": {
985
+ "version": "2.0.0",
986
+ "license": "MIT",
987
+ "dependencies": {
988
+ "depd": "2.0.0",
989
+ "inherits": "2.0.4",
990
+ "setprototypeof": "1.2.0",
991
+ "statuses": "2.0.1",
992
+ "toidentifier": "1.0.1"
993
+ },
994
+ "engines": {
995
+ "node": ">= 0.8"
996
+ }
997
+ },
998
+ "node_modules/iconv-lite": {
999
+ "version": "0.4.24",
1000
+ "license": "MIT",
1001
+ "dependencies": {
1002
+ "safer-buffer": ">= 2.1.2 < 3"
1003
+ },
1004
+ "engines": {
1005
+ "node": ">=0.10.0"
1006
+ }
1007
+ },
1008
+ "node_modules/ieee754": {
1009
+ "version": "1.2.1",
1010
+ "funding": [
1011
+ {
1012
+ "type": "github",
1013
+ "url": "https://github.com/sponsors/feross"
1014
+ },
1015
+ {
1016
+ "type": "patreon",
1017
+ "url": "https://www.patreon.com/feross"
1018
+ },
1019
+ {
1020
+ "type": "consulting",
1021
+ "url": "https://feross.org/support"
1022
+ }
1023
+ ],
1024
+ "license": "BSD-3-Clause"
1025
+ },
1026
+ "node_modules/inflight": {
1027
+ "version": "1.0.6",
1028
+ "license": "ISC",
1029
+ "dependencies": {
1030
+ "once": "^1.3.0",
1031
+ "wrappy": "1"
1032
+ }
1033
+ },
1034
+ "node_modules/inherits": {
1035
+ "version": "2.0.4",
1036
+ "license": "ISC"
1037
+ },
1038
+ "node_modules/ini": {
1039
+ "version": "1.3.8",
1040
+ "license": "ISC"
1041
+ },
1042
+ "node_modules/ipaddr.js": {
1043
+ "version": "1.9.1",
1044
+ "license": "MIT",
1045
+ "engines": {
1046
+ "node": ">= 0.10"
1047
+ }
1048
+ },
1049
+ "node_modules/is-arrayish": {
1050
+ "version": "0.3.2",
1051
+ "license": "MIT"
1052
+ },
1053
+ "node_modules/is-extglob": {
1054
+ "version": "2.1.1",
1055
+ "license": "MIT",
1056
+ "engines": {
1057
+ "node": ">=0.10.0"
1058
+ }
1059
+ },
1060
+ "node_modules/is-glob": {
1061
+ "version": "4.0.3",
1062
+ "license": "MIT",
1063
+ "dependencies": {
1064
+ "is-extglob": "^2.1.1"
1065
+ },
1066
+ "engines": {
1067
+ "node": ">=0.10.0"
1068
+ }
1069
+ },
1070
+ "node_modules/is-number": {
1071
+ "version": "7.0.0",
1072
+ "license": "MIT",
1073
+ "engines": {
1074
+ "node": ">=0.12.0"
1075
+ }
1076
+ },
1077
+ "node_modules/is-url": {
1078
+ "version": "1.2.4",
1079
+ "license": "MIT"
1080
+ },
1081
+ "node_modules/isarray": {
1082
+ "version": "1.0.0",
1083
+ "license": "MIT"
1084
+ },
1085
+ "node_modules/isexe": {
1086
+ "version": "2.0.0",
1087
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
1088
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
1089
+ },
1090
+ "node_modules/jsonfile": {
1091
+ "version": "6.1.0",
1092
+ "license": "MIT",
1093
+ "dependencies": {
1094
+ "universalify": "^2.0.0"
1095
+ },
1096
+ "optionalDependencies": {
1097
+ "graceful-fs": "^4.1.6"
1098
+ }
1099
+ },
1100
+ "node_modules/lazystream": {
1101
+ "version": "1.0.1",
1102
+ "license": "MIT",
1103
+ "dependencies": {
1104
+ "readable-stream": "^2.0.5"
1105
+ },
1106
+ "engines": {
1107
+ "node": ">= 0.6.3"
1108
+ }
1109
+ },
1110
+ "node_modules/lazystream/node_modules/readable-stream": {
1111
+ "version": "2.3.8",
1112
+ "license": "MIT",
1113
+ "dependencies": {
1114
+ "core-util-is": "~1.0.0",
1115
+ "inherits": "~2.0.3",
1116
+ "isarray": "~1.0.0",
1117
+ "process-nextick-args": "~2.0.0",
1118
+ "safe-buffer": "~5.1.1",
1119
+ "string_decoder": "~1.1.1",
1120
+ "util-deprecate": "~1.0.1"
1121
+ }
1122
+ },
1123
+ "node_modules/lazystream/node_modules/safe-buffer": {
1124
+ "version": "5.1.2",
1125
+ "license": "MIT"
1126
+ },
1127
+ "node_modules/lazystream/node_modules/string_decoder": {
1128
+ "version": "1.1.1",
1129
+ "license": "MIT",
1130
+ "dependencies": {
1131
+ "safe-buffer": "~5.1.0"
1132
+ }
1133
+ },
1134
+ "node_modules/lodash": {
1135
+ "version": "4.17.21",
1136
+ "license": "MIT"
1137
+ },
1138
+ "node_modules/lru-cache": {
1139
+ "version": "6.0.0",
1140
+ "license": "ISC",
1141
+ "dependencies": {
1142
+ "yallist": "^4.0.0"
1143
+ },
1144
+ "engines": {
1145
+ "node": ">=10"
1146
+ }
1147
+ },
1148
+ "node_modules/make-error": {
1149
+ "version": "1.3.6",
1150
+ "license": "ISC"
1151
+ },
1152
+ "node_modules/media-typer": {
1153
+ "version": "0.3.0",
1154
+ "license": "MIT",
1155
+ "engines": {
1156
+ "node": ">= 0.6"
1157
+ }
1158
+ },
1159
+ "node_modules/merge-descriptors": {
1160
+ "version": "1.0.1",
1161
+ "license": "MIT"
1162
+ },
1163
+ "node_modules/merge2": {
1164
+ "version": "1.4.1",
1165
+ "license": "MIT",
1166
+ "engines": {
1167
+ "node": ">= 8"
1168
+ }
1169
+ },
1170
+ "node_modules/methods": {
1171
+ "version": "1.1.2",
1172
+ "license": "MIT",
1173
+ "engines": {
1174
+ "node": ">= 0.6"
1175
+ }
1176
+ },
1177
+ "node_modules/micromatch": {
1178
+ "version": "4.0.5",
1179
+ "license": "MIT",
1180
+ "dependencies": {
1181
+ "braces": "^3.0.2",
1182
+ "picomatch": "^2.3.1"
1183
+ },
1184
+ "engines": {
1185
+ "node": ">=8.6"
1186
+ }
1187
+ },
1188
+ "node_modules/mime": {
1189
+ "version": "1.6.0",
1190
+ "license": "MIT",
1191
+ "bin": {
1192
+ "mime": "cli.js"
1193
+ },
1194
+ "engines": {
1195
+ "node": ">=4"
1196
+ }
1197
+ },
1198
+ "node_modules/mime-db": {
1199
+ "version": "1.52.0",
1200
+ "license": "MIT",
1201
+ "engines": {
1202
+ "node": ">= 0.6"
1203
+ }
1204
+ },
1205
+ "node_modules/mime-types": {
1206
+ "version": "2.1.35",
1207
+ "license": "MIT",
1208
+ "dependencies": {
1209
+ "mime-db": "1.52.0"
1210
+ },
1211
+ "engines": {
1212
+ "node": ">= 0.6"
1213
+ }
1214
+ },
1215
+ "node_modules/mimic-response": {
1216
+ "version": "3.1.0",
1217
+ "license": "MIT",
1218
+ "engines": {
1219
+ "node": ">=10"
1220
+ },
1221
+ "funding": {
1222
+ "url": "https://github.com/sponsors/sindresorhus"
1223
+ }
1224
+ },
1225
+ "node_modules/minimatch": {
1226
+ "version": "5.1.6",
1227
+ "license": "ISC",
1228
+ "dependencies": {
1229
+ "brace-expansion": "^2.0.1"
1230
+ },
1231
+ "engines": {
1232
+ "node": ">=10"
1233
+ }
1234
+ },
1235
+ "node_modules/minimist": {
1236
+ "version": "1.2.8",
1237
+ "license": "MIT",
1238
+ "funding": {
1239
+ "url": "https://github.com/sponsors/ljharb"
1240
+ }
1241
+ },
1242
+ "node_modules/mkdirp-classic": {
1243
+ "version": "0.5.3",
1244
+ "license": "MIT"
1245
+ },
1246
+ "node_modules/ms": {
1247
+ "version": "2.0.0",
1248
+ "license": "MIT"
1249
+ },
1250
+ "node_modules/mustache": {
1251
+ "version": "3.2.1",
1252
+ "license": "MIT",
1253
+ "bin": {
1254
+ "mustache": "bin/mustache"
1255
+ },
1256
+ "engines": {
1257
+ "npm": ">=1.4.0"
1258
+ }
1259
+ },
1260
+ "node_modules/napi-build-utils": {
1261
+ "version": "1.0.2",
1262
+ "license": "MIT"
1263
+ },
1264
+ "node_modules/negotiator": {
1265
+ "version": "0.6.3",
1266
+ "license": "MIT",
1267
+ "engines": {
1268
+ "node": ">= 0.6"
1269
+ }
1270
+ },
1271
+ "node_modules/node-abi": {
1272
+ "version": "3.47.0",
1273
+ "license": "MIT",
1274
+ "dependencies": {
1275
+ "semver": "^7.3.5"
1276
+ },
1277
+ "engines": {
1278
+ "node": ">=10"
1279
+ }
1280
+ },
1281
+ "node_modules/node-addon-api": {
1282
+ "version": "6.1.0",
1283
+ "license": "MIT"
1284
+ },
1285
+ "node_modules/node-domexception": {
1286
+ "version": "1.0.0",
1287
+ "funding": [
1288
+ {
1289
+ "type": "github",
1290
+ "url": "https://github.com/sponsors/jimmywarting"
1291
+ },
1292
+ {
1293
+ "type": "github",
1294
+ "url": "https://paypal.me/jimmywarting"
1295
+ }
1296
+ ],
1297
+ "license": "MIT",
1298
+ "engines": {
1299
+ "node": ">=10.5.0"
1300
+ }
1301
+ },
1302
+ "node_modules/node-fetch": {
1303
+ "version": "3.3.2",
1304
+ "license": "MIT",
1305
+ "dependencies": {
1306
+ "data-uri-to-buffer": "^4.0.0",
1307
+ "fetch-blob": "^3.1.4",
1308
+ "formdata-polyfill": "^4.0.10"
1309
+ },
1310
+ "engines": {
1311
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
1312
+ },
1313
+ "funding": {
1314
+ "type": "opencollective",
1315
+ "url": "https://opencollective.com/node-fetch"
1316
+ }
1317
+ },
1318
+ "node_modules/normalize-path": {
1319
+ "version": "3.0.0",
1320
+ "license": "MIT",
1321
+ "engines": {
1322
+ "node": ">=0.10.0"
1323
+ }
1324
+ },
1325
+ "node_modules/object-inspect": {
1326
+ "version": "1.12.3",
1327
+ "license": "MIT",
1328
+ "funding": {
1329
+ "url": "https://github.com/sponsors/ljharb"
1330
+ }
1331
+ },
1332
+ "node_modules/on-finished": {
1333
+ "version": "2.4.1",
1334
+ "license": "MIT",
1335
+ "dependencies": {
1336
+ "ee-first": "1.1.1"
1337
+ },
1338
+ "engines": {
1339
+ "node": ">= 0.8"
1340
+ }
1341
+ },
1342
+ "node_modules/once": {
1343
+ "version": "1.4.0",
1344
+ "license": "ISC",
1345
+ "dependencies": {
1346
+ "wrappy": "1"
1347
+ }
1348
+ },
1349
+ "node_modules/parseurl": {
1350
+ "version": "1.3.3",
1351
+ "license": "MIT",
1352
+ "engines": {
1353
+ "node": ">= 0.8"
1354
+ }
1355
+ },
1356
+ "node_modules/path-to-regexp": {
1357
+ "version": "0.1.7",
1358
+ "license": "MIT"
1359
+ },
1360
+ "node_modules/pend": {
1361
+ "version": "1.2.0",
1362
+ "license": "MIT"
1363
+ },
1364
+ "node_modules/picomatch": {
1365
+ "version": "2.3.1",
1366
+ "license": "MIT",
1367
+ "engines": {
1368
+ "node": ">=8.6"
1369
+ },
1370
+ "funding": {
1371
+ "url": "https://github.com/sponsors/jonschlinkert"
1372
+ }
1373
+ },
1374
+ "node_modules/prebuild-install": {
1375
+ "version": "7.1.1",
1376
+ "license": "MIT",
1377
+ "dependencies": {
1378
+ "detect-libc": "^2.0.0",
1379
+ "expand-template": "^2.0.3",
1380
+ "github-from-package": "0.0.0",
1381
+ "minimist": "^1.2.3",
1382
+ "mkdirp-classic": "^0.5.3",
1383
+ "napi-build-utils": "^1.0.1",
1384
+ "node-abi": "^3.3.0",
1385
+ "pump": "^3.0.0",
1386
+ "rc": "^1.2.7",
1387
+ "simple-get": "^4.0.0",
1388
+ "tar-fs": "^2.0.0",
1389
+ "tunnel-agent": "^0.6.0"
1390
+ },
1391
+ "bin": {
1392
+ "prebuild-install": "bin.js"
1393
+ },
1394
+ "engines": {
1395
+ "node": ">=10"
1396
+ }
1397
+ },
1398
+ "node_modules/prebuild-install/node_modules/tar-fs": {
1399
+ "version": "2.1.1",
1400
+ "license": "MIT",
1401
+ "dependencies": {
1402
+ "chownr": "^1.1.1",
1403
+ "mkdirp-classic": "^0.5.2",
1404
+ "pump": "^3.0.0",
1405
+ "tar-stream": "^2.1.4"
1406
+ }
1407
+ },
1408
+ "node_modules/prebuild-install/node_modules/tar-stream": {
1409
+ "version": "2.2.0",
1410
+ "license": "MIT",
1411
+ "dependencies": {
1412
+ "bl": "^4.0.3",
1413
+ "end-of-stream": "^1.4.1",
1414
+ "fs-constants": "^1.0.0",
1415
+ "inherits": "^2.0.3",
1416
+ "readable-stream": "^3.1.1"
1417
+ },
1418
+ "engines": {
1419
+ "node": ">=6"
1420
+ }
1421
+ },
1422
+ "node_modules/process-nextick-args": {
1423
+ "version": "2.0.1",
1424
+ "license": "MIT"
1425
+ },
1426
+ "node_modules/proxy-addr": {
1427
+ "version": "2.0.7",
1428
+ "license": "MIT",
1429
+ "dependencies": {
1430
+ "forwarded": "0.2.0",
1431
+ "ipaddr.js": "1.9.1"
1432
+ },
1433
+ "engines": {
1434
+ "node": ">= 0.10"
1435
+ }
1436
+ },
1437
+ "node_modules/pump": {
1438
+ "version": "3.0.0",
1439
+ "license": "MIT",
1440
+ "dependencies": {
1441
+ "end-of-stream": "^1.1.0",
1442
+ "once": "^1.3.1"
1443
+ }
1444
+ },
1445
+ "node_modules/qs": {
1446
+ "version": "6.11.0",
1447
+ "license": "BSD-3-Clause",
1448
+ "dependencies": {
1449
+ "side-channel": "^1.0.4"
1450
+ },
1451
+ "engines": {
1452
+ "node": ">=0.6"
1453
+ },
1454
+ "funding": {
1455
+ "url": "https://github.com/sponsors/ljharb"
1456
+ }
1457
+ },
1458
+ "node_modules/queue-microtask": {
1459
+ "version": "1.2.3",
1460
+ "funding": [
1461
+ {
1462
+ "type": "github",
1463
+ "url": "https://github.com/sponsors/feross"
1464
+ },
1465
+ {
1466
+ "type": "patreon",
1467
+ "url": "https://www.patreon.com/feross"
1468
+ },
1469
+ {
1470
+ "type": "consulting",
1471
+ "url": "https://feross.org/support"
1472
+ }
1473
+ ],
1474
+ "license": "MIT"
1475
+ },
1476
+ "node_modules/queue-tick": {
1477
+ "version": "1.0.1",
1478
+ "license": "MIT"
1479
+ },
1480
+ "node_modules/range-parser": {
1481
+ "version": "1.2.1",
1482
+ "license": "MIT",
1483
+ "engines": {
1484
+ "node": ">= 0.6"
1485
+ }
1486
+ },
1487
+ "node_modules/raw-body": {
1488
+ "version": "2.5.1",
1489
+ "license": "MIT",
1490
+ "dependencies": {
1491
+ "bytes": "3.1.2",
1492
+ "http-errors": "2.0.0",
1493
+ "iconv-lite": "0.4.24",
1494
+ "unpipe": "1.0.0"
1495
+ },
1496
+ "engines": {
1497
+ "node": ">= 0.8"
1498
+ }
1499
+ },
1500
+ "node_modules/rc": {
1501
+ "version": "1.2.8",
1502
+ "license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
1503
+ "dependencies": {
1504
+ "deep-extend": "^0.6.0",
1505
+ "ini": "~1.3.0",
1506
+ "minimist": "^1.2.0",
1507
+ "strip-json-comments": "~2.0.1"
1508
+ },
1509
+ "bin": {
1510
+ "rc": "cli.js"
1511
+ }
1512
+ },
1513
+ "node_modules/readable-stream": {
1514
+ "version": "3.6.2",
1515
+ "license": "MIT",
1516
+ "dependencies": {
1517
+ "inherits": "^2.0.3",
1518
+ "string_decoder": "^1.1.1",
1519
+ "util-deprecate": "^1.0.1"
1520
+ },
1521
+ "engines": {
1522
+ "node": ">= 6"
1523
+ }
1524
+ },
1525
+ "node_modules/readdir-glob": {
1526
+ "version": "1.1.3",
1527
+ "license": "Apache-2.0",
1528
+ "dependencies": {
1529
+ "minimatch": "^5.1.0"
1530
+ }
1531
+ },
1532
+ "node_modules/require-all": {
1533
+ "version": "3.0.0",
1534
+ "license": "MIT",
1535
+ "engines": {
1536
+ "node": ">= 0.8"
1537
+ }
1538
+ },
1539
+ "node_modules/resize-base64": {
1540
+ "version": "1.0.12",
1541
+ "license": "ISC",
1542
+ "dependencies": {
1543
+ "create-readme": "^1.1.0"
1544
+ }
1545
+ },
1546
+ "node_modules/reusify": {
1547
+ "version": "1.0.4",
1548
+ "license": "MIT",
1549
+ "engines": {
1550
+ "iojs": ">=1.0.0",
1551
+ "node": ">=0.10.0"
1552
+ }
1553
+ },
1554
+ "node_modules/run-parallel": {
1555
+ "version": "1.2.0",
1556
+ "funding": [
1557
+ {
1558
+ "type": "github",
1559
+ "url": "https://github.com/sponsors/feross"
1560
+ },
1561
+ {
1562
+ "type": "patreon",
1563
+ "url": "https://www.patreon.com/feross"
1564
+ },
1565
+ {
1566
+ "type": "consulting",
1567
+ "url": "https://feross.org/support"
1568
+ }
1569
+ ],
1570
+ "license": "MIT",
1571
+ "dependencies": {
1572
+ "queue-microtask": "^1.2.2"
1573
+ }
1574
+ },
1575
+ "node_modules/safe-buffer": {
1576
+ "version": "5.2.1",
1577
+ "funding": [
1578
+ {
1579
+ "type": "github",
1580
+ "url": "https://github.com/sponsors/feross"
1581
+ },
1582
+ {
1583
+ "type": "patreon",
1584
+ "url": "https://www.patreon.com/feross"
1585
+ },
1586
+ {
1587
+ "type": "consulting",
1588
+ "url": "https://feross.org/support"
1589
+ }
1590
+ ],
1591
+ "license": "MIT"
1592
+ },
1593
+ "node_modules/safer-buffer": {
1594
+ "version": "2.1.2",
1595
+ "license": "MIT"
1596
+ },
1597
+ "node_modules/semver": {
1598
+ "version": "7.5.4",
1599
+ "license": "ISC",
1600
+ "dependencies": {
1601
+ "lru-cache": "^6.0.0"
1602
+ },
1603
+ "bin": {
1604
+ "semver": "bin/semver.js"
1605
+ },
1606
+ "engines": {
1607
+ "node": ">=10"
1608
+ }
1609
+ },
1610
+ "node_modules/send": {
1611
+ "version": "0.18.0",
1612
+ "license": "MIT",
1613
+ "dependencies": {
1614
+ "debug": "2.6.9",
1615
+ "depd": "2.0.0",
1616
+ "destroy": "1.2.0",
1617
+ "encodeurl": "~1.0.2",
1618
+ "escape-html": "~1.0.3",
1619
+ "etag": "~1.8.1",
1620
+ "fresh": "0.5.2",
1621
+ "http-errors": "2.0.0",
1622
+ "mime": "1.6.0",
1623
+ "ms": "2.1.3",
1624
+ "on-finished": "2.4.1",
1625
+ "range-parser": "~1.2.1",
1626
+ "statuses": "2.0.1"
1627
+ },
1628
+ "engines": {
1629
+ "node": ">= 0.8.0"
1630
+ }
1631
+ },
1632
+ "node_modules/send/node_modules/ms": {
1633
+ "version": "2.1.3",
1634
+ "license": "MIT"
1635
+ },
1636
+ "node_modules/serve-static": {
1637
+ "version": "1.15.0",
1638
+ "license": "MIT",
1639
+ "dependencies": {
1640
+ "encodeurl": "~1.0.2",
1641
+ "escape-html": "~1.0.3",
1642
+ "parseurl": "~1.3.3",
1643
+ "send": "0.18.0"
1644
+ },
1645
+ "engines": {
1646
+ "node": ">= 0.8.0"
1647
+ }
1648
+ },
1649
+ "node_modules/setprototypeof": {
1650
+ "version": "1.2.0",
1651
+ "license": "ISC"
1652
+ },
1653
+ "node_modules/sharp": {
1654
+ "version": "0.32.6",
1655
+ "hasInstallScript": true,
1656
+ "license": "Apache-2.0",
1657
+ "dependencies": {
1658
+ "color": "^4.2.3",
1659
+ "detect-libc": "^2.0.2",
1660
+ "node-addon-api": "^6.1.0",
1661
+ "prebuild-install": "^7.1.1",
1662
+ "semver": "^7.5.4",
1663
+ "simple-get": "^4.0.1",
1664
+ "tar-fs": "^3.0.4",
1665
+ "tunnel-agent": "^0.6.0"
1666
+ },
1667
+ "engines": {
1668
+ "node": ">=14.15.0"
1669
+ },
1670
+ "funding": {
1671
+ "url": "https://opencollective.com/libvips"
1672
+ }
1673
+ },
1674
+ "node_modules/side-channel": {
1675
+ "version": "1.0.4",
1676
+ "license": "MIT",
1677
+ "dependencies": {
1678
+ "call-bind": "^1.0.0",
1679
+ "get-intrinsic": "^1.0.2",
1680
+ "object-inspect": "^1.9.0"
1681
+ },
1682
+ "funding": {
1683
+ "url": "https://github.com/sponsors/ljharb"
1684
+ }
1685
+ },
1686
+ "node_modules/simple-concat": {
1687
+ "version": "1.0.1",
1688
+ "funding": [
1689
+ {
1690
+ "type": "github",
1691
+ "url": "https://github.com/sponsors/feross"
1692
+ },
1693
+ {
1694
+ "type": "patreon",
1695
+ "url": "https://www.patreon.com/feross"
1696
+ },
1697
+ {
1698
+ "type": "consulting",
1699
+ "url": "https://feross.org/support"
1700
+ }
1701
+ ],
1702
+ "license": "MIT"
1703
+ },
1704
+ "node_modules/simple-get": {
1705
+ "version": "4.0.1",
1706
+ "funding": [
1707
+ {
1708
+ "type": "github",
1709
+ "url": "https://github.com/sponsors/feross"
1710
+ },
1711
+ {
1712
+ "type": "patreon",
1713
+ "url": "https://www.patreon.com/feross"
1714
+ },
1715
+ {
1716
+ "type": "consulting",
1717
+ "url": "https://feross.org/support"
1718
+ }
1719
+ ],
1720
+ "license": "MIT",
1721
+ "dependencies": {
1722
+ "decompress-response": "^6.0.0",
1723
+ "once": "^1.3.1",
1724
+ "simple-concat": "^1.0.0"
1725
+ }
1726
+ },
1727
+ "node_modules/simple-swizzle": {
1728
+ "version": "0.2.2",
1729
+ "license": "MIT",
1730
+ "dependencies": {
1731
+ "is-arrayish": "^0.3.1"
1732
+ }
1733
+ },
1734
+ "node_modules/statuses": {
1735
+ "version": "2.0.1",
1736
+ "license": "MIT",
1737
+ "engines": {
1738
+ "node": ">= 0.8"
1739
+ }
1740
+ },
1741
+ "node_modules/streamsearch": {
1742
+ "version": "1.1.0",
1743
+ "engines": {
1744
+ "node": ">=10.0.0"
1745
+ }
1746
+ },
1747
+ "node_modules/streamx": {
1748
+ "version": "2.15.1",
1749
+ "license": "MIT",
1750
+ "dependencies": {
1751
+ "fast-fifo": "^1.1.0",
1752
+ "queue-tick": "^1.0.1"
1753
+ }
1754
+ },
1755
+ "node_modules/string_decoder": {
1756
+ "version": "1.3.0",
1757
+ "license": "MIT",
1758
+ "dependencies": {
1759
+ "safe-buffer": "~5.2.0"
1760
+ }
1761
+ },
1762
+ "node_modules/strip-json-comments": {
1763
+ "version": "2.0.1",
1764
+ "license": "MIT",
1765
+ "engines": {
1766
+ "node": ">=0.10.0"
1767
+ }
1768
+ },
1769
+ "node_modules/tar-fs": {
1770
+ "version": "3.0.4",
1771
+ "license": "MIT",
1772
+ "dependencies": {
1773
+ "mkdirp-classic": "^0.5.2",
1774
+ "pump": "^3.0.0",
1775
+ "tar-stream": "^3.1.5"
1776
+ }
1777
+ },
1778
+ "node_modules/tar-stream": {
1779
+ "version": "3.1.6",
1780
+ "license": "MIT",
1781
+ "dependencies": {
1782
+ "b4a": "^1.6.4",
1783
+ "fast-fifo": "^1.2.0",
1784
+ "streamx": "^2.15.0"
1785
+ }
1786
+ },
1787
+ "node_modules/temp-dir": {
1788
+ "version": "3.0.0",
1789
+ "license": "MIT",
1790
+ "engines": {
1791
+ "node": ">=14.16"
1792
+ }
1793
+ },
1794
+ "node_modules/to-regex-range": {
1795
+ "version": "5.0.1",
1796
+ "license": "MIT",
1797
+ "dependencies": {
1798
+ "is-number": "^7.0.0"
1799
+ },
1800
+ "engines": {
1801
+ "node": ">=8.0"
1802
+ }
1803
+ },
1804
+ "node_modules/toidentifier": {
1805
+ "version": "1.0.1",
1806
+ "license": "MIT",
1807
+ "engines": {
1808
+ "node": ">=0.6"
1809
+ }
1810
+ },
1811
+ "node_modules/ts-node": {
1812
+ "version": "10.9.1",
1813
+ "license": "MIT",
1814
+ "dependencies": {
1815
+ "@cspotcode/source-map-support": "^0.8.0",
1816
+ "@tsconfig/node10": "^1.0.7",
1817
+ "@tsconfig/node12": "^1.0.7",
1818
+ "@tsconfig/node14": "^1.0.0",
1819
+ "@tsconfig/node16": "^1.0.2",
1820
+ "acorn": "^8.4.1",
1821
+ "acorn-walk": "^8.1.1",
1822
+ "arg": "^4.1.0",
1823
+ "create-require": "^1.1.0",
1824
+ "diff": "^4.0.1",
1825
+ "make-error": "^1.1.1",
1826
+ "v8-compile-cache-lib": "^3.0.1",
1827
+ "yn": "3.1.1"
1828
+ },
1829
+ "bin": {
1830
+ "ts-node": "dist/bin.js",
1831
+ "ts-node-cwd": "dist/bin-cwd.js",
1832
+ "ts-node-esm": "dist/bin-esm.js",
1833
+ "ts-node-script": "dist/bin-script.js",
1834
+ "ts-node-transpile-only": "dist/bin-transpile.js",
1835
+ "ts-script": "dist/bin-script-deprecated.js"
1836
+ },
1837
+ "peerDependencies": {
1838
+ "@swc/core": ">=1.2.50",
1839
+ "@swc/wasm": ">=1.2.50",
1840
+ "@types/node": "*",
1841
+ "typescript": ">=2.7"
1842
+ },
1843
+ "peerDependenciesMeta": {
1844
+ "@swc/core": {
1845
+ "optional": true
1846
+ },
1847
+ "@swc/wasm": {
1848
+ "optional": true
1849
+ }
1850
+ }
1851
+ },
1852
+ "node_modules/tunnel-agent": {
1853
+ "version": "0.6.0",
1854
+ "license": "Apache-2.0",
1855
+ "dependencies": {
1856
+ "safe-buffer": "^5.0.1"
1857
+ },
1858
+ "engines": {
1859
+ "node": "*"
1860
+ }
1861
+ },
1862
+ "node_modules/type-is": {
1863
+ "version": "1.6.18",
1864
+ "license": "MIT",
1865
+ "dependencies": {
1866
+ "media-typer": "0.3.0",
1867
+ "mime-types": "~2.1.24"
1868
+ },
1869
+ "engines": {
1870
+ "node": ">= 0.6"
1871
+ }
1872
+ },
1873
+ "node_modules/typescript": {
1874
+ "version": "5.2.2",
1875
+ "license": "Apache-2.0",
1876
+ "peer": true,
1877
+ "bin": {
1878
+ "tsc": "bin/tsc",
1879
+ "tsserver": "bin/tsserver"
1880
+ },
1881
+ "engines": {
1882
+ "node": ">=14.17"
1883
+ }
1884
+ },
1885
+ "node_modules/universalify": {
1886
+ "version": "2.0.0",
1887
+ "license": "MIT",
1888
+ "engines": {
1889
+ "node": ">= 10.0.0"
1890
+ }
1891
+ },
1892
+ "node_modules/unpipe": {
1893
+ "version": "1.0.0",
1894
+ "license": "MIT",
1895
+ "engines": {
1896
+ "node": ">= 0.8"
1897
+ }
1898
+ },
1899
+ "node_modules/util-deprecate": {
1900
+ "version": "1.0.2",
1901
+ "license": "MIT"
1902
+ },
1903
+ "node_modules/utils-merge": {
1904
+ "version": "1.0.1",
1905
+ "license": "MIT",
1906
+ "engines": {
1907
+ "node": ">= 0.4.0"
1908
+ }
1909
+ },
1910
+ "node_modules/uuid": {
1911
+ "version": "9.0.1",
1912
+ "funding": [
1913
+ "https://github.com/sponsors/broofa",
1914
+ "https://github.com/sponsors/ctavan"
1915
+ ],
1916
+ "license": "MIT",
1917
+ "bin": {
1918
+ "uuid": "dist/bin/uuid"
1919
+ }
1920
+ },
1921
+ "node_modules/v8-compile-cache-lib": {
1922
+ "version": "3.0.1",
1923
+ "license": "MIT"
1924
+ },
1925
+ "node_modules/vary": {
1926
+ "version": "1.1.2",
1927
+ "license": "MIT",
1928
+ "engines": {
1929
+ "node": ">= 0.8"
1930
+ }
1931
+ },
1932
+ "node_modules/web-streams-polyfill": {
1933
+ "version": "3.2.1",
1934
+ "license": "MIT",
1935
+ "engines": {
1936
+ "node": ">= 8"
1937
+ }
1938
+ },
1939
+ "node_modules/which": {
1940
+ "version": "1.3.1",
1941
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
1942
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
1943
+ "dependencies": {
1944
+ "isexe": "^2.0.0"
1945
+ },
1946
+ "bin": {
1947
+ "which": "bin/which"
1948
+ }
1949
+ },
1950
+ "node_modules/wrappy": {
1951
+ "version": "1.0.2",
1952
+ "license": "ISC"
1953
+ },
1954
+ "node_modules/yallist": {
1955
+ "version": "4.0.0",
1956
+ "license": "ISC"
1957
+ },
1958
+ "node_modules/yaml": {
1959
+ "version": "2.3.2",
1960
+ "license": "ISC",
1961
+ "engines": {
1962
+ "node": ">= 14"
1963
+ }
1964
+ },
1965
+ "node_modules/yauzl": {
1966
+ "version": "2.10.0",
1967
+ "license": "MIT",
1968
+ "dependencies": {
1969
+ "buffer-crc32": "~0.2.3",
1970
+ "fd-slicer": "~1.1.0"
1971
+ }
1972
+ },
1973
+ "node_modules/yn": {
1974
+ "version": "3.1.1",
1975
+ "license": "MIT",
1976
+ "engines": {
1977
+ "node": ">=6"
1978
+ }
1979
+ },
1980
+ "node_modules/zip-stream": {
1981
+ "version": "5.0.1",
1982
+ "license": "MIT",
1983
+ "dependencies": {
1984
+ "archiver-utils": "^4.0.1",
1985
+ "compress-commons": "^5.0.1",
1986
+ "readable-stream": "^3.6.0"
1987
+ },
1988
+ "engines": {
1989
+ "node": ">= 12.0.0"
1990
+ }
1991
+ }
1992
+ }
1993
+ }
package.json ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "@jbilcke-hf/campose-api",
3
+ "version": "1.0.0",
4
+ "description": "Generate camera pose data from a set of images or a video.",
5
+ "main": "src/index.mts",
6
+ "scripts": {
7
+ "start": "node --loader ts-node/esm src/index.mts",
8
+ "docker": "npm run docker:build && npm run docker:run",
9
+ "docker:build": "docker build -t campose-api .",
10
+ "docker:run": "docker run -it -p 7860:7860 campose-api"
11
+ },
12
+ "author": "Julian Bilcke <[email protected]>",
13
+ "license": "Apache License",
14
+ "dependencies": {
15
+ "@gorgonjs/file-provider": "^1.4.1",
16
+ "@gorgonjs/gorgon": "^1.4.1",
17
+ "@types/express": "^4.17.17",
18
+ "@types/uuid": "^9.0.2",
19
+ "archiver": "^6.0.1",
20
+ "eventsource-parser": "^1.0.0",
21
+ "express": "^4.18.2",
22
+ "express-fileupload": "^1.4.0",
23
+ "extract-zip": "^2.0.1",
24
+ "fluent-ffmpeg": "^2.1.2",
25
+ "fs-extra": "^11.1.1",
26
+ "node-fetch": "^3.3.1",
27
+ "resize-base64": "^1.0.12",
28
+ "sharp": "^0.32.4",
29
+ "temp-dir": "^3.0.0",
30
+ "ts-node": "^10.9.1",
31
+ "uuid": "^9.0.0",
32
+ "yaml": "^2.3.1"
33
+ }
34
+ }
src/colmap.mts ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { exec } from "child_process"
2
+
3
+ /**
4
+ * Interface for the options for the `runColmap` function.
5
+ * See: https://colmap.github.io/cli.html
6
+ */
7
+ export interface ColmapOptions {
8
+ /**
9
+ * The command to run (one of the available commands in COLMAP).
10
+ */
11
+ command: string;
12
+
13
+ /**
14
+ * The path to your project, which must contain a folder "images" with all the images.
15
+ */
16
+ projectPath?: string;
17
+
18
+ /**
19
+ * The workspace path for the project (used in some commands).
20
+ */
21
+ workspacePath?: string;
22
+
23
+ /**
24
+ * The image path for the project (used in some commands).
25
+ */
26
+ imagePath?: string;
27
+
28
+ /**
29
+ * The database path for the project (used in some commands).
30
+ */
31
+ databasePath?: string;
32
+
33
+ /**
34
+ * The output path for the project (used in some commands).
35
+ */
36
+ outputPath?: string;
37
+
38
+ /**
39
+ * Additional parameters that should be passed to the command.
40
+ */
41
+ parameters?: { [key: string]: any };
42
+
43
+ /**
44
+ * If set, forces the program to use CPU-based feature extraction and matching.
45
+ */
46
+ useCPU?: boolean;
47
+ }
48
+
49
+ /**
50
+ * Run COLMAP commands from NodeJS programmatically.
51
+ *
52
+ * @param {ColmapOptions} options A set of configurations to be passed to the application.
53
+ */
54
+ export const runColmap = (options: ColmapOptions): Promise<string> => {
55
+ return new Promise((resolve, reject) => {
56
+ let command = `colmap ${options.command}`;
57
+
58
+ if (options.projectPath) command += ` --project_path ${options.projectPath}`;
59
+ if (options.workspacePath) command += ` --workspace_path ${options.workspacePath}`;
60
+ if (options.imagePath) command += ` --image_path ${options.imagePath}`;
61
+ if (options.databasePath) command += ` --database_path ${options.databasePath}`;
62
+ if (options.outputPath) command += ` --output_path ${options.outputPath}`;
63
+
64
+ // Loop through additional parameters (if any) and add them to the command.
65
+ if (options.parameters) {
66
+ for (let key of Object.keys(options.parameters)) {
67
+ command += ` --${key} ${options.parameters[key]}`;
68
+ }
69
+ }
70
+
71
+ if (options.useCPU) command += ` --SiftExtraction.use_gpu 0 --SiftMatching.use_gpu 0`;
72
+
73
+ exec(command, (error, stdout, stderr) => {
74
+ if (error) {
75
+ reject(stderr);
76
+ } else {
77
+ resolve(stdout);
78
+ }
79
+ });
80
+ });
81
+ };
src/config.mts ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import path from "node:path"
2
+
3
+ export const storagePath = `${process.env.STORAGE_PATH || './sandbox'}`
4
+
5
+ export const inputsDirFilePath = path.join(storagePath, "training_inputs")
6
+ export const outputsDirFilePath = path.join(storagePath, "training_outputs")
7
+
8
+ export const shotFormatVersion = 1
9
+ export const sequenceFormatVersion = 1
src/index.mts ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import express from "express"
2
+ import fileUpload from "express-fileupload"
3
+ import path from "path"
4
+ import os from "os"
5
+ import fs from "fs"
6
+ import archiver from "archiver"
7
+ import ffmpeg from "fluent-ffmpeg"
8
+
9
+ // import { initFolders } from "./initFolders.mts"
10
+ import { runColmap, ColmapOptions } from "./colmap.mts"
11
+
12
+ // initFolders()
13
+
14
+ declare module 'express-serve-static-core' {
15
+ interface Request {
16
+ files: any;
17
+ }
18
+ }
19
+
20
+ const app = express()
21
+ const port = 7860
22
+
23
+ const maxActiveRequests = 4
24
+ let activeRequests = 0
25
+
26
+ app.use(express.json({limit: '50mb'}))
27
+ app.use(express.urlencoded({limit: '50mb', extended: true}))
28
+ app.use(fileUpload())
29
+
30
+ app.post("/", async (req, res) => {
31
+ if (activeRequests >= maxActiveRequests) {
32
+ res.status(503).json({message: "Service Unavailable: Max concurrent requests reached. Please try again later"}).end();
33
+ return
34
+ }
35
+ activeRequests++
36
+
37
+ if (!req.files || !req.files.data || req.files.data.mimetype !== 'video/mp4') {
38
+ res.status(400).json({error: "Missing or invalid data file in request"}).end()
39
+ return
40
+ }
41
+
42
+ let options: ColmapOptions = req.body
43
+ let dataFile: fileUpload.UploadedFile = req.files.data
44
+
45
+ let projectTempDir = path.join(os.tmpdir(), Math.random().toString().slice(2))
46
+ let outputTempDir = path.join(os.tmpdir(), Math.random().toString().slice(2))
47
+
48
+ try {
49
+ fs.mkdirSync(projectTempDir)
50
+ fs.mkdirSync(outputTempDir)
51
+
52
+ await dataFile.mv(path.join(projectTempDir, dataFile.name))
53
+
54
+ let imageFolder = path.join(projectTempDir, 'images');
55
+ fs.mkdirSync(imageFolder)
56
+
57
+ await new Promise((resolve, reject) => {
58
+ ffmpeg(path.join(projectTempDir, dataFile.name))
59
+ .outputOptions('-vf', 'fps=1') // Change this value depending on the number of frames you want from video.
60
+ .output(path.join(imageFolder, 'image-%03d.png'))
61
+ .on('end', resolve)
62
+ .on('error', reject)
63
+ .run()
64
+ })
65
+
66
+ options.projectPath = projectTempDir
67
+ options.workspacePath = projectTempDir
68
+ options.imagePath = imageFolder
69
+
70
+ const result = await runColmap(options)
71
+
72
+ let outputFilePath = path.join(outputTempDir, 'output.zip')
73
+ let output = fs.createWriteStream(outputFilePath)
74
+ let archive = archiver('zip')
75
+
76
+ archive.directory(outputTempDir, false)
77
+ archive.pipe(output)
78
+ await archive.finalize()
79
+
80
+ res.status(200)
81
+ res.download(outputFilePath, 'output.zip', (error) => {
82
+ if (!error) fs.rmSync(projectTempDir, {recursive: true, force: true})
83
+ fs.rmSync(outputTempDir, {recursive: true, force: true})
84
+ })
85
+ } catch (error) {
86
+ res.status(500).json({
87
+ error: "Couldn't generate pose data",
88
+ message: error
89
+ }).end()
90
+ } finally {
91
+ activeRequests--
92
+ }
93
+ });
94
+
95
+ app.get("/", async (req, res) => {
96
+ res.status(200)
97
+ res.write(`<html><head></head><body>
98
+ Campose API is a micro-service used to generate came pose data from a set of images.
99
+ </body></html>`)
100
+ res.end()
101
+ })
102
+
103
+ app.listen(port, () => { console.log(`Open http://localhost:${port}`) })
src/initFolders.mts ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {
2
+ inputsDirFilePath,
3
+ outputsDirFilePath,
4
+ } from "./config.mts"
5
+ import { createDirIfNeeded } from "./utils/createDirIfNeeded.mts"
6
+
7
+ export const initFolders = () => {
8
+ console.log(`initializing folders..`)
9
+ createDirIfNeeded(inputsDirFilePath)
10
+ createDirIfNeeded(outputsDirFilePath)
11
+ }
src/types.mts ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ export type PostVisibility =
3
+ | "featured" // featured by admins
4
+ | "trending" // top trending / received more than 10 upvotes
5
+ | "normal" // default visibility
6
+
7
+ export type Post = {
8
+ postId: string
9
+ appId: string
10
+ prompt: string
11
+ previewUrl: string
12
+ assetUrl: string
13
+ createdAt: string
14
+ visibility: PostVisibility
15
+ upvotes: number
16
+ downvotes: number
17
+ }
18
+
19
+ export type CreatePostResponse = {
20
+ success?: boolean
21
+ error?: string
22
+ post: Post
23
+ }
24
+
25
+ export type GetAppPostsResponse = {
26
+ success?: boolean
27
+ error?: string
28
+ posts: Post[]
29
+ }
30
+
31
+ export type GetAppPostResponse = {
32
+ success?: boolean
33
+ error?: string
34
+ post: Post
35
+ }
src/utils/createDirIfNeeded.mts ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ import { existsSync, mkdirSync } from "node:fs"
2
+
3
+ export const createDirIfNeeded = (dirPath: string) => {
4
+ if (!existsSync(dirPath)) {
5
+ mkdirSync(dirPath, { recursive: true })
6
+ }
7
+ }
src/utils/debouncePromise.mts ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+
3
+ Here's how you can use the `debouncePromise` function:
4
+
5
+ ```typescript
6
+ async function fetchData(query: string): Promise<string> {
7
+ // Simulating an API call
8
+ return new Promise((resolve) => {
9
+ setTimeout(() => {
10
+ resolve(`Results for ${query}`);
11
+ }, 500);
12
+ });
13
+ }
14
+
15
+ const debouncedFetchData = debouncePromise(fetchData, 300);
16
+
17
+ (async () => {
18
+ try {
19
+ console.log(await debouncedFetchData("query 1")); // This will be ignored
20
+ console.log(await debouncedFetchData("query 2")); // This will be ignored
21
+ console.log(await debouncedFetchData("query 3")); // This will return "Results for query 3"
22
+ } catch (error) {
23
+ console.error(error);
24
+ }
25
+ })();
26
+ ```
27
+
28
+ The `debouncePromise` function takes a Promise-based function `func` and a `wait` time as its arguments.
29
+ It returns a debounced version of the given function that, when called multiple times within the specified wait time, will only execute the last call.
30
+ */
31
+
32
+ type DebouncedFunction<T extends any[], R> = ((...args: T) => R) & {
33
+ clear: () => void
34
+ }
35
+
36
+ export function debouncePromise<T extends any[], R>(
37
+ func: (...args: T) => Promise<R>,
38
+ wait: number
39
+ ): DebouncedFunction<T, Promise<R | undefined>> {
40
+ let timeout: NodeJS.Timeout | undefined
41
+
42
+ const debounced = (...args: T) => {
43
+ return new Promise<R | undefined>((resolve, reject) => {
44
+ if (timeout) {
45
+ clearTimeout(timeout)
46
+ }
47
+
48
+ timeout = setTimeout(async () => {
49
+ try {
50
+ const result = await func(...args)
51
+ resolve(result)
52
+ } catch (error) {
53
+ reject(error)
54
+ }
55
+ }, wait)
56
+ })
57
+ }
58
+
59
+ debounced.clear = () => {
60
+ if (timeout) {
61
+ clearTimeout(timeout)
62
+ }
63
+ }
64
+
65
+ return debounced
66
+ }
src/utils/debounceSync.mts ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ type DebouncedFunctionSync<T extends any[], R> = ((...args: T) => R) & {
2
+ clear: () => void
3
+ }
4
+
5
+ /**
6
+ * Example usage:
7
+ * ```typescript
8
+ * function fetchDataSync(query: string): string {
9
+ * return `Results for ${query}`;
10
+ * }
11
+ *
12
+ * const debouncedFetchDataSync = debounceSync(fetchDataSync, 300);
13
+ *
14
+ * try {
15
+ * console.log(debouncedFetchDataSync("query 1")); // This will be ignored
16
+ * console.log(debouncedFetchDataSync("query 2")); // This will be ignored
17
+ * console.log(debouncedFetchDataSync("query 3")); // This will return "Results for query 3"
18
+ * } catch (error) {
19
+ * console.error(error);
20
+ * }
21
+ * ```
22
+ *
23
+ * Note that the synchronous version of the debounce function will return
24
+ * the result of the last function call or `undefined` if the function was
25
+ * not called within the specified wait time. You should also be aware that
26
+ * this synchronous version may cause blocking if the debounced function
27
+ * takes a long time to execute.
28
+ *
29
+ * @param func
30
+ * @param wait
31
+ * @returns
32
+ */
33
+ export function debounceSync<T extends any[], R>(
34
+ func: (...args: T) => R,
35
+ wait: number
36
+ ): DebouncedFunctionSync<T, R | undefined> {
37
+ let timeout: NodeJS.Timeout | undefined
38
+
39
+ const debounced = (...args: T): R | undefined => {
40
+ if (timeout) {
41
+ clearTimeout(timeout)
42
+ }
43
+
44
+ let result: R | undefined
45
+ timeout = setTimeout(() => {
46
+ result = func(...args)
47
+ }, wait)
48
+
49
+ return result
50
+ }
51
+
52
+ debounced.clear = () => {
53
+ if (timeout) {
54
+ clearTimeout(timeout)
55
+ }
56
+ }
57
+
58
+ return debounced
59
+ }
src/utils/deleteAllFilesWith.mts ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { promises as fs } from "node:fs"
2
+ import path from "node:path"
3
+
4
+ export const deleteFilesWithName = async (dir: string, name: string) => {
5
+ for (const file of await fs.readdir(dir)) {
6
+ if (file.includes(name)) {
7
+ const filePath = path.join(dir, file)
8
+ try {
9
+ await fs.unlink(filePath)
10
+ } catch (err) {
11
+ console.error(`failed to unlink file in ${filePath}: ${err}`)
12
+ }
13
+ }
14
+ }
15
+ }
src/utils/deleteFileIfExists.mts ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { existsSync, promises as fs } from "node:fs"
2
+
3
+ export const deleteFileIfExists = async (filePath: string) => {
4
+ // this function scares me a bit,
5
+ if (filePath === "/" || filePath === "~" || filePath === ".") {
6
+ throw new Error(`lol, no.`)
7
+ }
8
+
9
+ if (existsSync(filePath)) {
10
+ try {
11
+ await fs.unlink(filePath)
12
+ return true
13
+ } catch (err) {
14
+ console.log(`failed to delete file ${filePath}`)
15
+ }
16
+ }
17
+ return false
18
+ }
src/utils/downloadFileAsBase64.mts ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export const downloadImageAsBase64 = async (remoteUrl: string): Promise<string> => {
2
+ const controller = new AbortController()
3
+
4
+ // download the image
5
+ const response = await fetch(remoteUrl, {
6
+ signal: controller.signal
7
+ })
8
+
9
+ // get as Buffer
10
+ const arrayBuffer = await response.arrayBuffer()
11
+ const buffer = Buffer.from(arrayBuffer)
12
+
13
+ // convert it to base64
14
+ const base64 = buffer.toString('base64')
15
+
16
+ return base64
17
+ };
src/utils/downloadFileToTmp.mts ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import path from "node:path"
2
+ import fs from "node:fs"
3
+
4
+ import tmpDir from "temp-dir"
5
+
6
+ export const downloadFileToTmp = async (remoteUrl: string, fileName: string) => {
7
+
8
+ const filePath = path.resolve(tmpDir, fileName)
9
+
10
+ const controller = new AbortController()
11
+ const timeoutId = setTimeout(() => controller.abort(), 15 * 60 * 60 * 1000) // 15 minutes
12
+
13
+ // TODO finish the timeout?
14
+
15
+ // download the file
16
+ const response = await fetch(remoteUrl, {
17
+ signal: controller.signal
18
+ })
19
+
20
+ // write it to the disk
21
+ const arrayBuffer = await response.arrayBuffer()
22
+
23
+ await fs.promises.writeFile(
24
+ filePath,
25
+ Buffer.from(arrayBuffer)
26
+ )
27
+
28
+ return filePath
29
+ }
src/utils/getValidBoolean.mts ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ export const getValidBoolean = (something: any, defaultValue: boolean) => {
2
+ if (typeof something === "boolean") {
3
+ return something
4
+ }
5
+
6
+ const strValue = `${something || defaultValue}`.toLowerCase()
7
+
8
+ return strValue === "true" || strValue === "1" || strValue === "on"
9
+ }
src/utils/getValidNumber.mts ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ export const getValidNumber = (something: any, minValue: number, maxValue: number, defaultValue: number) => {
2
+ const strValue = `${something || defaultValue}`
3
+ const numValue = Number(strValue)
4
+ const isValid = !isNaN(numValue) && isFinite(numValue)
5
+ if (!isValid) {
6
+ return defaultValue
7
+ }
8
+ return Math.max(minValue, Math.min(maxValue, numValue))
9
+
10
+ }
src/utils/getValidResolution.mts ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { getValidNumber } from "./getValidNumber.mts"
2
+
3
+ export const getValidResolution = (something: any) => {
4
+ const strValue = `${something || ''}`
5
+ const chunks = strValue.split('x')
6
+
7
+ if (chunks.length !== 2) {
8
+ return `1280x720`
9
+ }
10
+
11
+ const [widthStr, heightStr] = chunks
12
+ const width = getValidNumber(widthStr, 256, 1280, 1280)
13
+ const height = getValidNumber(widthStr, 256, 720, 720)
14
+
15
+ return `${width}x${height}`
16
+ }
src/utils/hasValidAuthorization.mts ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import { IncomingHttpHeaders } from "node:http"
2
+
3
+ export const hasValidAuthorization = (headers: IncomingHttpHeaders) => {
4
+ const [_, token] = `${headers.authorization || ""}`.split(" ")
5
+ if (typeof token === "string" && token.trim() === process.env.SECRET_ACCESS_TOKEN.trim()) {
6
+ return true
7
+ }
8
+
9
+ return false
10
+ }
src/utils/hashRequest.mts ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { RenderRequest } from "../types.mts"
2
+ import { computeSha256 } from "./computeSha256.mts"
3
+
4
+ export function hashRequest(request: RenderRequest) {
5
+
6
+ // we ignore the commands associated to cache and stuff
7
+ const hashable = {
8
+ version: 1,
9
+ prompt: request.prompt,
10
+ segmentation: request.segmentation,
11
+ actionnables: request.actionnables,
12
+ nbFrames: request.nbFrames,
13
+ nbSteps: request.nbSteps,
14
+ // seed: request.seed,
15
+ width: request.width,
16
+ height: request.height,
17
+ projection: request.projection,
18
+ }
19
+
20
+ const requestJson = JSON.stringify(hashable)
21
+ const hash = computeSha256(requestJson)
22
+
23
+ return hash
24
+ }
src/utils/moveFile.mts ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { promises as fs } from "node:fs"
2
+
3
+ // a function to move a file
4
+ // this implementation is safe to use on a Hugging Face Space
5
+ // for instance when copying from one disk to another
6
+ // (we cannot use fs.rename in that case)
7
+ export const moveFile = async (sourceFilePath: string, targetFilePath: string) => {
8
+ await fs.copyFile(sourceFilePath, targetFilePath)
9
+ console.log(`moved file from ${sourceFilePath} to ${targetFilePath}`)
10
+ try {
11
+ await fs.unlink(sourceFilePath)
12
+ } catch (err) {
13
+ console.log("moveFile: failed to cleanup (no big deal..)")
14
+ }
15
+ }
src/utils/randomShuffle.mts ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ export function randomShuffle<T>(array: T[]): T[] {
2
+ for (let i = array.length - 1; i > 0; i--) {
3
+ const j = Math.floor(Math.random() * (i + 1));
4
+ [array[i], array[j]] = [array[j], array[i]];
5
+ }
6
+
7
+ return array
8
+ };
src/utils/sleep.mts ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ export const sleep = async (durationInMs: number) =>
2
+ new Promise((resolve) => {
3
+ setTimeout(() => {
4
+ resolve(true)
5
+ }, durationInMs)
6
+ })
tsconfig.json ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "allowJs": true,
4
+ "esModuleInterop": true,
5
+ "allowSyntheticDefaultImports": true,
6
+ "module": "nodenext",
7
+ "noEmit": true,
8
+ "allowImportingTsExtensions": true,
9
+ "target": "es2022"
10
+ },
11
+ "include": ["**/*.ts", "**/*.mts"],
12
+ }