├── .gitignore
├── README.md
├── newsfetch
├── .eslintrc.cjs
├── .firebase
│ ├── hosting.ZGlzdA.cache
│ └── hosting.cHVibGlj.cache
├── .firebaserc
├── .gitignore
├── README.md
├── bun.lockb
├── firebase.json
├── index.html
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
│ ├── logo.svg
│ └── vite.svg
├── src
│ ├── .env.sample
│ ├── Animations
│ │ └── index.js
│ ├── App.css
│ ├── App.jsx
│ ├── Layout.jsx
│ ├── assets
│ │ ├── image.png
│ │ └── react.svg
│ ├── components
│ │ ├── About
│ │ │ └── About.jsx
│ │ ├── Blog
│ │ │ └── Blog.jsx
│ │ ├── Contact
│ │ │ └── Contact.jsx
│ │ ├── Context
│ │ │ └── Theme.js
│ │ ├── Footer
│ │ │ └── Footer.jsx
│ │ ├── Header
│ │ │ ├── FireBaseConfig.js
│ │ │ ├── Header.jsx
│ │ │ └── ThemeButton.jsx
│ │ ├── NewsDetail
│ │ │ └── NewsDetail.jsx
│ │ ├── Preloader
│ │ │ ├── Preloader.css
│ │ │ └── Preloader.jsx
│ │ ├── Slider
│ │ │ └── Carousel.jsx
│ │ └── TrendingNews
│ │ │ └── TrendingNews.jsx
│ ├── index.css
│ └── main.jsx
├── style.css
├── tailwind.config.js
└── vite.config.js
└── server
├── .env.sample
├── .firebase
└── hosting.cHVibGlj.cache
├── .firebaserc
├── .github
└── workflows
│ ├── firebase-hosting-merge.yml
│ └── firebase-hosting-pull-request.yml
├── .gitignore
├── bun.lockb
├── dist
├── assets
│ ├── image-Cs6Ew6q3.png
│ ├── index-BQinPF2a.js
│ └── index-CxmS_tQk.css
├── index.html
└── vite.svg
├── firebase.json
├── package-lock.json
├── package.json
├── server.js
└── vercel.json
/.gitignore:
--------------------------------------------------------------------------------
1 | newsfetch/src/.env
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # NewsMania
2 |
3 | Welcome to **NewsMania**, a web application designed to keep you updated with the top business news headlines fetched from sources like Times of India and others using the https://newsapi.org. This project utilizes a combination of backend middleware and direct API calls. The middleware, built with Express.js, handles some API requests, while others are fetched directly from the frontend via the github API to fetch the admin information directly from Github account. The application also integrates Google authentication for seamless login and logout, and leverages Web3 forms to trigger emails to the admin.
4 |
5 | ## Features
6 |
7 | - **Business News Headlines**: Fetches top business Headlines from sources like Times of India and others via NEWSAPI.
8 | - **Google Authentication**: Integrates Google login/logout for user authentication.
9 | - **Github API**: Fetches user data from Github.
10 | - **Web Forms Integration**: Sends emails to the admin using Web forms.
11 |
12 | ## Middleware Explanation
13 |
14 | NEWSAPI allows fetching data from their API on localhost only. However, CORS (Cross-Origin Resource Sharing) are blocked for any other production deployment. To bypass these CORS restrictions, a middleware is created using Express.js. This middleware resolves the CORS issues by fetching the data at the backend and displaying it on the frontend.
15 |
16 | ## Live Demo
17 |
18 | You can see the live demo of the project [here](https://hunar-taupe.vercel.app).
19 |
20 | ## Technologies Used
21 |
22 | - **Frontend**:
23 | - React + Vite
24 | - Tailwind CSS
25 | - React Router DOM
26 | - GSAP(GreenSock Animation Platform)
27 |
28 | - **Backend**:
29 | - Express.js (as middleware/proxy server)
30 | - Firebase (for authentication)
31 | - Railway.app (for hosting backend)
32 |
33 | - **APIs**:
34 | - NEWSAPI (for fetching news)
35 | - Github API (for fetching user data)
36 | - Google Authentication (for user login/logout)
37 | - Web3Forms (for handling web forms and email triggers)
38 |
39 | - **Deployment**:
40 | - Vercel (for deploying frontend)
41 | - Railway.app (for deploying backend)
42 |
43 | ## Getting Started
44 |
45 | To get a local copy up and running, follow these simple steps.
46 |
47 | ### Prerequisites
48 |
49 | - Node.js installed on your machine
50 | - A NEWSAPI key
51 | - A Github API key
52 | - TailwindCSS & React + Vite Builder Pack Installed
53 | - Firebase project set up for Google authentication
54 | - Web3Forms account for handling form submissions
55 |
56 | ### Installation
57 |
58 | 1. **Clone the repository**:
59 |
60 | ```sh
61 | git clone https://github.com/happyrao78/Hunar.git
62 | ```
63 |
64 | 2. **Navigate to the project directory**:
65 |
66 | ```sh
67 | cd newsfetch
68 | ```
69 |
70 | 3. **Install dependencies for the frontend and backend**:
71 |
72 | ```sh
73 | cd newsfetch (Frontend)
74 | npm install
75 | cd server (Backend)
76 | npm install
77 | ```
78 |
79 | 4. **Set up environment variables**:
80 |
81 | Create a `.env` file in the server directory and add your NEWSAPI key, and PORT for local host.
82 |
83 | ```env
84 | NEWS_API_KEY=your_newsapi_key
85 | PORT=your desired PORT
86 | ```
87 |
88 | 5. **Set up Firebase**:
89 |
90 | - Create a Firebase project in the [Firebase Console](https://console.firebase.google.com/).
91 | - Enable Google authentication in the Firebase Authentication section.
92 | - Obtain the Firebase configuration settings (API key, Auth domain, Project ID, etc.) and add them to /newsfetch/src/components/Header/FireBaseConfig.js file.
93 |
94 | 6. **Run the backend server**:
95 |
96 | ```sh
97 | cd server
98 | node server.js
99 | ```
100 |
101 | 7. **Run the frontend server**:
102 |
103 | Open a new terminal window and run:
104 |
105 | ```sh
106 | cd newsfetch
107 | npm run dev
108 | ```
109 |
110 | ### Deployment
111 |
112 | 1. **Set up Railway.app**:
113 |
114 | - Create a project in [Railway.app](https://railway.app/).
115 | - Add your environment variables in the Railway platform. Railway.app uses dynamic allocation for environment variables, so the `.env` file is essential. Ensure all variables from the `.env` file are added to the Railway environment configuration.
116 |
117 | 2. **Deploy Backend**:
118 |
119 | - Deploy the backend server on Railway.app by following their documentation and connecting your repository.
120 |
121 | 3. **Deploy Frontend**:
122 |
123 | - Deploy the frontend on Vercel by connecting your repository and following their deployment steps.
124 |
125 | ## Usage
126 |
127 | 1. Open the application in your browser at `http://localhost:3000`.
128 | 2. Log in using your Google account.
129 | 3. Browse through the top business news headlines.
130 | 4. Fetch your Github user data.
131 | 5. Use the contact form to send an email to the admin.
132 |
133 | ## Contributing
134 |
135 | Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.
136 |
137 | 1. Fork the project.
138 | 2. Create your feature branch (`git checkout -b feature/AmazingFeature`).
139 | 3. Commit your changes (`git commit -m 'Add some AmazingFeature'`).
140 | 4. Push to the branch (`git push origin feature/AmazingFeature`).
141 | 5. Open a Pull Request.
142 |
143 | ## MIT License
144 |
145 | Distributed under the MIT License.
146 |
147 |
148 | Copyright (c) [2024] [NewsMania]
149 |
150 | Permission is hereby granted, free of charge, to any person obtaining a copy
151 | of this project and associated documentation files, to deal
152 | in the project without restriction, including without limitation the rights
153 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
154 | copies of the project, and to permit persons to whom the project is
155 | furnished to do so, subject to the following conditions:
156 |
157 | The above copyright notice and this permission notice shall be included in all
158 | copies or substantial portions of the project.
159 |
160 | THE PROJECT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
161 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
162 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
163 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
164 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
165 | OUT OF OR IN CONNECTION WITH THE PROJECT OR THE USE OR OTHER DEALINGS IN THE
166 | PROJECT.
167 |
168 |
169 | ## Contact
170 |
171 | Your Name - [happyrao7091@gmail.com](mailto:happyrao7091@gmail.com)
172 |
173 | Owner's Website: [https://www.happyrao.tech](https://www.happyrao.tech)
174 |
175 | Project Link: [https://github.com/happyrao78/Hunar](https://github.com/happyrao78/Hunar)
176 |
177 | ---
178 |
179 | Thank you for checking out NewsMania! Enjoy staying updated with the latest business news.
--------------------------------------------------------------------------------
/newsfetch/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: { browser: true, es2020: true },
4 | extends: [
5 | 'eslint:recommended',
6 | 'plugin:react/recommended',
7 | 'plugin:react/jsx-runtime',
8 | 'plugin:react-hooks/recommended',
9 | ],
10 | ignorePatterns: ['dist', '.eslintrc.cjs'],
11 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
12 | settings: { react: { version: '18.2' } },
13 | plugins: ['react-refresh'],
14 | rules: {
15 | 'react/jsx-no-target-blank': 'off',
16 | 'react-refresh/only-export-components': [
17 | 'warn',
18 | { allowConstantExport: true },
19 | ],
20 | },
21 | }
22 |
--------------------------------------------------------------------------------
/newsfetch/.firebase/hosting.ZGlzdA.cache:
--------------------------------------------------------------------------------
1 | vite.svg,1719070733215,699a02e0e68a579f687d364bbbe7633161244f35af068220aee37b1b33dfb3c7
2 | index.html,1719670418759,6efac3621d61854fc5d023e4de016e4296861c5b94d0a7f2b816a494d742a175
3 | assets/index-CxmS_tQk.css,1719670418759,ff7499b4d322d923c51e8a6ebb8fff7408c4523bf5037951d3d73dad1e649ab7
4 | assets/index-BQinPF2a.js,1719670418762,84259530a8cd31d6e348d4acf4547191d1876fc61ed160e88bcc7b5451f95d14
5 | assets/image-Cs6Ew6q3.png,1719670418759,117faebf7f84edbb05c36a48cb9264f41d2035234b30aeace9a8d9ec49b5d005
6 |
--------------------------------------------------------------------------------
/newsfetch/.firebase/hosting.cHVibGlj.cache:
--------------------------------------------------------------------------------
1 | vite.svg,1719070733215,699a02e0e68a579f687d364bbbe7633161244f35af068220aee37b1b33dfb3c7
2 |
--------------------------------------------------------------------------------
/newsfetch/.firebaserc:
--------------------------------------------------------------------------------
1 | {
2 | "projects": {
3 | "default": "hunar-8f29c"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/newsfetch/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/newsfetch/README.md:
--------------------------------------------------------------------------------
1 | # React + Vite
2 |
3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4 |
5 | Currently, two official plugins are available:
6 |
7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9 |
--------------------------------------------------------------------------------
/newsfetch/bun.lockb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/happyrao78/Hunar/d59138026a511f0f7bf399ea5d14623b8ed00272/newsfetch/bun.lockb
--------------------------------------------------------------------------------
/newsfetch/firebase.json:
--------------------------------------------------------------------------------
1 | {
2 | "hosting": {
3 | "public": "dist",
4 | "ignore": [
5 | "firebase.json",
6 | "**/.*",
7 | "**/node_modules/**"
8 | ],
9 | "rewrites": [
10 | {
11 | "source": "**",
12 | "destination": "/index.html"
13 | }
14 | ]
15 | },
16 | "emulators": {
17 | "auth": {
18 | "port": 2024
19 | },
20 | "hosting": {
21 | "port": 5000
22 | },
23 | "ui": {
24 | "enabled": false
25 | },
26 | "singleProjectMode": true
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/newsfetch/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | NewsMania
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/newsfetch/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "newsfetch",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
10 | "preview": "vite preview"
11 | },
12 | "dependencies": {
13 | "axios": "^1.7.2",
14 | "cheerio": "^1.0.0-rc.12",
15 | "cors": "^2.8.5",
16 | "express": "^4.19.2",
17 | "firebase": "^10.12.2",
18 | "gsap": "^3.12.5",
19 | "lucide-react": "^0.441.0",
20 | "newsfetch": "file:",
21 | "puppeteer": "^22.12.1",
22 | "react": "^18.3.1",
23 | "react-animated-cursor": "^2.11.2",
24 | "react-dom": "^18.3.1",
25 | "react-icons": "^5.2.1",
26 | "react-marquee-slider": "^1.1.5",
27 | "react-router": "^6.24.0",
28 | "react-router-dom": "^6.24.0",
29 | "react-slick": "^0.30.2",
30 | "react-spinners": "^0.14.1",
31 | "react-tilty": "^3.0.0",
32 | "react-tsparticles": "^2.12.2",
33 | "slick-carousel": "^1.8.1",
34 | "uuid": "^10.0.0"
35 | },
36 | "devDependencies": {
37 | "@types/react": "^18.3.3",
38 | "@types/react-dom": "^18.3.0",
39 | "@vitejs/plugin-react": "^4.3.1",
40 | "autoprefixer": "^10.4.19",
41 | "eslint": "^8.57.0",
42 | "eslint-plugin-react": "^7.34.2",
43 | "eslint-plugin-react-hooks": "^4.6.2",
44 | "eslint-plugin-react-refresh": "^0.4.7",
45 | "postcss": "^8.4.38",
46 | "tailwindcss": "^3.4.4",
47 | "vite": "^5.3.1"
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/newsfetch/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/newsfetch/public/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/newsfetch/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/newsfetch/src/.env.sample:
--------------------------------------------------------------------------------
1 | GITHUB_ACCESS_TOKEN=your_github_access_token
--------------------------------------------------------------------------------
/newsfetch/src/Animations/index.js:
--------------------------------------------------------------------------------
1 | import gsap from "gsap";
2 |
3 | // Declare a general timeline to use in all the animation functions.
4 |
5 | const tl = gsap.timeline();
6 |
7 | // Preloader Animation
8 | export const preLoaderAnim = () => {
9 | tl.to("body", {
10 | duration: 0.1,
11 | css: { overflowY: "hidden" },
12 | ease: "power3.inOut",
13 | })
14 | .to(".landing", {
15 | duration: 0.05,
16 | css: { overflowY: "hidden", height: "90vh" },
17 | })
18 | .to(".texts-container", {
19 | duration: 0,
20 | opacity: 1,
21 | ease: "Power3.easeOut",
22 | })
23 | .from(".texts-container span", {
24 | duration: 1.5,
25 | delay: 1,
26 | y: 70,
27 | skewY: 10,
28 | stagger: 0.4,
29 | ease: "Power3.easeOut",
30 | })
31 | .to(".texts-container span", {
32 | duration: 1,
33 | y: 70,
34 | skewY: -20,
35 | stagger: 0.2,
36 | ease: "Power3.easeOut",
37 | })
38 |
39 | .to(".landing", {
40 | duration: 0.05,
41 | css: { overflowY: "hidden", height: "unset" },
42 | })
43 | .to("body", {
44 | duration: 0.1,
45 | css: { overflowY: "scroll" },
46 | ease: "power3.inOut",
47 | })
48 | .from(".landing__top .sub", {
49 | duration: 1,
50 | opacity: 0,
51 | y: 80,
52 | ease: "expo.easeOut",
53 | })
54 | .to(
55 | ".preloader",
56 | {
57 | duration: 1.5,
58 | height: "0vh",
59 | ease: "Power3.easeOut",
60 | onComplete: mobileLanding(),
61 | },
62 | "-=2"
63 | )
64 | .from(".landing__main .text", {
65 | duration: 2,
66 | // scale: 0,
67 | y: 10,
68 | opacity: 0,
69 | stagger: {
70 | amount: 2,
71 | },
72 | ease: "power3.easeInOut",
73 | })
74 | .from(".links .item", {
75 | duration: 0.5,
76 | opacity: 0,
77 | delay: window.innerWidth < 763 ? -3 : -0.6,
78 | // y: 80,
79 | stagger: {
80 | amount: 0.5,
81 | },
82 | ease: "expo.easeOut",
83 | onComplete: animateMainShape(),
84 | })
85 | .from(".main-circle", {
86 | duration: 1,
87 | opacity: 0,
88 | ease: "power3.easeInOut",
89 | onComplete: animateShapes(),
90 | })
91 | .from(".shapes .shape", {
92 | duration: 1,
93 | opacity: 0,
94 | delay: -1,
95 | ease: "power3.easeInOut",
96 | stagger: 1,
97 | })
98 | .to(".preloader", {
99 | duration: 0,
100 | css: { display: "none" },
101 | });
102 | };
103 |
104 | export const openMenu = () => {
105 | const tl = gsap.timeline();
106 | tl.to("body", {
107 | duration: 0.1,
108 | css: { overflowY: "hidden" },
109 | ease: "power3.out",
110 | })
111 | .to(".hamburger-menu", {
112 | duration: 0.1,
113 | css: { display: "block" },
114 | })
115 | .to(".header-item", {
116 | duration: 0.1,
117 | css: { background: "none" },
118 | })
119 | .to(".cls-1", {
120 | duration: 0.1,
121 | delay: 0.3,
122 | css: { fill: "#ffffff" },
123 | })
124 | .to(
125 | [".nav-secondary", ".nav-primary"],
126 | {
127 | duration: 0.8,
128 | height: "100%",
129 | transformOrigin: "right top",
130 | stagger: {
131 | amount: 0.1,
132 | },
133 | ease: "power3.inOut",
134 | },
135 | "-=.5"
136 | )
137 | .from(
138 | ".nav-link",
139 | {
140 | duration: 0.5,
141 | x: -80,
142 | opacity: 0,
143 | stagger: {
144 | amount: 0.5,
145 | },
146 | ease: "Power3.in",
147 | },
148 | "-=.3"
149 | );
150 |
151 | // change cursor color when nav is open
152 | // tl.to(".cursor", {
153 | // delay: -1,
154 | // css: { className: "+=cursor-active" },
155 | // }).to(".cursor2", { delay: -1, css: { className: "+=cursor2-active" } });
156 | };
157 |
158 | export const closeMenu = () => {
159 | const tl = gsap.timeline();
160 | tl.to("body", {
161 | duration: 0.05,
162 | css: { overflowY: "scroll" },
163 | ease: "power3.inOut",
164 | })
165 | .to([".nav-primary", ".nav-secondary"], {
166 | duration: 0.8,
167 | height: "0",
168 | transformOrigin: "right top",
169 | stagger: {
170 | amount: 0.1,
171 | },
172 | ease: "power3.inOut",
173 | })
174 | .to(".cls-1", {
175 | duration: 0.1,
176 | delay: -0.3,
177 | css: { fill: "#08e7f3" },
178 | })
179 | .to(".header-item", {
180 | duration: 0.5,
181 | css: { background: "rgba(11,11,15,.8)" },
182 | })
183 | .to(".hamburger-menu", {
184 | duration: 0.05,
185 | css: { display: "none" },
186 | });
187 |
188 | // tl.to(".cursor-active", {
189 | // css: { className: "+=cursor" },
190 | // }).to(".cursor2-active", { css: { className: "+=cursor2" } });
191 | };
192 |
193 | // recurrent animations
194 | export const fadeUp = (el, delay = 0) => {
195 | tl.from(el, {
196 | y: 150,
197 | duration: 1,
198 | delay,
199 | opacity: 0,
200 | ease: "power3.Out",
201 | });
202 | };
203 |
204 | export const mobileLanding = () => {
205 | window.innerWidth < 763 &&
206 | tl.from(".landing__main2", {
207 | duration: 1,
208 | delay: 0,
209 | opacity: 0,
210 | y: 80,
211 | ease: "expo.easeOut",
212 | });
213 | };
214 |
215 | const animateShapes = () => {
216 | const infiniteTl = gsap.timeline({
217 | repeat: -1,
218 | });
219 | infiniteTl
220 | .to(".shapes .shape", {
221 | duration: 4,
222 | rotate: 360,
223 | delay: -1,
224 | ease: "power3.easeInOut",
225 | stagger: 2,
226 | })
227 | .to(".shapes .shape-3", {
228 | duration: 1,
229 | rotate: 360,
230 | delay: -2,
231 | ease: "power3.easeInOut",
232 | })
233 | .to(".shapes .shape", {
234 | duration: 3,
235 | rotate: 0,
236 | ease: "power3.easeInOut",
237 | stagger: 1,
238 | })
239 | .to(".shapes .shape", {
240 | duration: 1,
241 | opacity: 0,
242 | delay: -1,
243 | ease: "power3.easeInOut",
244 | stagger: 1,
245 | })
246 | .to(".shapes .shape", {
247 | duration: 1.5,
248 | opacity: 1,
249 | ease: "power3.easeInOut",
250 | stagger: 1,
251 | });
252 | };
253 |
254 | const animateMainShape = () => {
255 | const infiniteTl = gsap.timeline({
256 | repeat: -1,
257 | });
258 | infiniteTl
259 | .to(".shapes .main-circle", {
260 | duration: 6,
261 | x: -30,
262 | y: -50,
263 | ease: "expo.easeOut",
264 | })
265 | .to(".shapes .main-circle", {
266 | duration: 6,
267 | x: -30,
268 | y: 50,
269 | ease: "expo.easeOut",
270 | })
271 | .to(".shapes .main-circle", {
272 | duration: 4,
273 | x: 0,
274 | y: 0,
275 | ease: "expo.easeOut",
276 | });
277 | };
278 |
279 | export const boxHover = (e) => {
280 | const tl = gsap.timeline();
281 | window.innerWidth >= 986 &&
282 | tl
283 | .to(e.target.querySelector(".link"), {
284 | duration: 0,
285 | opacity: 1,
286 | })
287 | .from(e.target.querySelectorAll(".box-anim"), {
288 | duration: 0.3,
289 | opacity: 0,
290 | y: 30,
291 | stagger: 0.1,
292 | ease: "Power3.easeOut",
293 | });
294 | };
295 |
296 | export const boxExit = (e) => {
297 | window.innerWidth >= 986 &&
298 | gsap.to(e.target.querySelector(".link"), {
299 | duration: 0,
300 | opacity: 0,
301 | });
302 | };
303 |
304 | export const fadeIn = (el) => {
305 | gsap.to(el, {
306 | duration: 2,
307 | opacity: 1,
308 | y: -60,
309 | ease: "power4.out",
310 | });
311 | };
312 |
313 | export const fadeOut = (el) => {
314 | gsap.to(el, {
315 | duration: 1,
316 | opacity: 0,
317 | y: -20,
318 | ease: "power4.out",
319 | });
320 | };
--------------------------------------------------------------------------------
/newsfetch/src/App.css:
--------------------------------------------------------------------------------
1 | #root {
2 | max-width: 1280px;
3 | margin: 0 auto;
4 | padding: 2rem;
5 | text-align: center;
6 | }
7 |
8 | .logo {
9 | height: 6em;
10 | padding: 1.5em;
11 | will-change: filter;
12 | transition: filter 300ms;
13 | }
14 | .logo:hover {
15 | filter: drop-shadow(0 0 2em #646cffaa);
16 | }
17 | .logo.react:hover {
18 | filter: drop-shadow(0 0 2em #61dafbaa);
19 | }
20 |
21 | @keyframes logo-spin {
22 | from {
23 | transform: rotate(0deg);
24 | }
25 | to {
26 | transform: rotate(360deg);
27 | }
28 | }
29 |
30 | @media (prefers-reduced-motion: no-preference) {
31 | a:nth-of-type(2) .logo {
32 | animation: logo-spin infinite 20s linear;
33 | }
34 | }
35 |
36 | .card {
37 | padding: 2em;
38 | }
39 |
40 | .read-the-docs {
41 | color: #888;
42 | }
43 | /* @keyframes pulse {
44 | 0%, 100% {
45 | opacity: 1;
46 | }
47 | 50% {
48 | opacity: 0.5;
49 | }
50 | } */
51 |
--------------------------------------------------------------------------------
/newsfetch/src/App.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from 'react'
2 |
3 | import './App.css'
4 |
5 | function App() {
6 |
7 | return (
8 | <>
9 |
10 | >
11 | )
12 | }
13 |
14 | export default App
15 |
--------------------------------------------------------------------------------
/newsfetch/src/Layout.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from 'react'
2 | import Header from './components/Header/Header'
3 | import Footer from './components/Footer/Footer'
4 | import {Outlet} from 'react-router-dom'
5 | import AnimatedCursor from "react-animated-cursor"
6 | import Preloader from './components/Preloader/Preloader'
7 | import ThemeBtn from './components/Header/ThemeButton'
8 | import { ThemeProvider } from './components/Context/Theme'
9 |
10 | function Layout() {
11 | const [themeMode,setThemeMode]= useState("light");
12 | const lightTheme = ()=>{
13 | setThemeMode('light')
14 | }
15 | const darkTheme= ()=>{
16 | setThemeMode('dark')
17 | }
18 | useEffect(()=>{
19 | document.querySelector('html').classList.remove("light","dark")
20 | document.querySelector('html').classList.add(themeMode)
21 | },[themeMode])
22 | return (
23 | <>
24 |
45 |
46 | {/* */}
47 |
48 |
49 | {/* */}
50 |
51 |
52 |
53 |
54 | >
55 | )
56 | }
57 |
58 | export default Layout
--------------------------------------------------------------------------------
/newsfetch/src/assets/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/happyrao78/Hunar/d59138026a511f0f7bf399ea5d14623b8ed00272/newsfetch/src/assets/image.png
--------------------------------------------------------------------------------
/newsfetch/src/assets/react.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/newsfetch/src/components/About/About.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Link, useLoaderData } from 'react-router-dom'
3 | import { FaGithub } from "react-icons/fa";
4 | import { FaLinkedin } from "react-icons/fa";
5 | import { IoEarthOutline } from "react-icons/io5";
6 |
7 | const About = () => {
8 | const data = useLoaderData() // Automatically loads the data
9 |
10 | return (
11 |
12 |
13 | {/*
Github Followers: {data.followers}
*/}
14 |
15 |

22 |
23 |
{data.name}
24 |
{data.location}
25 |
33 |
34 |
35 |
{data.bio}
36 |
37 |
38 |
39 | )
40 | }
41 |
42 | export default About
43 |
44 | export const githubInfoLoader = async () => {
45 | const response = await fetch('https://api.github.com/users/happyrao78',{
46 | headers:{
47 | 'Authorization': import.meta.env.VITE_GITHUB_ACCESS_TOKEN
48 | }
49 | })
50 | return response.json()
51 | }
52 |
--------------------------------------------------------------------------------
/newsfetch/src/components/Blog/Blog.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 |
3 | const Blog = () => {
4 | const [articles, setArticles] = useState([
5 | { id: 1, title: 'First Article', content: 'This is the content of the first article.' },
6 | { id: 2, title: 'Second Article', content: 'This is the content of the second article.' },
7 | { id: 3, title: 'Third Article', content: 'This is the content of the third article.' },
8 | ]);
9 |
10 | const [newArticle, setNewArticle] = useState({ title: '', content: '' });
11 |
12 | const handleAddArticle = () => {
13 | if (newArticle.title && newArticle.content) {
14 | const id = articles.length ? articles[articles.length - 1].id + 1 : 1;
15 | setArticles([...articles, { id, ...newArticle }]);
16 | setNewArticle({ title: '', content: '' });
17 | }
18 | };
19 |
20 | const handleDeleteArticle = (id) => {
21 | setArticles(articles.filter((article) => article.id !== id));
22 | };
23 |
24 | return (
25 |
26 | {/* Add New Article Section */}
27 |
51 |
52 | {/* Article Grid */}
53 |
54 | Articles
55 |
56 | {articles.map((article) => (
57 |
61 |
{article.title}
62 |
{article.content}
63 |
69 |
70 | ))}
71 |
72 |
73 |
74 | );
75 | };
76 |
77 | export default Blog;
78 |
--------------------------------------------------------------------------------
/newsfetch/src/components/Contact/Contact.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 |
3 | export default function Contact() {
4 | const [result, setResult] = useState("");
5 | const [isLoading, setIsLoading] = useState(false);
6 | const [errorMessage, setErrorMessage] = useState("");
7 |
8 | const validateForm = (formData) => {
9 | const email = formData.get("email");
10 | const name = formData.get("name");
11 | const message = formData.get("message");
12 |
13 | // Basic validation
14 | if (!name || !email || !message) {
15 | return "All fields are required";
16 | }
17 |
18 | // Email validation (simple regex)
19 | const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
20 | if (!emailRegex.test(email)) {
21 | return "Please enter a valid email address";
22 | }
23 |
24 | return null;
25 | };
26 |
27 | const onSubmit = async (event) => {
28 | event.preventDefault();
29 | setIsLoading(true);
30 | setResult("");
31 | setErrorMessage("");
32 |
33 | const formData = new FormData(event.target);
34 | formData.append("access_key", "dca63c08-8567-4d70-a8c2-5d1eb5cfe98f");
35 |
36 | // Client-side validation
37 | const validationError = validateForm(formData);
38 | if (validationError) {
39 | setIsLoading(false);
40 | setErrorMessage(validationError);
41 | setTimeout(() => {
42 | setErrorMessage("");
43 | }, 3000);
44 | return;
45 | }
46 |
47 | try {
48 | const response = await fetch("https://api.web3forms.com/submit", {
49 | method: "POST",
50 | body: formData,
51 | });
52 |
53 | const data = await response.json();
54 |
55 | if (data.success) {
56 | setResult("Form Submitted Successfully");
57 | event.target.reset();
58 | } else {
59 | setResult("Error: " + data.message);
60 | }
61 | } catch (error) {
62 | setResult("An unexpected error occurred. Please try again later.");
63 | } finally {
64 | setIsLoading(false);
65 |
66 | setTimeout(() => {
67 | setResult("");
68 | }, 3000);
69 | }
70 | };
71 |
72 | return (
73 |
74 |
75 |
76 | Contact Us
77 |
78 |
138 | {result && (
139 |
144 | {result}
145 |
146 | )}
147 |
148 |
149 | );
150 | }
151 |
--------------------------------------------------------------------------------
/newsfetch/src/components/Context/Theme.js:
--------------------------------------------------------------------------------
1 | import { useContext, createContext } from "react";
2 |
3 | export const ThemeContext= createContext({
4 | lightTheme : ()=>{},
5 | darkTheme : ()=>{},
6 | themeMode : "light"
7 | })
8 | export const ThemeProvider = ThemeContext.Provider
9 | export default function useTheme(){
10 | return useContext(ThemeContext)
11 | }
--------------------------------------------------------------------------------
/newsfetch/src/components/Footer/Footer.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {Link, NavLink} from 'react-router-dom'
3 | import Logo from '../../../public/logo.svg'
4 | const Footer = () => {
5 | return (
6 |
183 | )
184 | }
185 |
186 | export default Footer
--------------------------------------------------------------------------------
/newsfetch/src/components/Header/FireBaseConfig.js:
--------------------------------------------------------------------------------
1 |
2 | import { initializeApp } from 'firebase/app';
3 | import { getAuth, GoogleAuthProvider } from 'firebase/auth';
4 | import { getFirestore } from 'firebase/firestore';
5 |
6 | const firebaseConfig = {
7 | apiKey: "AIzaSyBrwnwHpTP9v6ajijsHIGtEvIAppoR4oR0",
8 | authDomain: "hunar-8f29c.firebaseapp.com",
9 | projectId: "hunar-8f29c",
10 | storageBucket: "hunar-8f29c.appspot.com",
11 | messagingSenderId: "58277786750",
12 | appId: "1:58277786750:web:1e280e0c238f55a155d42f",
13 | measurementId: "G-JLJR8WPWM1"
14 | };
15 |
16 | const app = initializeApp(firebaseConfig);
17 | const auth = getAuth(app);
18 | const provider = new GoogleAuthProvider();
19 | const db = getFirestore(app);
20 |
21 | export { auth, provider, db };
22 |
--------------------------------------------------------------------------------
/newsfetch/src/components/Header/Header.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react';
2 | import { Link, NavLink } from 'react-router-dom';
3 | import Logo from '../../../public/logo.svg';
4 | import { auth, provider } from './FireBaseConfig';
5 | import { signInWithPopup, signOut } from 'firebase/auth';
6 | // import useTheme from '../Context/Theme';
7 | import ThemeBtn from './ThemeButton';
8 | // Adjust the path to your firebaseConfig.js
9 |
10 | function Header() {
11 | const [isMenuOpen, setIsMenuOpen] = useState(false);
12 | const [user, setUser] = useState(null);
13 |
14 | useEffect(() => {
15 | const unsubscribe = auth.onAuthStateChanged((user) => {
16 | if (user) {
17 | setUser(user);
18 | } else {
19 | setUser(null);
20 | }
21 | });
22 |
23 | return () => unsubscribe();
24 | }, []);
25 |
26 | const handleLogin = async () => {
27 | try {
28 | const result = await signInWithPopup(auth, provider);
29 | const credential = GoogleAuthProvider.credentialFromResult(result);
30 | const token = credential.accessToken;
31 | const user = result.user;
32 | console.log('User signed in: ', user);
33 | } catch (error) {
34 | console.error('Error signing in: ', error);
35 | }
36 | };
37 |
38 | const handleLogout = async () => {
39 | try {
40 | await signOut(auth);
41 | setUser(null);
42 | } catch (error) {
43 | console.error('Error signing out: ', error);
44 | }
45 | };
46 |
47 | return (
48 |
49 |
159 |
160 | );
161 | }
162 |
163 | export default Header;
164 |
--------------------------------------------------------------------------------
/newsfetch/src/components/Header/ThemeButton.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import useTheme from '../Context/Theme'
3 |
4 | function ThemeBtn() {
5 | const{themeMode,lightTheme,darkTheme}=useTheme()
6 | const onChangeBtn=(e)=>{
7 | const darkModeStatus = e.currentTarget.checked
8 | if(darkModeStatus){
9 | darkTheme();
10 | }
11 | else{
12 | lightTheme();
13 | }
14 | }
15 | return (
16 |
27 | )
28 | }
29 |
30 | export default ThemeBtn
--------------------------------------------------------------------------------
/newsfetch/src/components/NewsDetail/NewsDetail.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { useLocation } from 'react-router-dom';
3 |
4 | function NewsDetail() {
5 | const location = useLocation();
6 | const { article } = location.state || {};
7 |
8 | return (
9 |
10 | {article ? (
11 |
12 |

17 |
{article.title}
18 |
{article.description}
19 |
20 | ) : (
21 |
No article to display
22 | )}
23 |
24 | );
25 | }
26 |
27 | export default NewsDetail;
28 |
--------------------------------------------------------------------------------
/newsfetch/src/components/Preloader/Preloader.css:
--------------------------------------------------------------------------------
1 | .preloader{
2 | height:100vh;
3 | width: 100%;
4 | background: #000;
5 | color: #fff;
6 | position: fixed;
7 | bottom: 0;
8 | left: 0;
9 | right: 0;
10 | z-index: 55;
11 | display: flex;
12 | justify-content: center;
13 | align-items: center;
14 | overflow: hidden;
15 | }
16 | .preloader .texts-container{
17 | display: flex;
18 | align-items: center;
19 | justify-content: space-between;
20 | height: 60px;
21 | width: 300px;
22 | font-size: 25px;
23 | font-weight: 600;
24 | overflow: hidden;
25 | color: #fff;
26 | }
--------------------------------------------------------------------------------
/newsfetch/src/components/Preloader/Preloader.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from 'react'
2 | import './Preloader.css'
3 | import { preLoaderAnim } from '../../Animations/index'
4 | function Preloader() {
5 | useEffect(()=>{
6 | preLoaderAnim()
7 | },[]);
8 | return (
9 |
10 |
11 | Welcome
12 | to
13 | NewsMania
14 |
15 |
16 | )
17 | }
18 |
19 | export default Preloader
--------------------------------------------------------------------------------
/newsfetch/src/components/Slider/Carousel.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Slider from "react-slick";
3 | import "slick-carousel/slick/slick.css";
4 | import "slick-carousel/slick/slick-theme.css";
5 |
6 | const Carousel = () => {
7 | const data = [
8 | {
9 | name: "Happy Yadav",
10 | img: "https://media.licdn.com/dms/image/v2/D5603AQEalnJ9oj3hFg/profile-displayphoto-shrink_200_200/profile-displayphoto-shrink_200_200/0/1727021664030?e=2147483647&v=beta&t=vFwF1j-O6WHPaOyGn0E7P_nRTbpnhGREdhnWRpAc43Y",
11 | review: "TBD",
12 | },
13 | {
14 | name: "Happy Yadav",
15 | img: "https://media.licdn.com/dms/image/v2/D5603AQEalnJ9oj3hFg/profile-displayphoto-shrink_200_200/profile-displayphoto-shrink_200_200/0/1727021664030?e=2147483647&v=beta&t=vFwF1j-O6WHPaOyGn0E7P_nRTbpnhGREdhnWRpAc43Y",
16 | review: "TBD",
17 | },
18 | {
19 | name: "Happy Yadav",
20 | img: "https://media.licdn.com/dms/image/v2/D5603AQEalnJ9oj3hFg/profile-displayphoto-shrink_200_200/profile-displayphoto-shrink_200_200/0/1727021664030?e=2147483647&v=beta&t=vFwF1j-O6WHPaOyGn0E7P_nRTbpnhGREdhnWRpAc43Y",
21 | review: "TBD",
22 | },
23 | {
24 | name: "Happy Yadav",
25 | img: "https://media.licdn.com/dms/image/v2/D5603AQEalnJ9oj3hFg/profile-displayphoto-shrink_200_200/profile-displayphoto-shrink_200_200/0/1727021664030?e=2147483647&v=beta&t=vFwF1j-O6WHPaOyGn0E7P_nRTbpnhGREdhnWRpAc43Y",
26 | review: "TBD",
27 | },
28 | {
29 | name: "Happy Yadav",
30 | img: "https://media.licdn.com/dms/image/v2/D5603AQEalnJ9oj3hFg/profile-displayphoto-shrink_200_200/profile-displayphoto-shrink_200_200/0/1727021664030?e=2147483647&v=beta&t=vFwF1j-O6WHPaOyGn0E7P_nRTbpnhGREdhnWRpAc43Y",
31 | review: "TBD",
32 | },
33 | ];
34 |
35 | const settings = {
36 | dots: true,
37 | infinite: true,
38 | speed: 500,
39 | slidesToShow: 3,
40 | slidesToScroll: 1,
41 | autoplay: true,
42 | autoplaySpeed: 2000,
43 | cssEase: "linear",
44 | responsive: [
45 | {
46 | breakpoint: 1024,
47 | settings: {
48 | slidesToShow: 2,
49 | slidesToScroll: 1,
50 | infinite: true,
51 | dots: true,
52 | },
53 | },
54 | {
55 | breakpoint: 600,
56 | settings: {
57 | slidesToShow: 2,
58 | slidesToScroll: 1,
59 | },
60 | },
61 | {
62 | breakpoint: 480,
63 | settings: {
64 | slidesToShow: 1,
65 | slidesToScroll: 1,
66 | },
67 | },
68 | ],
69 | };
70 |
71 | return (
72 | //
73 | //
74 | //
75 | // {data.map((d, index) => (
76 | //
77 | //
78 | //
79 | //

85 | //
86 | //
87 | //
{d.name}
88 | //
{d.review}
89 | //
92 | //
93 | //
94 | //
95 | // ))}
96 | //
97 | //
98 | //
99 |
100 | );
101 | };
102 |
103 | export default Carousel;
104 |
--------------------------------------------------------------------------------
/newsfetch/src/components/TrendingNews/TrendingNews.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import axios from "axios";
3 | import { useNavigate } from "react-router-dom";
4 | import Carousel from "../Slider/Carousel";
5 |
6 | function TrendingNews() {
7 | const [news, setNews] = useState([]);
8 | const [loading, setLoading] = useState(true); // Loading state
9 | const navigate = useNavigate();
10 | const defaultImage =
11 | "https://yt3.googleusercontent.com/VbGkSvLpAmSOVxSQ-42YlR4uQjaRbADrBZ0Jbm8rpeI7RiFSEp2_8DJqzgqH4dWViwYOQy2QJnQ=s900-c-k-c0x00ffffff-no-rj";
12 |
13 | useEffect(() => {
14 | setLoading(true); // Start loading
15 | axios
16 | .get("https://backend-server-jsdp.vercel.app/api/news")
17 | .then((response) => {
18 | const filteredNews = response.data.articles.filter(
19 | (article) =>
20 | article.source.name === "The Times of India" || "google-news"
21 | );
22 | setNews(filteredNews.slice(0, 20));
23 | setLoading(false); // Stop loading after data is fetched
24 | })
25 | .catch((error) => {
26 | console.error("Error fetching the news", error);
27 | setLoading(false); // Stop loading even if there's an error
28 | });
29 | }, []);
30 |
31 | const handleReadMore = (article) => {
32 | navigate("/newsdetail", { state: { article } });
33 | };
34 |
35 | const getFirstWords = (text, wordCount) => {
36 | return text.split(" ").slice(0, wordCount).join(" ");
37 | };
38 |
39 | return (
40 | <>
41 |
42 |
43 |
44 | TOP BUSINESS HEADLINES
45 |
46 |
47 | {loading ? (
48 |
49 | {Array.from({ length: 12 }).map((_, index) => (
50 |
54 | {/* Placeholder for the image */}
55 |
56 | {/* Placeholder for the text */}
57 |
61 | {/* Placeholder for the button */}
62 |
65 |
66 | ))}
67 |
68 | ) : (
69 |
70 | {news.map((article, index) => (
71 |
75 |

80 |
81 |
82 | {getFirstWords(article.title, 10)}
83 |
84 |
85 |
86 |
92 |
93 |
94 | ))}
95 |
96 | )}
97 |
98 | {!loading &&
}
99 |
100 | >
101 | );
102 | }
103 |
104 | export default TrendingNews;
105 |
--------------------------------------------------------------------------------
/newsfetch/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 | @layer base{
5 | body {
6 | background-color: #14161b;
7 | }
8 | }
9 |
10 | .slick-slide > div {
11 | margin: 0 10px;
12 | }
13 |
14 | .slick-dots li.slick-active button:before {
15 | color:orange !important;
16 | }
--------------------------------------------------------------------------------
/newsfetch/src/main.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom/client'
3 | import Layout from './Layout'
4 | import { Route } from 'react-router-dom'
5 | import About , {githubInfoLoader}from './components/About/About'
6 | import TrendingNews from './components/TrendingNews/TrendingNews'
7 | import Contact from './components/Contact/Contact'
8 | import Blog from './components/Blog/Blog'
9 | import NewsDetail from './components/NewsDetail/NewsDetail'
10 | import { RouterProvider, createBrowserRouter, createRoutesFromElements } from 'react-router-dom'
11 |
12 | // import App from './App.jsx'
13 | import './index.css'
14 |
15 | const router = createBrowserRouter(
16 | createRoutesFromElements(
17 | }>
18 | } />
19 | } />
20 | } />
21 | } />
22 | } />
23 |
24 |
25 |
26 | )
27 | )
28 |
29 | ReactDOM.createRoot(document.getElementById('root')).render(
30 |
31 | {/* */}
32 |
33 |
34 | ,
35 | )
36 |
--------------------------------------------------------------------------------
/newsfetch/style.css:
--------------------------------------------------------------------------------
1 | body{
2 | font-family: 'EB Garamond';
3 | }
--------------------------------------------------------------------------------
/newsfetch/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | content: [
4 | "./index.html",
5 | "./src/**/*.{js,ts,jsx,tsx}",
6 | ],
7 | darkMode: "class",
8 | theme: {
9 | extend: {},
10 | },
11 | plugins: [],
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/newsfetch/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | server:{
7 | proxy:{
8 | '/api': {
9 |
10 | target: 'http://localhost:8080',
11 |
12 | // target: 'https://newsapi.org/v2/top-headlines?country=in&category=business&apiKey=74816c3690434f50b56a475c71cd3b56',
13 |
14 | changeOrigin: true,
15 | secure: false,
16 | }
17 | }
18 | },
19 | plugins: [react()],
20 | build:{
21 | outDir: 'dist',
22 | },
23 | })
24 |
--------------------------------------------------------------------------------
/server/.env.sample:
--------------------------------------------------------------------------------
1 | NEWS_API_KEY= # Your News API key here
--------------------------------------------------------------------------------
/server/.firebase/hosting.cHVibGlj.cache:
--------------------------------------------------------------------------------
1 | index.html,1726344717376,19dec9818b45cce35af1777687001d189ee2c680e8bf305e25410db6c3f881d2
2 |
--------------------------------------------------------------------------------
/server/.firebaserc:
--------------------------------------------------------------------------------
1 | {
2 | "projects": {
3 | "default": "codingninja-96464"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/server/.github/workflows/firebase-hosting-merge.yml:
--------------------------------------------------------------------------------
1 | # This file was auto-generated by the Firebase CLI
2 | # https://github.com/firebase/firebase-tools
3 |
4 | name: Deploy to Firebase Hosting on merge
5 | on:
6 | push:
7 | branches:
8 | - master
9 | jobs:
10 | build_and_deploy:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v4
14 | - run: npm run build
15 | - uses: FirebaseExtended/action-hosting-deploy@v0
16 | with:
17 | repoToken: ${{ secrets.GITHUB_TOKEN }}
18 | firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_CODINGNINJA_96464 }}
19 | channelId: live
20 | projectId: codingninja-96464
21 |
--------------------------------------------------------------------------------
/server/.github/workflows/firebase-hosting-pull-request.yml:
--------------------------------------------------------------------------------
1 | # This file was auto-generated by the Firebase CLI
2 | # https://github.com/firebase/firebase-tools
3 |
4 | name: Deploy to Firebase Hosting on PR
5 | on: pull_request
6 | permissions:
7 | checks: write
8 | contents: read
9 | pull-requests: write
10 | jobs:
11 | build_and_preview:
12 | if: ${{ github.event.pull_request.head.repo.full_name == github.repository }}
13 | runs-on: ubuntu-latest
14 | steps:
15 | - uses: actions/checkout@v4
16 | - run: npm run build
17 | - uses: FirebaseExtended/action-hosting-deploy@v0
18 | with:
19 | repoToken: ${{ secrets.GITHUB_TOKEN }}
20 | firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_CODINGNINJA_96464 }}
21 | projectId: codingninja-96464
22 |
--------------------------------------------------------------------------------
/server/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | .env
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 | .vercel
26 |
--------------------------------------------------------------------------------
/server/bun.lockb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/happyrao78/Hunar/d59138026a511f0f7bf399ea5d14623b8ed00272/server/bun.lockb
--------------------------------------------------------------------------------
/server/dist/assets/image-Cs6Ew6q3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/happyrao78/Hunar/d59138026a511f0f7bf399ea5d14623b8ed00272/server/dist/assets/image-Cs6Ew6q3.png
--------------------------------------------------------------------------------
/server/dist/assets/index-CxmS_tQk.css:
--------------------------------------------------------------------------------
1 | *,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }.container{width:100%}@media (min-width: 640px){.container{max-width:640px}}@media (min-width: 768px){.container{max-width:768px}}@media (min-width: 1024px){.container{max-width:1024px}}@media (min-width: 1280px){.container{max-width:1280px}}@media (min-width: 1536px){.container{max-width:1536px}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.sticky{position:sticky}.top-0{top:0}.z-50{z-index:50}.m-4{margin:1rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-auto{margin-left:auto;margin-right:auto}.my-6{margin-top:1.5rem;margin-bottom:1.5rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-2{margin-left:.5rem}.mr-1{margin-right:.25rem}.mr-4{margin-right:1rem}.mt-1{margin-top:.25rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.line-clamp-3{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.hidden{display:none}.h-12{height:3rem}.h-4{height:1rem}.h-40{height:10rem}.h-6{height:1.5rem}.h-64{height:16rem}.min-h-screen{min-height:100vh}.w-12{width:3rem}.w-4{width:1rem}.w-6{width:1.5rem}.w-full{width:100%}.max-w-3xl{max-width:48rem}.max-w-md{max-width:28rem}.max-w-screen-xl{max-width:1280px}.max-w-sm{max-width:24rem}.max-w-xs{max-width:20rem}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-6{gap:1.5rem}.gap-8{gap:2rem}.space-x-5>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(1.25rem * var(--tw-space-x-reverse));margin-left:calc(1.25rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.rounded-2xl{border-radius:1rem}.rounded-3xl{border-radius:1.5rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-4{border-width:4px}.border-y{border-top-width:1px;border-bottom-width:1px}.border-b{border-bottom-width:1px}.border-gray-100{--tw-border-opacity: 1;border-color:rgb(243 244 246 / var(--tw-border-opacity))}.border-gray-200{--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity))}.border-gray-300{--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity))}.border-transparent{border-color:transparent}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity))}.bg-gray-200{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity))}.bg-gray-400{--tw-bg-opacity: 1;background-color:rgb(156 163 175 / var(--tw-bg-opacity))}.bg-green-100{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity))}.bg-green-900{--tw-bg-opacity: 1;background-color:rgb(20 83 45 / var(--tw-bg-opacity))}.bg-indigo-600{--tw-bg-opacity: 1;background-color:rgb(79 70 229 / var(--tw-bg-opacity))}.bg-orange-700{--tw-bg-opacity: 1;background-color:rgb(194 65 12 / var(--tw-bg-opacity))}.bg-red-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity))}.object-cover{-o-object-fit:cover;object-fit:cover}.p-2{padding:.5rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.pb-2{padding-bottom:.5rem}.pl-3{padding-left:.75rem}.pr-4{padding-right:1rem}.pt-2{padding-top:.5rem}.text-center{text-align:center}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-5xl{font-size:3rem;line-height:1}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.text-black{--tw-text-opacity: 1;color:rgb(0 0 0 / var(--tw-text-opacity))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity))}.text-gray-800{--tw-text-opacity: 1;color:rgb(31 41 55 / var(--tw-text-opacity))}.text-gray-900{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity))}.text-orange-700{--tw-text-opacity: 1;color:rgb(194 65 12 / var(--tw-text-opacity))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity))}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.hover\:scale-105:hover{--tw-scale-x: 1.05;--tw-scale-y: 1.05;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:bg-blue-700:hover{--tw-bg-opacity: 1;background-color:rgb(29 78 216 / var(--tw-bg-opacity))}.hover\:bg-gray-50:hover{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity))}.hover\:bg-indigo-700:hover{--tw-bg-opacity: 1;background-color:rgb(67 56 202 / var(--tw-bg-opacity))}.hover\:bg-orange-800:hover{--tw-bg-opacity: 1;background-color:rgb(154 52 18 / var(--tw-bg-opacity))}.hover\:text-gray-900:hover{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity))}.hover\:text-orange-700:hover{--tw-text-opacity: 1;color:rgb(194 65 12 / var(--tw-text-opacity))}.hover\:underline:hover{text-decoration-line:underline}.focus\:border-indigo-500:focus{--tw-border-opacity: 1;border-color:rgb(99 102 241 / var(--tw-border-opacity))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-4:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-gray-300:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(209 213 219 / var(--tw-ring-opacity))}.focus\:ring-indigo-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(99 102 241 / var(--tw-ring-opacity))}.focus\:ring-orange-300:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(253 186 116 / var(--tw-ring-opacity))}.focus\:ring-offset-2:focus{--tw-ring-offset-width: 2px}@media (min-width: 640px){.sm\:mx-auto{margin-left:auto;margin-right:auto}.sm\:mt-0{margin-top:0}.sm\:flex{display:flex}.sm\:h-10{height:2.5rem}.sm\:w-10{width:2.5rem}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:items-center{align-items:center}.sm\:justify-center{justify-content:center}.sm\:justify-between{justify-content:space-between}.sm\:gap-6{gap:1.5rem}.sm\:text-center{text-align:center}}@media (min-width: 768px){.md\:mb-0{margin-bottom:0}.md\:mr-2{margin-right:.5rem}.md\:flex{display:flex}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:justify-between{justify-content:space-between}.md\:px-4{padding-left:1rem;padding-right:1rem}.md\:py-2{padding-top:.5rem;padding-bottom:.5rem}.md\:text-lg{font-size:1.125rem;line-height:1.75rem}}@media (min-width: 1024px){.lg\:order-1{order:1}.lg\:order-2{order:2}.lg\:my-8{margin-top:2rem;margin-bottom:2rem}.lg\:mt-0{margin-top:0}.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:h-20{height:5rem}.lg\:w-20{width:5rem}.lg\:w-auto{width:auto}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:space-x-8>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(2rem * var(--tw-space-x-reverse));margin-left:calc(2rem * calc(1 - var(--tw-space-x-reverse)))}.lg\:border-0{border-width:0px}.lg\:p-0{padding:0}.lg\:px-6{padding-left:1.5rem;padding-right:1.5rem}.lg\:py-2{padding-top:.5rem;padding-bottom:.5rem}.lg\:py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.lg\:py-8{padding-top:2rem;padding-bottom:2rem}.lg\:text-xl{font-size:1.25rem;line-height:1.75rem}.lg\:hover\:bg-transparent:hover{background-color:transparent}}
2 |
--------------------------------------------------------------------------------
/server/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + React
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/server/dist/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server/firebase.json:
--------------------------------------------------------------------------------
1 | {
2 | "hosting": {
3 | "public": "public",
4 | "ignore": [
5 | "firebase.json",
6 | "**/.*",
7 | "**/node_modules/**"
8 | ],
9 | "rewrites": [
10 | {
11 | "source": "**",
12 | "destination": "/index.html"
13 | }
14 | ]
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/server/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "server",
3 | "lockfileVersion": 3,
4 | "requires": true,
5 | "packages": {
6 | "": {
7 | "dependencies": {
8 | "axios": "^1.7.2",
9 | "cors": "^2.8.5",
10 | "dotenv": "^16.4.5",
11 | "express": "^4.19.2",
12 | "firebase": "^10.13.1"
13 | }
14 | },
15 | "node_modules/@firebase/analytics": {
16 | "version": "0.10.7",
17 | "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.7.tgz",
18 | "integrity": "sha512-GE29uTT6y/Jv2EP0OjpTezeTQZ5FTCTaZXKrrdVGjb/t35AU4u/jiU+hUwUPpuK8fqhhiHkS/AawE3a3ZK/a9Q==",
19 | "license": "Apache-2.0",
20 | "dependencies": {
21 | "@firebase/component": "0.6.8",
22 | "@firebase/installations": "0.6.8",
23 | "@firebase/logger": "0.4.2",
24 | "@firebase/util": "1.9.7",
25 | "tslib": "^2.1.0"
26 | },
27 | "peerDependencies": {
28 | "@firebase/app": "0.x"
29 | }
30 | },
31 | "node_modules/@firebase/analytics-compat": {
32 | "version": "0.2.13",
33 | "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.13.tgz",
34 | "integrity": "sha512-aZ4wGfNDMsCxhKzDbK2g1aV0JKsdQ9FbeIsjpNJPzhahV0XYj+z36Y4RNLPpG/6hHU4gxnezxs+yn3HhHkNL8w==",
35 | "license": "Apache-2.0",
36 | "dependencies": {
37 | "@firebase/analytics": "0.10.7",
38 | "@firebase/analytics-types": "0.8.2",
39 | "@firebase/component": "0.6.8",
40 | "@firebase/util": "1.9.7",
41 | "tslib": "^2.1.0"
42 | },
43 | "peerDependencies": {
44 | "@firebase/app-compat": "0.x"
45 | }
46 | },
47 | "node_modules/@firebase/analytics-types": {
48 | "version": "0.8.2",
49 | "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.2.tgz",
50 | "integrity": "sha512-EnzNNLh+9/sJsimsA/FGqzakmrAUKLeJvjRHlg8df1f97NLUlFidk9600y0ZgWOp3CAxn6Hjtk+08tixlUOWyw==",
51 | "license": "Apache-2.0"
52 | },
53 | "node_modules/@firebase/app": {
54 | "version": "0.10.10",
55 | "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.10.tgz",
56 | "integrity": "sha512-sDqkdeFdVn5uygQm5EuIKOQ6/wxTcX/qKfm0MR46AiwLRHGLCDUMrXBkc8GhkK3ca2d6mPUSfPmndggo43D6PQ==",
57 | "license": "Apache-2.0",
58 | "dependencies": {
59 | "@firebase/component": "0.6.8",
60 | "@firebase/logger": "0.4.2",
61 | "@firebase/util": "1.9.7",
62 | "idb": "7.1.1",
63 | "tslib": "^2.1.0"
64 | }
65 | },
66 | "node_modules/@firebase/app-check": {
67 | "version": "0.8.7",
68 | "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.8.7.tgz",
69 | "integrity": "sha512-EkOeJcMKVR0zZ6z/jqcFTqHb/xq+TVIRIuBNGHdpcIuFU1czhSlegvqv2+nC+nFrkD8M6Xvd3tAlUOkdbMeS6A==",
70 | "license": "Apache-2.0",
71 | "dependencies": {
72 | "@firebase/component": "0.6.8",
73 | "@firebase/logger": "0.4.2",
74 | "@firebase/util": "1.9.7",
75 | "tslib": "^2.1.0"
76 | },
77 | "peerDependencies": {
78 | "@firebase/app": "0.x"
79 | }
80 | },
81 | "node_modules/@firebase/app-check-compat": {
82 | "version": "0.3.14",
83 | "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.14.tgz",
84 | "integrity": "sha512-kK3bPfojAfXE53W+20rxMqIxrloFswXG9vh4kEdYL6Wa2IB3sD5++2dPiK3yGxl8oQiqS8qL2wcKB5/xLpEVEg==",
85 | "license": "Apache-2.0",
86 | "dependencies": {
87 | "@firebase/app-check": "0.8.7",
88 | "@firebase/app-check-types": "0.5.2",
89 | "@firebase/component": "0.6.8",
90 | "@firebase/logger": "0.4.2",
91 | "@firebase/util": "1.9.7",
92 | "tslib": "^2.1.0"
93 | },
94 | "peerDependencies": {
95 | "@firebase/app-compat": "0.x"
96 | }
97 | },
98 | "node_modules/@firebase/app-check-interop-types": {
99 | "version": "0.3.2",
100 | "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.2.tgz",
101 | "integrity": "sha512-LMs47Vinv2HBMZi49C09dJxp0QT5LwDzFaVGf/+ITHe3BlIhUiLNttkATSXplc89A2lAaeTqjgqVkiRfUGyQiQ==",
102 | "license": "Apache-2.0"
103 | },
104 | "node_modules/@firebase/app-check-types": {
105 | "version": "0.5.2",
106 | "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.2.tgz",
107 | "integrity": "sha512-FSOEzTzL5bLUbD2co3Zut46iyPWML6xc4x+78TeaXMSuJap5QObfb+rVvZJtla3asN4RwU7elaQaduP+HFizDA==",
108 | "license": "Apache-2.0"
109 | },
110 | "node_modules/@firebase/app-compat": {
111 | "version": "0.2.40",
112 | "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.40.tgz",
113 | "integrity": "sha512-2L5MW4MH2ya7Wvw0hzWy3ZWeB4SqC5gYXDAV5AS1lBTL4zL3k8dsqJmry/cFV00GgkCI01WJbcXvFMCXJvgyow==",
114 | "license": "Apache-2.0",
115 | "dependencies": {
116 | "@firebase/app": "0.10.10",
117 | "@firebase/component": "0.6.8",
118 | "@firebase/logger": "0.4.2",
119 | "@firebase/util": "1.9.7",
120 | "tslib": "^2.1.0"
121 | }
122 | },
123 | "node_modules/@firebase/app-types": {
124 | "version": "0.9.2",
125 | "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.2.tgz",
126 | "integrity": "sha512-oMEZ1TDlBz479lmABwWsWjzHwheQKiAgnuKxE0pz0IXCVx7/rtlkx1fQ6GfgK24WCrxDKMplZrT50Kh04iMbXQ==",
127 | "license": "Apache-2.0"
128 | },
129 | "node_modules/@firebase/auth": {
130 | "version": "1.7.8",
131 | "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.7.8.tgz",
132 | "integrity": "sha512-1KJlDrTrEEFTIBj9MxjAWjQ4skecBD4bmoayQ0l14QDbNc1a8qGbi+MFSJkH7O6VnGE6bTMcWSw6RrQNecqKaw==",
133 | "license": "Apache-2.0",
134 | "dependencies": {
135 | "@firebase/component": "0.6.8",
136 | "@firebase/logger": "0.4.2",
137 | "@firebase/util": "1.9.7",
138 | "tslib": "^2.1.0",
139 | "undici": "6.19.7"
140 | },
141 | "peerDependencies": {
142 | "@firebase/app": "0.x",
143 | "@react-native-async-storage/async-storage": "^1.18.1"
144 | },
145 | "peerDependenciesMeta": {
146 | "@react-native-async-storage/async-storage": {
147 | "optional": true
148 | }
149 | }
150 | },
151 | "node_modules/@firebase/auth-compat": {
152 | "version": "0.5.13",
153 | "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.13.tgz",
154 | "integrity": "sha512-rV6TMxUU6wBBZ2ouDMtjJsJXeewtvYvVzslzt3/P7O/kxiWlreHT/2M/1guMiXKo3zk52XK3GqP0uM2bN7fEow==",
155 | "license": "Apache-2.0",
156 | "dependencies": {
157 | "@firebase/auth": "1.7.8",
158 | "@firebase/auth-types": "0.12.2",
159 | "@firebase/component": "0.6.8",
160 | "@firebase/util": "1.9.7",
161 | "tslib": "^2.1.0",
162 | "undici": "6.19.7"
163 | },
164 | "peerDependencies": {
165 | "@firebase/app-compat": "0.x"
166 | }
167 | },
168 | "node_modules/@firebase/auth-interop-types": {
169 | "version": "0.2.3",
170 | "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.3.tgz",
171 | "integrity": "sha512-Fc9wuJGgxoxQeavybiuwgyi+0rssr76b+nHpj+eGhXFYAdudMWyfBHvFL/I5fEHniUM/UQdFzi9VXJK2iZF7FQ==",
172 | "license": "Apache-2.0"
173 | },
174 | "node_modules/@firebase/auth-types": {
175 | "version": "0.12.2",
176 | "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.2.tgz",
177 | "integrity": "sha512-qsEBaRMoGvHO10unlDJhaKSuPn4pyoTtlQuP1ghZfzB6rNQPuhp/N/DcFZxm9i4v0SogjCbf9reWupwIvfmH6w==",
178 | "license": "Apache-2.0",
179 | "peerDependencies": {
180 | "@firebase/app-types": "0.x",
181 | "@firebase/util": "1.x"
182 | }
183 | },
184 | "node_modules/@firebase/component": {
185 | "version": "0.6.8",
186 | "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.8.tgz",
187 | "integrity": "sha512-LcNvxGLLGjBwB0dJUsBGCej2fqAepWyBubs4jt1Tiuns7QLbXHuyObZ4aMeBjZjWx4m8g1LoVI9QFpSaq/k4/g==",
188 | "license": "Apache-2.0",
189 | "dependencies": {
190 | "@firebase/util": "1.9.7",
191 | "tslib": "^2.1.0"
192 | }
193 | },
194 | "node_modules/@firebase/database": {
195 | "version": "1.0.7",
196 | "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.7.tgz",
197 | "integrity": "sha512-wjXr5AO8RPxVVg7rRCYffT7FMtBjHRfJ9KMwi19MbOf0vBf0H9YqW3WCgcnLpXI6ehiUcU3z3qgPnnU0nK6SnA==",
198 | "license": "Apache-2.0",
199 | "dependencies": {
200 | "@firebase/app-check-interop-types": "0.3.2",
201 | "@firebase/auth-interop-types": "0.2.3",
202 | "@firebase/component": "0.6.8",
203 | "@firebase/logger": "0.4.2",
204 | "@firebase/util": "1.9.7",
205 | "faye-websocket": "0.11.4",
206 | "tslib": "^2.1.0"
207 | }
208 | },
209 | "node_modules/@firebase/database-compat": {
210 | "version": "1.0.7",
211 | "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-1.0.7.tgz",
212 | "integrity": "sha512-R/3B+VVzEFN5YcHmfWns3eitA8fHLTL03io+FIoMcTYkajFnrBdS3A+g/KceN9omP7FYYYGTQWF9lvbEx6eMEg==",
213 | "license": "Apache-2.0",
214 | "dependencies": {
215 | "@firebase/component": "0.6.8",
216 | "@firebase/database": "1.0.7",
217 | "@firebase/database-types": "1.0.4",
218 | "@firebase/logger": "0.4.2",
219 | "@firebase/util": "1.9.7",
220 | "tslib": "^2.1.0"
221 | }
222 | },
223 | "node_modules/@firebase/database-types": {
224 | "version": "1.0.4",
225 | "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.4.tgz",
226 | "integrity": "sha512-mz9ZzbH6euFXbcBo+enuJ36I5dR5w+enJHHjy9Y5ThCdKUseqfDjW3vCp1YxE9zygFCSjJJ/z1cQ+zodvUcwPQ==",
227 | "license": "Apache-2.0",
228 | "dependencies": {
229 | "@firebase/app-types": "0.9.2",
230 | "@firebase/util": "1.9.7"
231 | }
232 | },
233 | "node_modules/@firebase/firestore": {
234 | "version": "4.7.1",
235 | "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.7.1.tgz",
236 | "integrity": "sha512-WliQNa8GVcH6EWkH0NAf+uAnxNiBuH+G8Buzr2ZS1NznOhJDK/q6Hsjv5TzNrijLTAdEfj/wk9VEv994KDSjxg==",
237 | "license": "Apache-2.0",
238 | "dependencies": {
239 | "@firebase/component": "0.6.8",
240 | "@firebase/logger": "0.4.2",
241 | "@firebase/util": "1.9.7",
242 | "@firebase/webchannel-wrapper": "1.0.1",
243 | "@grpc/grpc-js": "~1.9.0",
244 | "@grpc/proto-loader": "^0.7.8",
245 | "tslib": "^2.1.0",
246 | "undici": "6.19.7"
247 | },
248 | "engines": {
249 | "node": ">=10.10.0"
250 | },
251 | "peerDependencies": {
252 | "@firebase/app": "0.x"
253 | }
254 | },
255 | "node_modules/@firebase/firestore-compat": {
256 | "version": "0.3.36",
257 | "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.36.tgz",
258 | "integrity": "sha512-NtoIm7CT9f+SFB7cPMCtyCSxZReh/+SII5X4TQH394S3dwhru9HIfvEOKAMuAnXsSsLH72jXPUgdsEAUqg6Oug==",
259 | "license": "Apache-2.0",
260 | "dependencies": {
261 | "@firebase/component": "0.6.8",
262 | "@firebase/firestore": "4.7.1",
263 | "@firebase/firestore-types": "3.0.2",
264 | "@firebase/util": "1.9.7",
265 | "tslib": "^2.1.0"
266 | },
267 | "peerDependencies": {
268 | "@firebase/app-compat": "0.x"
269 | }
270 | },
271 | "node_modules/@firebase/firestore-types": {
272 | "version": "3.0.2",
273 | "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.2.tgz",
274 | "integrity": "sha512-wp1A+t5rI2Qc/2q7r2ZpjUXkRVPtGMd6zCLsiWurjsQpqPgFin3AhNibKcIzoF2rnToNa/XYtyWXuifjOOwDgg==",
275 | "license": "Apache-2.0",
276 | "peerDependencies": {
277 | "@firebase/app-types": "0.x",
278 | "@firebase/util": "1.x"
279 | }
280 | },
281 | "node_modules/@firebase/functions": {
282 | "version": "0.11.7",
283 | "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.11.7.tgz",
284 | "integrity": "sha512-xaUsGI2kYrI8zJXgrNB7SrJKB8v1vJqR16YYi6g6dFTgBz4+VzWJFqqVU60BbdAWm6fXnUrg9gjlJQeqomT2Vg==",
285 | "license": "Apache-2.0",
286 | "dependencies": {
287 | "@firebase/app-check-interop-types": "0.3.2",
288 | "@firebase/auth-interop-types": "0.2.3",
289 | "@firebase/component": "0.6.8",
290 | "@firebase/messaging-interop-types": "0.2.2",
291 | "@firebase/util": "1.9.7",
292 | "tslib": "^2.1.0",
293 | "undici": "6.19.7"
294 | },
295 | "peerDependencies": {
296 | "@firebase/app": "0.x"
297 | }
298 | },
299 | "node_modules/@firebase/functions-compat": {
300 | "version": "0.3.13",
301 | "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.13.tgz",
302 | "integrity": "sha512-qcZvJO2ed6PAD+18DanVztw7WyQVQK43HoRhxusHAwDFvK/xY+mcGpj+IpfdxTNMBGCOIxKFp4Xqk/c2nubBlQ==",
303 | "license": "Apache-2.0",
304 | "dependencies": {
305 | "@firebase/component": "0.6.8",
306 | "@firebase/functions": "0.11.7",
307 | "@firebase/functions-types": "0.6.2",
308 | "@firebase/util": "1.9.7",
309 | "tslib": "^2.1.0"
310 | },
311 | "peerDependencies": {
312 | "@firebase/app-compat": "0.x"
313 | }
314 | },
315 | "node_modules/@firebase/functions-types": {
316 | "version": "0.6.2",
317 | "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.2.tgz",
318 | "integrity": "sha512-0KiJ9lZ28nS2iJJvimpY4nNccV21rkQyor5Iheu/nq8aKXJqtJdeSlZDspjPSBBiHRzo7/GMUttegnsEITqR+w==",
319 | "license": "Apache-2.0"
320 | },
321 | "node_modules/@firebase/installations": {
322 | "version": "0.6.8",
323 | "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.8.tgz",
324 | "integrity": "sha512-57V374qdb2+wT5v7+ntpLXBjZkO6WRgmAUbVkRfFTM/4t980p0FesbqTAcOIiM8U866UeuuuF8lYH70D3jM/jQ==",
325 | "license": "Apache-2.0",
326 | "dependencies": {
327 | "@firebase/component": "0.6.8",
328 | "@firebase/util": "1.9.7",
329 | "idb": "7.1.1",
330 | "tslib": "^2.1.0"
331 | },
332 | "peerDependencies": {
333 | "@firebase/app": "0.x"
334 | }
335 | },
336 | "node_modules/@firebase/installations-compat": {
337 | "version": "0.2.8",
338 | "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.8.tgz",
339 | "integrity": "sha512-pI2q8JFHB7yIq/szmhzGSWXtOvtzl6tCUmyykv5C8vvfOVJUH6mP4M4iwjbK8S1JotKd/K70+JWyYlxgQ0Kpyw==",
340 | "license": "Apache-2.0",
341 | "dependencies": {
342 | "@firebase/component": "0.6.8",
343 | "@firebase/installations": "0.6.8",
344 | "@firebase/installations-types": "0.5.2",
345 | "@firebase/util": "1.9.7",
346 | "tslib": "^2.1.0"
347 | },
348 | "peerDependencies": {
349 | "@firebase/app-compat": "0.x"
350 | }
351 | },
352 | "node_modules/@firebase/installations-types": {
353 | "version": "0.5.2",
354 | "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.2.tgz",
355 | "integrity": "sha512-que84TqGRZJpJKHBlF2pkvc1YcXrtEDOVGiDjovP/a3s6W4nlbohGXEsBJo0JCeeg/UG9A+DEZVDUV9GpklUzA==",
356 | "license": "Apache-2.0",
357 | "peerDependencies": {
358 | "@firebase/app-types": "0.x"
359 | }
360 | },
361 | "node_modules/@firebase/logger": {
362 | "version": "0.4.2",
363 | "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.2.tgz",
364 | "integrity": "sha512-Q1VuA5M1Gjqrwom6I6NUU4lQXdo9IAQieXlujeHZWvRt1b7qQ0KwBaNAjgxG27jgF9/mUwsNmO8ptBCGVYhB0A==",
365 | "license": "Apache-2.0",
366 | "dependencies": {
367 | "tslib": "^2.1.0"
368 | }
369 | },
370 | "node_modules/@firebase/messaging": {
371 | "version": "0.12.10",
372 | "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.10.tgz",
373 | "integrity": "sha512-fGbxJPKpl2DIKNJGhbk4mYPcM+qE2gl91r6xPoiol/mN88F5Ym6UeRdMVZah+pijh9WxM55alTYwXuW40r1Y2Q==",
374 | "license": "Apache-2.0",
375 | "dependencies": {
376 | "@firebase/component": "0.6.8",
377 | "@firebase/installations": "0.6.8",
378 | "@firebase/messaging-interop-types": "0.2.2",
379 | "@firebase/util": "1.9.7",
380 | "idb": "7.1.1",
381 | "tslib": "^2.1.0"
382 | },
383 | "peerDependencies": {
384 | "@firebase/app": "0.x"
385 | }
386 | },
387 | "node_modules/@firebase/messaging-compat": {
388 | "version": "0.2.10",
389 | "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.10.tgz",
390 | "integrity": "sha512-FXQm7rcowkDm8kFLduHV35IRYCRo+Ng0PIp/t1+EBuEbyplaKkGjZ932pE+owf/XR+G/60ku2QRBptRGLXZydg==",
391 | "license": "Apache-2.0",
392 | "dependencies": {
393 | "@firebase/component": "0.6.8",
394 | "@firebase/messaging": "0.12.10",
395 | "@firebase/util": "1.9.7",
396 | "tslib": "^2.1.0"
397 | },
398 | "peerDependencies": {
399 | "@firebase/app-compat": "0.x"
400 | }
401 | },
402 | "node_modules/@firebase/messaging-interop-types": {
403 | "version": "0.2.2",
404 | "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.2.tgz",
405 | "integrity": "sha512-l68HXbuD2PPzDUOFb3aG+nZj5KA3INcPwlocwLZOzPp9rFM9yeuI9YLl6DQfguTX5eAGxO0doTR+rDLDvQb5tA==",
406 | "license": "Apache-2.0"
407 | },
408 | "node_modules/@firebase/performance": {
409 | "version": "0.6.8",
410 | "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.6.8.tgz",
411 | "integrity": "sha512-F+alziiIZ6Yn8FG47mxwljq+4XkgkT2uJIFRlkyViUQRLzrogaUJW6u/+6ZrePXnouKlKIwzqos3PVJraPEcCA==",
412 | "license": "Apache-2.0",
413 | "dependencies": {
414 | "@firebase/component": "0.6.8",
415 | "@firebase/installations": "0.6.8",
416 | "@firebase/logger": "0.4.2",
417 | "@firebase/util": "1.9.7",
418 | "tslib": "^2.1.0"
419 | },
420 | "peerDependencies": {
421 | "@firebase/app": "0.x"
422 | }
423 | },
424 | "node_modules/@firebase/performance-compat": {
425 | "version": "0.2.8",
426 | "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.8.tgz",
427 | "integrity": "sha512-o7TFClRVJd3VIBoY7KZQqtCeW0PC6v9uBzM6Lfw3Nc9D7hM6OonqecYvh7NwJ6R14k+xM27frLS4BcCvFHKw2A==",
428 | "license": "Apache-2.0",
429 | "dependencies": {
430 | "@firebase/component": "0.6.8",
431 | "@firebase/logger": "0.4.2",
432 | "@firebase/performance": "0.6.8",
433 | "@firebase/performance-types": "0.2.2",
434 | "@firebase/util": "1.9.7",
435 | "tslib": "^2.1.0"
436 | },
437 | "peerDependencies": {
438 | "@firebase/app-compat": "0.x"
439 | }
440 | },
441 | "node_modules/@firebase/performance-types": {
442 | "version": "0.2.2",
443 | "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.2.tgz",
444 | "integrity": "sha512-gVq0/lAClVH5STrIdKnHnCo2UcPLjJlDUoEB/tB4KM+hAeHUxWKnpT0nemUPvxZ5nbdY/pybeyMe8Cs29gEcHA==",
445 | "license": "Apache-2.0"
446 | },
447 | "node_modules/@firebase/remote-config": {
448 | "version": "0.4.8",
449 | "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.4.8.tgz",
450 | "integrity": "sha512-AMLqe6wfIRnjc6FkCWOSUjhc1fSTEf8o+cv1NolFvbiJ/tU+TqN4pI7pT+MIKQzNiq5fxLehkOx+xtAQBxPJKQ==",
451 | "license": "Apache-2.0",
452 | "dependencies": {
453 | "@firebase/component": "0.6.8",
454 | "@firebase/installations": "0.6.8",
455 | "@firebase/logger": "0.4.2",
456 | "@firebase/util": "1.9.7",
457 | "tslib": "^2.1.0"
458 | },
459 | "peerDependencies": {
460 | "@firebase/app": "0.x"
461 | }
462 | },
463 | "node_modules/@firebase/remote-config-compat": {
464 | "version": "0.2.8",
465 | "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.8.tgz",
466 | "integrity": "sha512-UxSFOp6dzFj2AHB8Bq/BYtbq5iFyizKx4Rd6WxAdaKYM8cnPMeK+l2v+Oogtjae+AeyHRI+MfL2acsfVe5cd2A==",
467 | "license": "Apache-2.0",
468 | "dependencies": {
469 | "@firebase/component": "0.6.8",
470 | "@firebase/logger": "0.4.2",
471 | "@firebase/remote-config": "0.4.8",
472 | "@firebase/remote-config-types": "0.3.2",
473 | "@firebase/util": "1.9.7",
474 | "tslib": "^2.1.0"
475 | },
476 | "peerDependencies": {
477 | "@firebase/app-compat": "0.x"
478 | }
479 | },
480 | "node_modules/@firebase/remote-config-types": {
481 | "version": "0.3.2",
482 | "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.3.2.tgz",
483 | "integrity": "sha512-0BC4+Ud7y2aPTyhXJTMTFfrGGLqdYXrUB9sJVAB8NiqJswDTc4/2qrE/yfUbnQJhbSi6ZaTTBKyG3n1nplssaA==",
484 | "license": "Apache-2.0"
485 | },
486 | "node_modules/@firebase/storage": {
487 | "version": "0.13.1",
488 | "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.13.1.tgz",
489 | "integrity": "sha512-L6AJ5tWgHSi2g/gbc/2Pbm3qxmoEg9THmPIOpRsLwuz9LPeWbhyMQeGlqxWqtZGQO/z/LMjGYadNlupQj0HNfw==",
490 | "license": "Apache-2.0",
491 | "dependencies": {
492 | "@firebase/component": "0.6.8",
493 | "@firebase/util": "1.9.7",
494 | "tslib": "^2.1.0",
495 | "undici": "6.19.7"
496 | },
497 | "peerDependencies": {
498 | "@firebase/app": "0.x"
499 | }
500 | },
501 | "node_modules/@firebase/storage-compat": {
502 | "version": "0.3.11",
503 | "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.11.tgz",
504 | "integrity": "sha512-EEa9jgm/aRVIGSD0ByYAsZ0tvEKfVwSp9uFoa/97BISGWGjSNPIWjenaDvpDZ7aL8OxaGIpwuk700aHy7/T0Ug==",
505 | "license": "Apache-2.0",
506 | "dependencies": {
507 | "@firebase/component": "0.6.8",
508 | "@firebase/storage": "0.13.1",
509 | "@firebase/storage-types": "0.8.2",
510 | "@firebase/util": "1.9.7",
511 | "tslib": "^2.1.0"
512 | },
513 | "peerDependencies": {
514 | "@firebase/app-compat": "0.x"
515 | }
516 | },
517 | "node_modules/@firebase/storage-types": {
518 | "version": "0.8.2",
519 | "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.2.tgz",
520 | "integrity": "sha512-0vWu99rdey0g53lA7IShoA2Lol1jfnPovzLDUBuon65K7uKG9G+L5uO05brD9pMw+l4HRFw23ah3GwTGpEav6g==",
521 | "license": "Apache-2.0",
522 | "peerDependencies": {
523 | "@firebase/app-types": "0.x",
524 | "@firebase/util": "1.x"
525 | }
526 | },
527 | "node_modules/@firebase/util": {
528 | "version": "1.9.7",
529 | "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.7.tgz",
530 | "integrity": "sha512-fBVNH/8bRbYjqlbIhZ+lBtdAAS4WqZumx03K06/u7fJSpz1TGjEMm1ImvKD47w+xaFKIP2ori6z8BrbakRfjJA==",
531 | "license": "Apache-2.0",
532 | "dependencies": {
533 | "tslib": "^2.1.0"
534 | }
535 | },
536 | "node_modules/@firebase/vertexai-preview": {
537 | "version": "0.0.3",
538 | "resolved": "https://registry.npmjs.org/@firebase/vertexai-preview/-/vertexai-preview-0.0.3.tgz",
539 | "integrity": "sha512-KVtUWLp+ScgiwkDKAvNkVucAyhLVQp6C6lhnVEuIg4mWhWcS3oerjAeVhZT4uNofKwWxRsOaB2Yec7DMTXlQPQ==",
540 | "license": "Apache-2.0",
541 | "dependencies": {
542 | "@firebase/app-check-interop-types": "0.3.2",
543 | "@firebase/component": "0.6.8",
544 | "@firebase/logger": "0.4.2",
545 | "@firebase/util": "1.9.7",
546 | "tslib": "^2.1.0"
547 | },
548 | "engines": {
549 | "node": ">=18.0.0"
550 | },
551 | "peerDependencies": {
552 | "@firebase/app": "0.x",
553 | "@firebase/app-types": "0.x"
554 | }
555 | },
556 | "node_modules/@firebase/webchannel-wrapper": {
557 | "version": "1.0.1",
558 | "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.1.tgz",
559 | "integrity": "sha512-jmEnr/pk0yVkA7mIlHNnxCi+wWzOFUg0WyIotgkKAb2u1J7fAeDBcVNSTjTihbAYNusCLQdW5s9IJ5qwnEufcQ==",
560 | "license": "Apache-2.0"
561 | },
562 | "node_modules/@grpc/grpc-js": {
563 | "version": "1.9.15",
564 | "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz",
565 | "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==",
566 | "license": "Apache-2.0",
567 | "dependencies": {
568 | "@grpc/proto-loader": "^0.7.8",
569 | "@types/node": ">=12.12.47"
570 | },
571 | "engines": {
572 | "node": "^8.13.0 || >=10.10.0"
573 | }
574 | },
575 | "node_modules/@grpc/proto-loader": {
576 | "version": "0.7.13",
577 | "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz",
578 | "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==",
579 | "license": "Apache-2.0",
580 | "dependencies": {
581 | "lodash.camelcase": "^4.3.0",
582 | "long": "^5.0.0",
583 | "protobufjs": "^7.2.5",
584 | "yargs": "^17.7.2"
585 | },
586 | "bin": {
587 | "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js"
588 | },
589 | "engines": {
590 | "node": ">=6"
591 | }
592 | },
593 | "node_modules/@protobufjs/aspromise": {
594 | "version": "1.1.2",
595 | "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
596 | "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
597 | "license": "BSD-3-Clause"
598 | },
599 | "node_modules/@protobufjs/base64": {
600 | "version": "1.1.2",
601 | "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
602 | "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
603 | "license": "BSD-3-Clause"
604 | },
605 | "node_modules/@protobufjs/codegen": {
606 | "version": "2.0.4",
607 | "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
608 | "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==",
609 | "license": "BSD-3-Clause"
610 | },
611 | "node_modules/@protobufjs/eventemitter": {
612 | "version": "1.1.0",
613 | "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
614 | "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==",
615 | "license": "BSD-3-Clause"
616 | },
617 | "node_modules/@protobufjs/fetch": {
618 | "version": "1.1.0",
619 | "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
620 | "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
621 | "license": "BSD-3-Clause",
622 | "dependencies": {
623 | "@protobufjs/aspromise": "^1.1.1",
624 | "@protobufjs/inquire": "^1.1.0"
625 | }
626 | },
627 | "node_modules/@protobufjs/float": {
628 | "version": "1.0.2",
629 | "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
630 | "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
631 | "license": "BSD-3-Clause"
632 | },
633 | "node_modules/@protobufjs/inquire": {
634 | "version": "1.1.0",
635 | "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
636 | "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==",
637 | "license": "BSD-3-Clause"
638 | },
639 | "node_modules/@protobufjs/path": {
640 | "version": "1.1.2",
641 | "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
642 | "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
643 | "license": "BSD-3-Clause"
644 | },
645 | "node_modules/@protobufjs/pool": {
646 | "version": "1.1.0",
647 | "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
648 | "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
649 | "license": "BSD-3-Clause"
650 | },
651 | "node_modules/@protobufjs/utf8": {
652 | "version": "1.1.0",
653 | "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
654 | "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==",
655 | "license": "BSD-3-Clause"
656 | },
657 | "node_modules/@types/node": {
658 | "version": "22.5.5",
659 | "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz",
660 | "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==",
661 | "license": "MIT",
662 | "dependencies": {
663 | "undici-types": "~6.19.2"
664 | }
665 | },
666 | "node_modules/accepts": {
667 | "version": "1.3.8",
668 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
669 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
670 | "dependencies": {
671 | "mime-types": "~2.1.34",
672 | "negotiator": "0.6.3"
673 | },
674 | "engines": {
675 | "node": ">= 0.6"
676 | }
677 | },
678 | "node_modules/ansi-regex": {
679 | "version": "5.0.1",
680 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
681 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
682 | "license": "MIT",
683 | "engines": {
684 | "node": ">=8"
685 | }
686 | },
687 | "node_modules/ansi-styles": {
688 | "version": "4.3.0",
689 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
690 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
691 | "license": "MIT",
692 | "dependencies": {
693 | "color-convert": "^2.0.1"
694 | },
695 | "engines": {
696 | "node": ">=8"
697 | },
698 | "funding": {
699 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
700 | }
701 | },
702 | "node_modules/array-flatten": {
703 | "version": "1.1.1",
704 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
705 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
706 | },
707 | "node_modules/asynckit": {
708 | "version": "0.4.0",
709 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
710 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
711 | },
712 | "node_modules/axios": {
713 | "version": "1.7.2",
714 | "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
715 | "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
716 | "dependencies": {
717 | "follow-redirects": "^1.15.6",
718 | "form-data": "^4.0.0",
719 | "proxy-from-env": "^1.1.0"
720 | }
721 | },
722 | "node_modules/body-parser": {
723 | "version": "1.20.2",
724 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
725 | "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
726 | "dependencies": {
727 | "bytes": "3.1.2",
728 | "content-type": "~1.0.5",
729 | "debug": "2.6.9",
730 | "depd": "2.0.0",
731 | "destroy": "1.2.0",
732 | "http-errors": "2.0.0",
733 | "iconv-lite": "0.4.24",
734 | "on-finished": "2.4.1",
735 | "qs": "6.11.0",
736 | "raw-body": "2.5.2",
737 | "type-is": "~1.6.18",
738 | "unpipe": "1.0.0"
739 | },
740 | "engines": {
741 | "node": ">= 0.8",
742 | "npm": "1.2.8000 || >= 1.4.16"
743 | }
744 | },
745 | "node_modules/bytes": {
746 | "version": "3.1.2",
747 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
748 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
749 | "engines": {
750 | "node": ">= 0.8"
751 | }
752 | },
753 | "node_modules/call-bind": {
754 | "version": "1.0.7",
755 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
756 | "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
757 | "dependencies": {
758 | "es-define-property": "^1.0.0",
759 | "es-errors": "^1.3.0",
760 | "function-bind": "^1.1.2",
761 | "get-intrinsic": "^1.2.4",
762 | "set-function-length": "^1.2.1"
763 | },
764 | "engines": {
765 | "node": ">= 0.4"
766 | },
767 | "funding": {
768 | "url": "https://github.com/sponsors/ljharb"
769 | }
770 | },
771 | "node_modules/cliui": {
772 | "version": "8.0.1",
773 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
774 | "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
775 | "license": "ISC",
776 | "dependencies": {
777 | "string-width": "^4.2.0",
778 | "strip-ansi": "^6.0.1",
779 | "wrap-ansi": "^7.0.0"
780 | },
781 | "engines": {
782 | "node": ">=12"
783 | }
784 | },
785 | "node_modules/color-convert": {
786 | "version": "2.0.1",
787 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
788 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
789 | "license": "MIT",
790 | "dependencies": {
791 | "color-name": "~1.1.4"
792 | },
793 | "engines": {
794 | "node": ">=7.0.0"
795 | }
796 | },
797 | "node_modules/color-name": {
798 | "version": "1.1.4",
799 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
800 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
801 | "license": "MIT"
802 | },
803 | "node_modules/combined-stream": {
804 | "version": "1.0.8",
805 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
806 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
807 | "dependencies": {
808 | "delayed-stream": "~1.0.0"
809 | },
810 | "engines": {
811 | "node": ">= 0.8"
812 | }
813 | },
814 | "node_modules/content-disposition": {
815 | "version": "0.5.4",
816 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
817 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
818 | "dependencies": {
819 | "safe-buffer": "5.2.1"
820 | },
821 | "engines": {
822 | "node": ">= 0.6"
823 | }
824 | },
825 | "node_modules/content-type": {
826 | "version": "1.0.5",
827 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
828 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
829 | "engines": {
830 | "node": ">= 0.6"
831 | }
832 | },
833 | "node_modules/cookie": {
834 | "version": "0.6.0",
835 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
836 | "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
837 | "engines": {
838 | "node": ">= 0.6"
839 | }
840 | },
841 | "node_modules/cookie-signature": {
842 | "version": "1.0.6",
843 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
844 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
845 | },
846 | "node_modules/cors": {
847 | "version": "2.8.5",
848 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
849 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
850 | "dependencies": {
851 | "object-assign": "^4",
852 | "vary": "^1"
853 | },
854 | "engines": {
855 | "node": ">= 0.10"
856 | }
857 | },
858 | "node_modules/debug": {
859 | "version": "2.6.9",
860 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
861 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
862 | "dependencies": {
863 | "ms": "2.0.0"
864 | }
865 | },
866 | "node_modules/define-data-property": {
867 | "version": "1.1.4",
868 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
869 | "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
870 | "dependencies": {
871 | "es-define-property": "^1.0.0",
872 | "es-errors": "^1.3.0",
873 | "gopd": "^1.0.1"
874 | },
875 | "engines": {
876 | "node": ">= 0.4"
877 | },
878 | "funding": {
879 | "url": "https://github.com/sponsors/ljharb"
880 | }
881 | },
882 | "node_modules/delayed-stream": {
883 | "version": "1.0.0",
884 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
885 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
886 | "engines": {
887 | "node": ">=0.4.0"
888 | }
889 | },
890 | "node_modules/depd": {
891 | "version": "2.0.0",
892 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
893 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
894 | "engines": {
895 | "node": ">= 0.8"
896 | }
897 | },
898 | "node_modules/destroy": {
899 | "version": "1.2.0",
900 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
901 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
902 | "engines": {
903 | "node": ">= 0.8",
904 | "npm": "1.2.8000 || >= 1.4.16"
905 | }
906 | },
907 | "node_modules/dotenv": {
908 | "version": "16.4.5",
909 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
910 | "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==",
911 | "license": "BSD-2-Clause",
912 | "engines": {
913 | "node": ">=12"
914 | },
915 | "funding": {
916 | "url": "https://dotenvx.com"
917 | }
918 | },
919 | "node_modules/ee-first": {
920 | "version": "1.1.1",
921 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
922 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
923 | },
924 | "node_modules/emoji-regex": {
925 | "version": "8.0.0",
926 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
927 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
928 | "license": "MIT"
929 | },
930 | "node_modules/encodeurl": {
931 | "version": "1.0.2",
932 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
933 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
934 | "engines": {
935 | "node": ">= 0.8"
936 | }
937 | },
938 | "node_modules/es-define-property": {
939 | "version": "1.0.0",
940 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
941 | "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
942 | "dependencies": {
943 | "get-intrinsic": "^1.2.4"
944 | },
945 | "engines": {
946 | "node": ">= 0.4"
947 | }
948 | },
949 | "node_modules/es-errors": {
950 | "version": "1.3.0",
951 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
952 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
953 | "engines": {
954 | "node": ">= 0.4"
955 | }
956 | },
957 | "node_modules/escalade": {
958 | "version": "3.2.0",
959 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
960 | "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
961 | "license": "MIT",
962 | "engines": {
963 | "node": ">=6"
964 | }
965 | },
966 | "node_modules/escape-html": {
967 | "version": "1.0.3",
968 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
969 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
970 | },
971 | "node_modules/etag": {
972 | "version": "1.8.1",
973 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
974 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
975 | "engines": {
976 | "node": ">= 0.6"
977 | }
978 | },
979 | "node_modules/express": {
980 | "version": "4.19.2",
981 | "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
982 | "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
983 | "dependencies": {
984 | "accepts": "~1.3.8",
985 | "array-flatten": "1.1.1",
986 | "body-parser": "1.20.2",
987 | "content-disposition": "0.5.4",
988 | "content-type": "~1.0.4",
989 | "cookie": "0.6.0",
990 | "cookie-signature": "1.0.6",
991 | "debug": "2.6.9",
992 | "depd": "2.0.0",
993 | "encodeurl": "~1.0.2",
994 | "escape-html": "~1.0.3",
995 | "etag": "~1.8.1",
996 | "finalhandler": "1.2.0",
997 | "fresh": "0.5.2",
998 | "http-errors": "2.0.0",
999 | "merge-descriptors": "1.0.1",
1000 | "methods": "~1.1.2",
1001 | "on-finished": "2.4.1",
1002 | "parseurl": "~1.3.3",
1003 | "path-to-regexp": "0.1.7",
1004 | "proxy-addr": "~2.0.7",
1005 | "qs": "6.11.0",
1006 | "range-parser": "~1.2.1",
1007 | "safe-buffer": "5.2.1",
1008 | "send": "0.18.0",
1009 | "serve-static": "1.15.0",
1010 | "setprototypeof": "1.2.0",
1011 | "statuses": "2.0.1",
1012 | "type-is": "~1.6.18",
1013 | "utils-merge": "1.0.1",
1014 | "vary": "~1.1.2"
1015 | },
1016 | "engines": {
1017 | "node": ">= 0.10.0"
1018 | }
1019 | },
1020 | "node_modules/faye-websocket": {
1021 | "version": "0.11.4",
1022 | "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz",
1023 | "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==",
1024 | "license": "Apache-2.0",
1025 | "dependencies": {
1026 | "websocket-driver": ">=0.5.1"
1027 | },
1028 | "engines": {
1029 | "node": ">=0.8.0"
1030 | }
1031 | },
1032 | "node_modules/finalhandler": {
1033 | "version": "1.2.0",
1034 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
1035 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
1036 | "dependencies": {
1037 | "debug": "2.6.9",
1038 | "encodeurl": "~1.0.2",
1039 | "escape-html": "~1.0.3",
1040 | "on-finished": "2.4.1",
1041 | "parseurl": "~1.3.3",
1042 | "statuses": "2.0.1",
1043 | "unpipe": "~1.0.0"
1044 | },
1045 | "engines": {
1046 | "node": ">= 0.8"
1047 | }
1048 | },
1049 | "node_modules/firebase": {
1050 | "version": "10.13.1",
1051 | "resolved": "https://registry.npmjs.org/firebase/-/firebase-10.13.1.tgz",
1052 | "integrity": "sha512-L5BSkmvB2dzCUMpr8i/O8WMJC3Nqj5Ld8Wj/qnak+tz2Ga+JH6/FO93xArg9IGhktCrPXVODoWp6t9ybdgmXCA==",
1053 | "license": "Apache-2.0",
1054 | "dependencies": {
1055 | "@firebase/analytics": "0.10.7",
1056 | "@firebase/analytics-compat": "0.2.13",
1057 | "@firebase/app": "0.10.10",
1058 | "@firebase/app-check": "0.8.7",
1059 | "@firebase/app-check-compat": "0.3.14",
1060 | "@firebase/app-compat": "0.2.40",
1061 | "@firebase/app-types": "0.9.2",
1062 | "@firebase/auth": "1.7.8",
1063 | "@firebase/auth-compat": "0.5.13",
1064 | "@firebase/database": "1.0.7",
1065 | "@firebase/database-compat": "1.0.7",
1066 | "@firebase/firestore": "4.7.1",
1067 | "@firebase/firestore-compat": "0.3.36",
1068 | "@firebase/functions": "0.11.7",
1069 | "@firebase/functions-compat": "0.3.13",
1070 | "@firebase/installations": "0.6.8",
1071 | "@firebase/installations-compat": "0.2.8",
1072 | "@firebase/messaging": "0.12.10",
1073 | "@firebase/messaging-compat": "0.2.10",
1074 | "@firebase/performance": "0.6.8",
1075 | "@firebase/performance-compat": "0.2.8",
1076 | "@firebase/remote-config": "0.4.8",
1077 | "@firebase/remote-config-compat": "0.2.8",
1078 | "@firebase/storage": "0.13.1",
1079 | "@firebase/storage-compat": "0.3.11",
1080 | "@firebase/util": "1.9.7",
1081 | "@firebase/vertexai-preview": "0.0.3"
1082 | }
1083 | },
1084 | "node_modules/follow-redirects": {
1085 | "version": "1.15.6",
1086 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
1087 | "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
1088 | "funding": [
1089 | {
1090 | "type": "individual",
1091 | "url": "https://github.com/sponsors/RubenVerborgh"
1092 | }
1093 | ],
1094 | "engines": {
1095 | "node": ">=4.0"
1096 | },
1097 | "peerDependenciesMeta": {
1098 | "debug": {
1099 | "optional": true
1100 | }
1101 | }
1102 | },
1103 | "node_modules/form-data": {
1104 | "version": "4.0.0",
1105 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
1106 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
1107 | "dependencies": {
1108 | "asynckit": "^0.4.0",
1109 | "combined-stream": "^1.0.8",
1110 | "mime-types": "^2.1.12"
1111 | },
1112 | "engines": {
1113 | "node": ">= 6"
1114 | }
1115 | },
1116 | "node_modules/forwarded": {
1117 | "version": "0.2.0",
1118 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
1119 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
1120 | "engines": {
1121 | "node": ">= 0.6"
1122 | }
1123 | },
1124 | "node_modules/fresh": {
1125 | "version": "0.5.2",
1126 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
1127 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
1128 | "engines": {
1129 | "node": ">= 0.6"
1130 | }
1131 | },
1132 | "node_modules/function-bind": {
1133 | "version": "1.1.2",
1134 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
1135 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
1136 | "funding": {
1137 | "url": "https://github.com/sponsors/ljharb"
1138 | }
1139 | },
1140 | "node_modules/get-caller-file": {
1141 | "version": "2.0.5",
1142 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
1143 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
1144 | "license": "ISC",
1145 | "engines": {
1146 | "node": "6.* || 8.* || >= 10.*"
1147 | }
1148 | },
1149 | "node_modules/get-intrinsic": {
1150 | "version": "1.2.4",
1151 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
1152 | "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
1153 | "dependencies": {
1154 | "es-errors": "^1.3.0",
1155 | "function-bind": "^1.1.2",
1156 | "has-proto": "^1.0.1",
1157 | "has-symbols": "^1.0.3",
1158 | "hasown": "^2.0.0"
1159 | },
1160 | "engines": {
1161 | "node": ">= 0.4"
1162 | },
1163 | "funding": {
1164 | "url": "https://github.com/sponsors/ljharb"
1165 | }
1166 | },
1167 | "node_modules/gopd": {
1168 | "version": "1.0.1",
1169 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
1170 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
1171 | "dependencies": {
1172 | "get-intrinsic": "^1.1.3"
1173 | },
1174 | "funding": {
1175 | "url": "https://github.com/sponsors/ljharb"
1176 | }
1177 | },
1178 | "node_modules/has-property-descriptors": {
1179 | "version": "1.0.2",
1180 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
1181 | "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
1182 | "dependencies": {
1183 | "es-define-property": "^1.0.0"
1184 | },
1185 | "funding": {
1186 | "url": "https://github.com/sponsors/ljharb"
1187 | }
1188 | },
1189 | "node_modules/has-proto": {
1190 | "version": "1.0.3",
1191 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
1192 | "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
1193 | "engines": {
1194 | "node": ">= 0.4"
1195 | },
1196 | "funding": {
1197 | "url": "https://github.com/sponsors/ljharb"
1198 | }
1199 | },
1200 | "node_modules/has-symbols": {
1201 | "version": "1.0.3",
1202 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
1203 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
1204 | "engines": {
1205 | "node": ">= 0.4"
1206 | },
1207 | "funding": {
1208 | "url": "https://github.com/sponsors/ljharb"
1209 | }
1210 | },
1211 | "node_modules/hasown": {
1212 | "version": "2.0.2",
1213 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
1214 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
1215 | "dependencies": {
1216 | "function-bind": "^1.1.2"
1217 | },
1218 | "engines": {
1219 | "node": ">= 0.4"
1220 | }
1221 | },
1222 | "node_modules/http-errors": {
1223 | "version": "2.0.0",
1224 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
1225 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
1226 | "dependencies": {
1227 | "depd": "2.0.0",
1228 | "inherits": "2.0.4",
1229 | "setprototypeof": "1.2.0",
1230 | "statuses": "2.0.1",
1231 | "toidentifier": "1.0.1"
1232 | },
1233 | "engines": {
1234 | "node": ">= 0.8"
1235 | }
1236 | },
1237 | "node_modules/http-parser-js": {
1238 | "version": "0.5.8",
1239 | "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz",
1240 | "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==",
1241 | "license": "MIT"
1242 | },
1243 | "node_modules/iconv-lite": {
1244 | "version": "0.4.24",
1245 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
1246 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
1247 | "dependencies": {
1248 | "safer-buffer": ">= 2.1.2 < 3"
1249 | },
1250 | "engines": {
1251 | "node": ">=0.10.0"
1252 | }
1253 | },
1254 | "node_modules/idb": {
1255 | "version": "7.1.1",
1256 | "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz",
1257 | "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==",
1258 | "license": "ISC"
1259 | },
1260 | "node_modules/inherits": {
1261 | "version": "2.0.4",
1262 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
1263 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
1264 | },
1265 | "node_modules/ipaddr.js": {
1266 | "version": "1.9.1",
1267 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
1268 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
1269 | "engines": {
1270 | "node": ">= 0.10"
1271 | }
1272 | },
1273 | "node_modules/is-fullwidth-code-point": {
1274 | "version": "3.0.0",
1275 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
1276 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
1277 | "license": "MIT",
1278 | "engines": {
1279 | "node": ">=8"
1280 | }
1281 | },
1282 | "node_modules/lodash.camelcase": {
1283 | "version": "4.3.0",
1284 | "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
1285 | "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
1286 | "license": "MIT"
1287 | },
1288 | "node_modules/long": {
1289 | "version": "5.2.3",
1290 | "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
1291 | "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==",
1292 | "license": "Apache-2.0"
1293 | },
1294 | "node_modules/media-typer": {
1295 | "version": "0.3.0",
1296 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
1297 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
1298 | "engines": {
1299 | "node": ">= 0.6"
1300 | }
1301 | },
1302 | "node_modules/merge-descriptors": {
1303 | "version": "1.0.1",
1304 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
1305 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
1306 | },
1307 | "node_modules/methods": {
1308 | "version": "1.1.2",
1309 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
1310 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
1311 | "engines": {
1312 | "node": ">= 0.6"
1313 | }
1314 | },
1315 | "node_modules/mime": {
1316 | "version": "1.6.0",
1317 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
1318 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
1319 | "bin": {
1320 | "mime": "cli.js"
1321 | },
1322 | "engines": {
1323 | "node": ">=4"
1324 | }
1325 | },
1326 | "node_modules/mime-db": {
1327 | "version": "1.52.0",
1328 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
1329 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
1330 | "engines": {
1331 | "node": ">= 0.6"
1332 | }
1333 | },
1334 | "node_modules/mime-types": {
1335 | "version": "2.1.35",
1336 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
1337 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
1338 | "dependencies": {
1339 | "mime-db": "1.52.0"
1340 | },
1341 | "engines": {
1342 | "node": ">= 0.6"
1343 | }
1344 | },
1345 | "node_modules/ms": {
1346 | "version": "2.0.0",
1347 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
1348 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
1349 | },
1350 | "node_modules/negotiator": {
1351 | "version": "0.6.3",
1352 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
1353 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
1354 | "engines": {
1355 | "node": ">= 0.6"
1356 | }
1357 | },
1358 | "node_modules/object-assign": {
1359 | "version": "4.1.1",
1360 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
1361 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
1362 | "engines": {
1363 | "node": ">=0.10.0"
1364 | }
1365 | },
1366 | "node_modules/object-inspect": {
1367 | "version": "1.13.2",
1368 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
1369 | "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==",
1370 | "engines": {
1371 | "node": ">= 0.4"
1372 | },
1373 | "funding": {
1374 | "url": "https://github.com/sponsors/ljharb"
1375 | }
1376 | },
1377 | "node_modules/on-finished": {
1378 | "version": "2.4.1",
1379 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
1380 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
1381 | "dependencies": {
1382 | "ee-first": "1.1.1"
1383 | },
1384 | "engines": {
1385 | "node": ">= 0.8"
1386 | }
1387 | },
1388 | "node_modules/parseurl": {
1389 | "version": "1.3.3",
1390 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
1391 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
1392 | "engines": {
1393 | "node": ">= 0.8"
1394 | }
1395 | },
1396 | "node_modules/path-to-regexp": {
1397 | "version": "0.1.7",
1398 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
1399 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
1400 | },
1401 | "node_modules/protobufjs": {
1402 | "version": "7.4.0",
1403 | "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz",
1404 | "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==",
1405 | "hasInstallScript": true,
1406 | "license": "BSD-3-Clause",
1407 | "dependencies": {
1408 | "@protobufjs/aspromise": "^1.1.2",
1409 | "@protobufjs/base64": "^1.1.2",
1410 | "@protobufjs/codegen": "^2.0.4",
1411 | "@protobufjs/eventemitter": "^1.1.0",
1412 | "@protobufjs/fetch": "^1.1.0",
1413 | "@protobufjs/float": "^1.0.2",
1414 | "@protobufjs/inquire": "^1.1.0",
1415 | "@protobufjs/path": "^1.1.2",
1416 | "@protobufjs/pool": "^1.1.0",
1417 | "@protobufjs/utf8": "^1.1.0",
1418 | "@types/node": ">=13.7.0",
1419 | "long": "^5.0.0"
1420 | },
1421 | "engines": {
1422 | "node": ">=12.0.0"
1423 | }
1424 | },
1425 | "node_modules/proxy-addr": {
1426 | "version": "2.0.7",
1427 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
1428 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
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/proxy-from-env": {
1438 | "version": "1.1.0",
1439 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
1440 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
1441 | },
1442 | "node_modules/qs": {
1443 | "version": "6.11.0",
1444 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
1445 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
1446 | "dependencies": {
1447 | "side-channel": "^1.0.4"
1448 | },
1449 | "engines": {
1450 | "node": ">=0.6"
1451 | },
1452 | "funding": {
1453 | "url": "https://github.com/sponsors/ljharb"
1454 | }
1455 | },
1456 | "node_modules/range-parser": {
1457 | "version": "1.2.1",
1458 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
1459 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
1460 | "engines": {
1461 | "node": ">= 0.6"
1462 | }
1463 | },
1464 | "node_modules/raw-body": {
1465 | "version": "2.5.2",
1466 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
1467 | "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
1468 | "dependencies": {
1469 | "bytes": "3.1.2",
1470 | "http-errors": "2.0.0",
1471 | "iconv-lite": "0.4.24",
1472 | "unpipe": "1.0.0"
1473 | },
1474 | "engines": {
1475 | "node": ">= 0.8"
1476 | }
1477 | },
1478 | "node_modules/require-directory": {
1479 | "version": "2.1.1",
1480 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
1481 | "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
1482 | "license": "MIT",
1483 | "engines": {
1484 | "node": ">=0.10.0"
1485 | }
1486 | },
1487 | "node_modules/safe-buffer": {
1488 | "version": "5.2.1",
1489 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
1490 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
1491 | "funding": [
1492 | {
1493 | "type": "github",
1494 | "url": "https://github.com/sponsors/feross"
1495 | },
1496 | {
1497 | "type": "patreon",
1498 | "url": "https://www.patreon.com/feross"
1499 | },
1500 | {
1501 | "type": "consulting",
1502 | "url": "https://feross.org/support"
1503 | }
1504 | ]
1505 | },
1506 | "node_modules/safer-buffer": {
1507 | "version": "2.1.2",
1508 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1509 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
1510 | },
1511 | "node_modules/send": {
1512 | "version": "0.18.0",
1513 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
1514 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
1515 | "dependencies": {
1516 | "debug": "2.6.9",
1517 | "depd": "2.0.0",
1518 | "destroy": "1.2.0",
1519 | "encodeurl": "~1.0.2",
1520 | "escape-html": "~1.0.3",
1521 | "etag": "~1.8.1",
1522 | "fresh": "0.5.2",
1523 | "http-errors": "2.0.0",
1524 | "mime": "1.6.0",
1525 | "ms": "2.1.3",
1526 | "on-finished": "2.4.1",
1527 | "range-parser": "~1.2.1",
1528 | "statuses": "2.0.1"
1529 | },
1530 | "engines": {
1531 | "node": ">= 0.8.0"
1532 | }
1533 | },
1534 | "node_modules/send/node_modules/ms": {
1535 | "version": "2.1.3",
1536 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1537 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
1538 | },
1539 | "node_modules/serve-static": {
1540 | "version": "1.15.0",
1541 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
1542 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
1543 | "dependencies": {
1544 | "encodeurl": "~1.0.2",
1545 | "escape-html": "~1.0.3",
1546 | "parseurl": "~1.3.3",
1547 | "send": "0.18.0"
1548 | },
1549 | "engines": {
1550 | "node": ">= 0.8.0"
1551 | }
1552 | },
1553 | "node_modules/set-function-length": {
1554 | "version": "1.2.2",
1555 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
1556 | "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
1557 | "dependencies": {
1558 | "define-data-property": "^1.1.4",
1559 | "es-errors": "^1.3.0",
1560 | "function-bind": "^1.1.2",
1561 | "get-intrinsic": "^1.2.4",
1562 | "gopd": "^1.0.1",
1563 | "has-property-descriptors": "^1.0.2"
1564 | },
1565 | "engines": {
1566 | "node": ">= 0.4"
1567 | }
1568 | },
1569 | "node_modules/setprototypeof": {
1570 | "version": "1.2.0",
1571 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
1572 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
1573 | },
1574 | "node_modules/side-channel": {
1575 | "version": "1.0.6",
1576 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
1577 | "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
1578 | "dependencies": {
1579 | "call-bind": "^1.0.7",
1580 | "es-errors": "^1.3.0",
1581 | "get-intrinsic": "^1.2.4",
1582 | "object-inspect": "^1.13.1"
1583 | },
1584 | "engines": {
1585 | "node": ">= 0.4"
1586 | },
1587 | "funding": {
1588 | "url": "https://github.com/sponsors/ljharb"
1589 | }
1590 | },
1591 | "node_modules/statuses": {
1592 | "version": "2.0.1",
1593 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
1594 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
1595 | "engines": {
1596 | "node": ">= 0.8"
1597 | }
1598 | },
1599 | "node_modules/string-width": {
1600 | "version": "4.2.3",
1601 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
1602 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
1603 | "license": "MIT",
1604 | "dependencies": {
1605 | "emoji-regex": "^8.0.0",
1606 | "is-fullwidth-code-point": "^3.0.0",
1607 | "strip-ansi": "^6.0.1"
1608 | },
1609 | "engines": {
1610 | "node": ">=8"
1611 | }
1612 | },
1613 | "node_modules/strip-ansi": {
1614 | "version": "6.0.1",
1615 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
1616 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
1617 | "license": "MIT",
1618 | "dependencies": {
1619 | "ansi-regex": "^5.0.1"
1620 | },
1621 | "engines": {
1622 | "node": ">=8"
1623 | }
1624 | },
1625 | "node_modules/toidentifier": {
1626 | "version": "1.0.1",
1627 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
1628 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
1629 | "engines": {
1630 | "node": ">=0.6"
1631 | }
1632 | },
1633 | "node_modules/tslib": {
1634 | "version": "2.7.0",
1635 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
1636 | "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
1637 | "license": "0BSD"
1638 | },
1639 | "node_modules/type-is": {
1640 | "version": "1.6.18",
1641 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
1642 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
1643 | "dependencies": {
1644 | "media-typer": "0.3.0",
1645 | "mime-types": "~2.1.24"
1646 | },
1647 | "engines": {
1648 | "node": ">= 0.6"
1649 | }
1650 | },
1651 | "node_modules/undici": {
1652 | "version": "6.19.7",
1653 | "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.7.tgz",
1654 | "integrity": "sha512-HR3W/bMGPSr90i8AAp2C4DM3wChFdJPLrWYpIS++LxS8K+W535qftjt+4MyjNYHeWabMj1nvtmLIi7l++iq91A==",
1655 | "license": "MIT",
1656 | "engines": {
1657 | "node": ">=18.17"
1658 | }
1659 | },
1660 | "node_modules/undici-types": {
1661 | "version": "6.19.8",
1662 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
1663 | "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
1664 | "license": "MIT"
1665 | },
1666 | "node_modules/unpipe": {
1667 | "version": "1.0.0",
1668 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
1669 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
1670 | "engines": {
1671 | "node": ">= 0.8"
1672 | }
1673 | },
1674 | "node_modules/utils-merge": {
1675 | "version": "1.0.1",
1676 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
1677 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
1678 | "engines": {
1679 | "node": ">= 0.4.0"
1680 | }
1681 | },
1682 | "node_modules/vary": {
1683 | "version": "1.1.2",
1684 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
1685 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
1686 | "engines": {
1687 | "node": ">= 0.8"
1688 | }
1689 | },
1690 | "node_modules/websocket-driver": {
1691 | "version": "0.7.4",
1692 | "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
1693 | "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
1694 | "license": "Apache-2.0",
1695 | "dependencies": {
1696 | "http-parser-js": ">=0.5.1",
1697 | "safe-buffer": ">=5.1.0",
1698 | "websocket-extensions": ">=0.1.1"
1699 | },
1700 | "engines": {
1701 | "node": ">=0.8.0"
1702 | }
1703 | },
1704 | "node_modules/websocket-extensions": {
1705 | "version": "0.1.4",
1706 | "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
1707 | "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
1708 | "license": "Apache-2.0",
1709 | "engines": {
1710 | "node": ">=0.8.0"
1711 | }
1712 | },
1713 | "node_modules/wrap-ansi": {
1714 | "version": "7.0.0",
1715 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
1716 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
1717 | "license": "MIT",
1718 | "dependencies": {
1719 | "ansi-styles": "^4.0.0",
1720 | "string-width": "^4.1.0",
1721 | "strip-ansi": "^6.0.0"
1722 | },
1723 | "engines": {
1724 | "node": ">=10"
1725 | },
1726 | "funding": {
1727 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
1728 | }
1729 | },
1730 | "node_modules/y18n": {
1731 | "version": "5.0.8",
1732 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
1733 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
1734 | "license": "ISC",
1735 | "engines": {
1736 | "node": ">=10"
1737 | }
1738 | },
1739 | "node_modules/yargs": {
1740 | "version": "17.7.2",
1741 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
1742 | "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
1743 | "license": "MIT",
1744 | "dependencies": {
1745 | "cliui": "^8.0.1",
1746 | "escalade": "^3.1.1",
1747 | "get-caller-file": "^2.0.5",
1748 | "require-directory": "^2.1.1",
1749 | "string-width": "^4.2.3",
1750 | "y18n": "^5.0.5",
1751 | "yargs-parser": "^21.1.1"
1752 | },
1753 | "engines": {
1754 | "node": ">=12"
1755 | }
1756 | },
1757 | "node_modules/yargs-parser": {
1758 | "version": "21.1.1",
1759 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
1760 | "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
1761 | "license": "ISC",
1762 | "engines": {
1763 | "node": ">=12"
1764 | }
1765 | }
1766 | }
1767 | }
1768 |
--------------------------------------------------------------------------------
/server/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "scripts": {
3 | "start": "node server.js"
4 | },
5 | "dependencies": {
6 | "axios": "^1.7.2",
7 | "cors": "^2.8.5",
8 | "dotenv": "^16.4.5",
9 | "express": "^4.19.2",
10 | "firebase": "^10.13.1"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/server/server.js:
--------------------------------------------------------------------------------
1 | require('dotenv').config();
2 | const express = require("express");
3 | const cors = require("cors");
4 | const path = require("path");
5 | const axios = require("axios");
6 |
7 | const app = express();
8 |
9 | // CORS configuration
10 | app.use(cors({
11 | origin: 'https://hunar-taupe.vercel.app', // Allow requests from any origin
12 | methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
13 | optionsSuccessStatus: 204,
14 | }));
15 |
16 | // Serve static files
17 | app.use(express.static('dist'));
18 |
19 | // API endpoint
20 | app.get("/api/news", (req, res) => {
21 | const apiKey = process.env.NEWS_API_KEY;
22 | axios.get(`https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=${apiKey}`)
23 | .then((response) => {
24 | res.send(response.data);
25 | })
26 | .catch(error => {
27 | console.error('Error fetching news from NewsAPI', error);
28 | res.status(500).send('Error fetching news');
29 | });
30 | });
31 |
32 | // Start server
33 | const port = process.env.PORT || 8080;
34 | app.listen(port, () => {
35 | console.log(`Listening on port ${port}`);
36 | });
37 |
--------------------------------------------------------------------------------
/server/vercel.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 2,
3 | "builds": [
4 | { "src": "server.js", "use": "@vercel/node" }
5 | ],
6 | "routes": [
7 | { "src": "/api/(.*)", "dest": "server.js" }
8 | ],
9 | "headers": [
10 | {
11 | "source": "/api/(.*)",
12 | "headers": [
13 | { "key": "Access-Control-Allow-Origin", "value": "*" },
14 | { "key": "Access-Control-Allow-Methods", "value": "GET,HEAD,PUT,PATCH,POST,DELETE" },
15 | { "key": "Access-Control-Allow-Headers", "value": "Content-Type" }
16 | ]
17 | }
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------