├── .gitignore ├── api ├── .gitignore ├── package.json ├── models │ ├── user.js │ └── order.js ├── index.js └── yarn.lock ├── .expo ├── devices.json ├── settings.json ├── packager-info.json ├── web │ └── cache │ │ └── production │ │ └── images │ │ ├── splash-android │ │ └── splash-android-bc25a616b4e31cf7300cd97b9cbf8894e855e6373aa797d0badd7e211111c5e5-contain │ │ │ └── icon_undefined.png │ │ ├── android-standard-circle │ │ └── android-standard-circle-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-#ffffff │ │ │ ├── icon_108.png │ │ │ ├── icon_162.png │ │ │ ├── icon_216.png │ │ │ ├── icon_324.png │ │ │ └── icon_432.png │ │ ├── android-standard-square │ │ └── android-standard-square-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-#ffffff │ │ │ ├── icon_108.png │ │ │ ├── icon_162.png │ │ │ ├── icon_216.png │ │ │ ├── icon_324.png │ │ │ └── icon_432.png │ │ └── android-adaptive-foreground │ │ └── android-adaptive-foreground-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-transparent │ │ ├── icon_108.png │ │ ├── icon_162.png │ │ ├── icon_216.png │ │ ├── icon_324.png │ │ └── icon_432.png └── README.md ├── assets ├── icon.png ├── splash.png ├── favicon.png ├── adaptive-icon.png └── sparkle.json ├── babel.config.js ├── store.js ├── UserContext.js ├── App.js ├── app.json ├── package.json ├── screens ├── OrderScreen.js ├── ProfileScreen.js ├── LoginScreen.js ├── AddAddressScreen.js ├── AddressScreen.js ├── RegisterScreen.js ├── ProductInfoScreen.js ├── CartScreen.js ├── ConfirmationScreen.js └── HomeScreen.js ├── redux └── CartReducer.js ├── README.md ├── components └── ProductItem.js └── navigation └── StackNavigator.js /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | node_modules/ -------------------------------------------------------------------------------- /api/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | node_modules/ -------------------------------------------------------------------------------- /.expo/devices.json: -------------------------------------------------------------------------------- 1 | { 2 | "devices": [] 3 | } 4 | -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jigneshgit935/Ecommerce-Application-React-Native/HEAD/assets/icon.png -------------------------------------------------------------------------------- /assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jigneshgit935/Ecommerce-Application-React-Native/HEAD/assets/splash.png -------------------------------------------------------------------------------- /assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jigneshgit935/Ecommerce-Application-React-Native/HEAD/assets/favicon.png -------------------------------------------------------------------------------- /assets/adaptive-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jigneshgit935/Ecommerce-Application-React-Native/HEAD/assets/adaptive-icon.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /store.js: -------------------------------------------------------------------------------- 1 | import { configureStore } from '@reduxjs/toolkit'; 2 | import CartReducer from './redux/CartReducer'; 3 | 4 | export default configureStore({ 5 | reducer: { 6 | cart: CartReducer, 7 | }, 8 | }); 9 | -------------------------------------------------------------------------------- /.expo/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "hostType": "lan", 3 | "lanType": "ip", 4 | "dev": true, 5 | "minify": false, 6 | "urlRandomness": null, 7 | "https": false, 8 | "scheme": null, 9 | "devClient": false 10 | } 11 | -------------------------------------------------------------------------------- /.expo/packager-info.json: -------------------------------------------------------------------------------- 1 | { 2 | "expoServerPort": null, 3 | "packagerPort": 19000, 4 | "packagerPid": null, 5 | "expoServerNgrokUrl": null, 6 | "packagerNgrokUrl": null, 7 | "ngrokPid": null, 8 | "webpackServerPort": null 9 | } 10 | -------------------------------------------------------------------------------- /.expo/web/cache/production/images/splash-android/splash-android-bc25a616b4e31cf7300cd97b9cbf8894e855e6373aa797d0badd7e211111c5e5-contain/icon_undefined.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jigneshgit935/Ecommerce-Application-React-Native/HEAD/.expo/web/cache/production/images/splash-android/splash-android-bc25a616b4e31cf7300cd97b9cbf8894e855e6373aa797d0badd7e211111c5e5-contain/icon_undefined.png -------------------------------------------------------------------------------- /UserContext.js: -------------------------------------------------------------------------------- 1 | import { createContext, useState } from 'react'; 2 | 3 | const UserType = createContext(); 4 | 5 | const UserContext = ({ children }) => { 6 | const [userId, setUserId] = useState(''); 7 | 8 | return ( 9 | 10 | {children} 11 | 12 | ); 13 | }; 14 | 15 | export { UserType, UserContext }; 16 | -------------------------------------------------------------------------------- /.expo/web/cache/production/images/android-standard-circle/android-standard-circle-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-#ffffff/icon_108.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jigneshgit935/Ecommerce-Application-React-Native/HEAD/.expo/web/cache/production/images/android-standard-circle/android-standard-circle-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-#ffffff/icon_108.png -------------------------------------------------------------------------------- /.expo/web/cache/production/images/android-standard-circle/android-standard-circle-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-#ffffff/icon_162.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jigneshgit935/Ecommerce-Application-React-Native/HEAD/.expo/web/cache/production/images/android-standard-circle/android-standard-circle-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-#ffffff/icon_162.png -------------------------------------------------------------------------------- /.expo/web/cache/production/images/android-standard-circle/android-standard-circle-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-#ffffff/icon_216.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jigneshgit935/Ecommerce-Application-React-Native/HEAD/.expo/web/cache/production/images/android-standard-circle/android-standard-circle-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-#ffffff/icon_216.png -------------------------------------------------------------------------------- /.expo/web/cache/production/images/android-standard-circle/android-standard-circle-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-#ffffff/icon_324.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jigneshgit935/Ecommerce-Application-React-Native/HEAD/.expo/web/cache/production/images/android-standard-circle/android-standard-circle-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-#ffffff/icon_324.png -------------------------------------------------------------------------------- /.expo/web/cache/production/images/android-standard-circle/android-standard-circle-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-#ffffff/icon_432.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jigneshgit935/Ecommerce-Application-React-Native/HEAD/.expo/web/cache/production/images/android-standard-circle/android-standard-circle-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-#ffffff/icon_432.png -------------------------------------------------------------------------------- /.expo/web/cache/production/images/android-standard-square/android-standard-square-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-#ffffff/icon_108.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jigneshgit935/Ecommerce-Application-React-Native/HEAD/.expo/web/cache/production/images/android-standard-square/android-standard-square-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-#ffffff/icon_108.png -------------------------------------------------------------------------------- /.expo/web/cache/production/images/android-standard-square/android-standard-square-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-#ffffff/icon_162.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jigneshgit935/Ecommerce-Application-React-Native/HEAD/.expo/web/cache/production/images/android-standard-square/android-standard-square-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-#ffffff/icon_162.png -------------------------------------------------------------------------------- /.expo/web/cache/production/images/android-standard-square/android-standard-square-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-#ffffff/icon_216.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jigneshgit935/Ecommerce-Application-React-Native/HEAD/.expo/web/cache/production/images/android-standard-square/android-standard-square-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-#ffffff/icon_216.png -------------------------------------------------------------------------------- /.expo/web/cache/production/images/android-standard-square/android-standard-square-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-#ffffff/icon_324.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jigneshgit935/Ecommerce-Application-React-Native/HEAD/.expo/web/cache/production/images/android-standard-square/android-standard-square-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-#ffffff/icon_324.png -------------------------------------------------------------------------------- /.expo/web/cache/production/images/android-standard-square/android-standard-square-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-#ffffff/icon_432.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jigneshgit935/Ecommerce-Application-React-Native/HEAD/.expo/web/cache/production/images/android-standard-square/android-standard-square-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-#ffffff/icon_432.png -------------------------------------------------------------------------------- /.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-transparent/icon_108.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jigneshgit935/Ecommerce-Application-React-Native/HEAD/.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-transparent/icon_108.png -------------------------------------------------------------------------------- /.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-transparent/icon_162.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jigneshgit935/Ecommerce-Application-React-Native/HEAD/.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-transparent/icon_162.png -------------------------------------------------------------------------------- /.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-transparent/icon_216.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jigneshgit935/Ecommerce-Application-React-Native/HEAD/.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-transparent/icon_216.png -------------------------------------------------------------------------------- /.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-transparent/icon_324.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jigneshgit935/Ecommerce-Application-React-Native/HEAD/.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-transparent/icon_324.png -------------------------------------------------------------------------------- /.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-transparent/icon_432.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jigneshgit935/Ecommerce-Application-React-Native/HEAD/.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-5f4c0a732b6325bf4071d9124d2ae67e037cb24fcc9c482ef82bea742109a3b8-cover-transparent/icon_432.png -------------------------------------------------------------------------------- /api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "api", 3 | "version": "1.0.0", 4 | "description": "backend", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "nodemon index.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "body-parser": "^1.20.2", 14 | "cors": "^2.8.5", 15 | "dotenv": "^16.3.1", 16 | "express": "^4.18.2", 17 | "jsonwebtoken": "^9.0.1", 18 | "mongoose": "^7.4.5", 19 | "nodemailer": "^6.9.4", 20 | "nodemon": "^3.0.1" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /App.js: -------------------------------------------------------------------------------- 1 | import { StatusBar } from 'expo-status-bar'; 2 | import { StyleSheet, Text, View } from 'react-native'; 3 | import StackNavigator from './navigation/StackNavigator'; 4 | import { Provider } from 'react-redux'; 5 | import store from './store'; 6 | import { ModalPortal } from 'react-native-modals'; 7 | import { UserContext } from './UserContext'; 8 | 9 | export default function App() { 10 | return ( 11 | <> 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | ); 20 | } 21 | 22 | const styles = StyleSheet.create({ 23 | container: { 24 | flex: 1, 25 | backgroundColor: '#fff', 26 | alignItems: 'center', 27 | justifyContent: 'center', 28 | }, 29 | }); 30 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "ecommerce-project", 4 | "slug": "ecommerce-project", 5 | "version": "1.0.0", 6 | "orientation": "portrait", 7 | "icon": "./assets/icon.png", 8 | "userInterfaceStyle": "light", 9 | "splash": { 10 | "image": "./assets/splash.png", 11 | "resizeMode": "contain", 12 | "backgroundColor": "#ffffff" 13 | }, 14 | "assetBundlePatterns": [ 15 | "**/*" 16 | ], 17 | "ios": { 18 | "supportsTablet": true 19 | }, 20 | "android": { 21 | "adaptiveIcon": { 22 | "foregroundImage": "./assets/adaptive-icon.png", 23 | "backgroundColor": "#ffffff" 24 | }, 25 | "package": "host.exp.exponent" 26 | }, 27 | "web": { 28 | "favicon": "./assets/favicon.png" 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /.expo/README.md: -------------------------------------------------------------------------------- 1 | > Why do I have a folder named ".expo" in my project? 2 | 3 | The ".expo" folder is created when an Expo project is started using "expo start" command. 4 | 5 | > What do the files contain? 6 | 7 | - "devices.json": contains information about devices that have recently opened this project. This is used to populate the "Development sessions" list in your development builds. 8 | - "packager-info.json": contains port numbers and process PIDs that are used to serve the application to the mobile device/simulator. 9 | - "settings.json": contains the server configuration that is used to serve the application manifest. 10 | 11 | > Should I commit the ".expo" folder? 12 | 13 | No, you should not share the ".expo" folder. It does not contain any information that is relevant for other developers working on the project, it is specific to your machine. 14 | 15 | Upon project creation, the ".expo" folder is already added to your ".gitignore" file. 16 | -------------------------------------------------------------------------------- /api/models/user.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const userSchema = new mongoose.Schema({ 4 | name: { 5 | type: String, 6 | required: true, 7 | }, 8 | email: { 9 | type: String, 10 | required: true, 11 | unique: true, 12 | }, 13 | password: { 14 | type: String, 15 | required: true, 16 | }, 17 | verified: { 18 | type: Boolean, 19 | default: false, 20 | }, 21 | verificationToken: String, 22 | addresses: [ 23 | { 24 | name: String, 25 | mobileNo: String, 26 | houseNo: String, 27 | street: String, 28 | landmark: String, 29 | city: String, 30 | country: String, 31 | postalCode: String, 32 | }, 33 | ], 34 | orders: [ 35 | { 36 | type: mongoose.Schema.Types.ObjectId, 37 | ref: 'Order', 38 | }, 39 | ], 40 | createdAt: { 41 | type: Date, 42 | default: Date.now, 43 | }, 44 | }); 45 | 46 | const User = mongoose.model('User', userSchema); 47 | 48 | module.exports = User; 49 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ecommerce-project", 3 | "version": "1.0.0", 4 | "main": "node_modules/expo/AppEntry.js", 5 | "scripts": { 6 | "start": "expo start", 7 | "android": "expo run:android", 8 | "ios": "expo run:ios", 9 | "web": "expo start --web" 10 | }, 11 | "dependencies": { 12 | "@react-native-async-storage/async-storage": "1.18.2", 13 | "@react-navigation/bottom-tabs": "^6.5.8", 14 | "@react-navigation/native": "^6.1.7", 15 | "@react-navigation/native-stack": "^6.9.13", 16 | "@reduxjs/toolkit": "^1.9.5", 17 | "axios": "^1.5.0", 18 | "expo": "~49.0.8", 19 | "expo-status-bar": "~1.6.0", 20 | "jwt-decode": "^3.1.2", 21 | "lottie-react-native": "^6.2.0", 22 | "react": "18.2.0", 23 | "react-native": "0.72.4", 24 | "react-native-dropdown-picker": "^5.4.6", 25 | "react-native-image-slider-box": "^2.0.7", 26 | "react-native-modals": "^0.22.3", 27 | "react-native-razorpay": "^2.3.0", 28 | "react-native-safe-area-context": "4.6.3", 29 | "react-native-screens": "~3.22.0", 30 | "react-redux": "^8.1.2", 31 | "expo-splash-screen": "~0.20.5" 32 | }, 33 | "devDependencies": { 34 | "@babel/core": "^7.20.0" 35 | }, 36 | "private": true 37 | } 38 | -------------------------------------------------------------------------------- /api/models/order.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const orderSchema = new mongoose.Schema({ 4 | user: { 5 | type: mongoose.Schema.Types.ObjectId, 6 | ref: 'User', 7 | require: true, 8 | }, 9 | products: [ 10 | { 11 | name: { 12 | type: String, 13 | required: true, 14 | }, 15 | quantity: { 16 | type: Number, 17 | required: true, 18 | }, 19 | price: { 20 | type: Number, 21 | required: true, 22 | }, 23 | image: { 24 | type: String, 25 | required: true, 26 | }, 27 | }, 28 | ], 29 | totalPrice: { 30 | type: Number, 31 | required: true, 32 | }, 33 | shippingAddress: { 34 | name: { 35 | type: String, 36 | required: true, 37 | }, 38 | mobileNo: { 39 | type: String, 40 | required: true, 41 | }, 42 | houseNo: { 43 | type: String, 44 | required: true, 45 | }, 46 | street: { 47 | type: String, 48 | required: true, 49 | }, 50 | landmark: { 51 | type: String, 52 | required: true, 53 | }, 54 | postalCode: { 55 | type: String, 56 | required: true, 57 | }, 58 | }, 59 | paymentMethod: { 60 | type: String, 61 | required: true, 62 | }, 63 | createdAt: { 64 | type: Date, 65 | default: Date.now, 66 | }, 67 | }); 68 | 69 | const Order = mongoose.model('Order', orderSchema); 70 | 71 | module.exports = Order; 72 | -------------------------------------------------------------------------------- /screens/OrderScreen.js: -------------------------------------------------------------------------------- 1 | import { StyleSheet, Text } from 'react-native'; 2 | import React, { useEffect } from 'react'; 3 | import { useNavigation } from '@react-navigation/native'; 4 | import { SafeAreaView } from 'react-native-safe-area-context'; 5 | import LottieView from 'lottie-react-native'; 6 | 7 | const OrderScreen = () => { 8 | const navigation = useNavigation(); 9 | useEffect(() => { 10 | setTimeout(() => { 11 | navigation.replace('Main'); 12 | }, 1300); 13 | }, []); 14 | return ( 15 | 16 | 30 | 38 | Your Order Has been Recieved 39 | 40 | 53 | 54 | ); 55 | }; 56 | 57 | export default OrderScreen; 58 | 59 | const styles = StyleSheet.create({}); 60 | -------------------------------------------------------------------------------- /redux/CartReducer.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from '@reduxjs/toolkit'; 2 | 3 | export const CartSlice = createSlice({ 4 | name: 'cart', 5 | initialState: { 6 | cart: [], 7 | }, 8 | reducers: { 9 | addToCart: (state, action) => { 10 | const itemPresent = state.cart.find( 11 | (item) => item.id === action.payload.id 12 | ); 13 | if (itemPresent) { 14 | itemPresent.quantity++; 15 | } else { 16 | state.cart.push({ ...action.payload, quantity: 1 }); 17 | } 18 | }, 19 | 20 | removeFromCart: (state, action) => { 21 | const removeItem = state.cart.filter( 22 | (item) => item.id !== action.payload.id 23 | ); 24 | state.cart = removeItem; 25 | }, 26 | incrementQuantity: (state, action) => { 27 | const itemPresent = state.cart.find( 28 | (item) => item.id === action.payload.id 29 | ); 30 | itemPresent.quantity++; 31 | }, 32 | decrementQuantity: (state, action) => { 33 | const itemPresent = state.cart.find( 34 | (item) => item.id === action.payload.id 35 | ); 36 | if (itemPresent.quantity === 1) { 37 | itemPresent.quantity = 0; 38 | const removeItem = state.cart.filter( 39 | (item) => item.id !== action.payload.id 40 | ); 41 | state.cart = removeItem; 42 | } else { 43 | itemPresent.quantity--; 44 | } 45 | }, 46 | 47 | cleanCart: (state) => { 48 | state.cart = []; 49 | }, 50 | }, 51 | }); 52 | 53 | export const { 54 | addToCart, 55 | removeFromCart, 56 | incrementQuantity, 57 | decrementQuantity, 58 | cleanCart, 59 | } = CartSlice.actions; 60 | 61 | export default CartSlice.reducer; 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ecommerce-Application-React-Native 2 | E-commerce-Shopping-App using React-native. For backend we have used NodeJS and for Database we have used MongoDB. For State Management we worked on Redux/Toolkit for add to card, delete and for many more state to handle.It is a FullStack React-Native Mobile Application 3 | 4 | 1.Register Screen 5 | 6 | https://github.com/jigneshgit935/Ecommerce-Application-React-Native/assets/102901231/753265f9-4316-4be9-a46d-d8d7e211743f 7 | 8 | 2.Login Screen 9 | 10 | https://github.com/jigneshgit935/Ecommerce-Application-React-Native/assets/102901231/c6bd2c2a-73fa-452d-b796-6b9ecff458a8 11 | 12 | 3.Home Screen 13 | 14 | https://github.com/jigneshgit935/Ecommerce-Application-React-Native/assets/102901231/d2ff4b92-3b69-4b60-bd54-7c66d7feb065 15 | 16 | 4.Filter Products (Men's Clothing, Jewelery, Electronics, Women's Clothing) 17 | 18 | https://github.com/jigneshgit935/Ecommerce-Application-React-Native/assets/102901231/c51b281a-fb63-4e33-ae2c-f92c3a32140c 19 | 20 | 4.Add to Cart Functionality 21 | 22 | https://github.com/jigneshgit935/Ecommerce-Application-React-Native/assets/102901231/f368cf0a-7e1f-43da-ae07-e109377ddd6c 23 | 24 | 5.Cart Screen 25 | 26 | https://github.com/jigneshgit935/Ecommerce-Application-React-Native/assets/102901231/5b29bf6f-f985-4470-a207-ef171186e093 27 | 28 | 6.Add Address for Shopping 29 | 30 | https://github.com/jigneshgit935/Ecommerce-Application-React-Native/assets/102901231/39226bbd-8f40-4ab6-aa77-9007a5c9e843 31 | 32 | 7.Proceed to buy (4 steps 1.select address, 2. prime membership, 3.payment method, 4.place order) 33 | 34 | https://github.com/jigneshgit935/Ecommerce-Application-React-Native/assets/102901231/0dc4c19a-b044-46c8-8344-a7db71fbb06a 35 | 36 | 8.Profile Screen and Logout functionality (Your Orders) 37 | 38 | https://github.com/jigneshgit935/Ecommerce-Application-React-Native/assets/102901231/ce18560d-bfeb-4773-8ab7-c7924778885d 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /components/ProductItem.js: -------------------------------------------------------------------------------- 1 | import { Image, Pressable, StyleSheet, Text, View } from 'react-native'; 2 | import React, { useState } from 'react'; 3 | import { useDispatch } from 'react-redux'; 4 | import { addToCart } from '../redux/CartReducer'; 5 | 6 | const ProductItem = ({ item }) => { 7 | const [addedToCart, setAddedToCart] = useState(false); 8 | 9 | const dispatch = useDispatch(); 10 | const addItemToCart = (item) => { 11 | setAddedToCart(true); 12 | dispatch(addToCart(item)); 13 | setTimeout(() => { 14 | setAddedToCart(false); 15 | }, 60000); 16 | }; 17 | 18 | return ( 19 | 20 | 24 | 25 | {item?.title} 26 | 27 | 35 | ₹{item?.price} 36 | 37 | {item?.rating?.rate} ratings 38 | 39 | 40 | 41 | addItemToCart(item)} 43 | style={{ 44 | backgroundColor: '#FFC72C', 45 | padding: 10, 46 | borderRadius: 20, 47 | justifyContent: 'center', 48 | alignItems: 'center', 49 | marginHorizontal: 10, 50 | marginTop: 10, 51 | }} 52 | > 53 | 54 | {addedToCart ? ( 55 | 56 | Added to Cart 57 | 58 | ) : ( 59 | 60 | Add to Cart 61 | 62 | )} 63 | 64 | 65 | 66 | ); 67 | }; 68 | 69 | export default ProductItem; 70 | 71 | const styles = StyleSheet.create({}); 72 | -------------------------------------------------------------------------------- /navigation/StackNavigator.js: -------------------------------------------------------------------------------- 1 | import { StyleSheet, Text, View } from 'react-native'; 2 | import React from 'react'; 3 | import { NavigationContainer } from '@react-navigation/native'; 4 | import { createNativeStackNavigator } from '@react-navigation/native-stack'; 5 | import LoginScreen from '../screens/LoginScreen'; 6 | import RegisterScreen from '../screens/RegisterScreen'; 7 | import HomeScreen from '../screens/HomeScreen'; 8 | import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; 9 | import { Entypo } from '@expo/vector-icons'; 10 | import { AntDesign } from '@expo/vector-icons'; 11 | import { Ionicons } from '@expo/vector-icons'; 12 | import ProductInfoScreen from '../screens/ProductInfoScreen'; 13 | import AddAddressScreen from '../screens/AddAddressScreen'; 14 | import AddressScreen from '../screens/AddressScreen'; 15 | import CartScreen from '../screens/CartScreen'; 16 | import ProfileScreen from '../screens/ProfileScreen'; 17 | import ConfirmationScreen from '../screens/ConfirmationScreen'; 18 | import OrderScreen from '../screens/OrderScreen'; 19 | 20 | const StackNavigator = () => { 21 | const Stack = createNativeStackNavigator(); 22 | const Tab = createBottomTabNavigator(); 23 | 24 | function BottomTabs() { 25 | return ( 26 | 27 | 35 | focused ? ( 36 | 37 | ) : ( 38 | 39 | ), 40 | }} 41 | /> 42 | 49 | focused ? ( 50 | 51 | ) : ( 52 | 53 | ), 54 | }} 55 | /> 56 | 64 | focused ? ( 65 | 66 | ) : ( 67 | 68 | ), 69 | }} 70 | /> 71 | 72 | ); 73 | } 74 | return ( 75 | 76 | 77 | 82 | 87 | 92 | 97 | 102 | 107 | 112 | 117 | 118 | 119 | ); 120 | }; 121 | 122 | export default StackNavigator; 123 | 124 | const styles = StyleSheet.create({}); 125 | -------------------------------------------------------------------------------- /screens/ProfileScreen.js: -------------------------------------------------------------------------------- 1 | import { 2 | Image, 3 | Pressable, 4 | ScrollView, 5 | StyleSheet, 6 | Text, 7 | View, 8 | } from 'react-native'; 9 | import React, { useLayoutEffect, useState, useEffect, useContext } from 'react'; 10 | import { Ionicons, AntDesign } from '@expo/vector-icons'; 11 | import { useNavigation } from '@react-navigation/native'; 12 | import { UserType } from '../UserContext'; 13 | import axios from 'axios'; 14 | 15 | const ProfileScreen = () => { 16 | const navigation = useNavigation(); 17 | const { userId, setUserId } = useContext(UserType); 18 | const [orders, setOrders] = useState([]); 19 | const [loading, setLoading] = useState(true); 20 | useLayoutEffect(() => { 21 | navigation.setOptions({ 22 | headerTitle: '', 23 | headerStyle: { 24 | backgroundColor: '#00CED1', 25 | }, 26 | headerLeft: () => ( 27 | 33 | ), 34 | headerRight: () => ( 35 | 43 | 44 | 45 | 46 | 47 | ), 48 | }); 49 | }, []); 50 | 51 | const [user, setUser] = useState(); 52 | useEffect(() => { 53 | const fetchUserProfile = async () => { 54 | try { 55 | const response = await axios.get( 56 | `http://localhost:8000/profile/${userId}` 57 | ); 58 | const { user } = response.data; 59 | setUser(user); 60 | } catch (error) { 61 | console.log('error', error); 62 | } 63 | }; 64 | 65 | fetchUserProfile(); 66 | }, []); 67 | const logout = () => { 68 | clearAuthToken(); 69 | }; 70 | const clearAuthToken = async () => { 71 | await AsyncStorage.removeItem('authToken'); 72 | console.log('auth token cleared'); 73 | navigation.replace('Login'); 74 | }; 75 | useEffect(() => { 76 | const fetchOrders = async () => { 77 | try { 78 | const response = await axios.get( 79 | `http://localhost:8000/orders/${userId}` 80 | ); 81 | const orders = response.data.orders; 82 | setOrders(orders); 83 | 84 | setLoading(false); 85 | } catch (error) { 86 | console.log('error', error); 87 | } 88 | }; 89 | 90 | fetchOrders(); 91 | }, []); 92 | console.log('orders', orders); 93 | return ( 94 | 95 | 96 | Welcome {user?.name} 97 | 98 | 99 | 107 | 115 | Your orders 116 | 117 | 118 | 126 | Your Account 127 | 128 | 129 | 130 | 138 | 146 | Buy Again 147 | 148 | 149 | 158 | Logout 159 | 160 | 161 | 162 | 163 | {loading ? ( 164 | Loading... 165 | ) : orders.length > 0 ? ( 166 | orders.map((order) => ( 167 | 180 | {/* Render the order information here */} 181 | {order.products.slice(0, 1)?.map((product) => ( 182 | 183 | 187 | 188 | ))} 189 | 190 | )) 191 | ) : ( 192 | No orders found 193 | )} 194 | 195 | 196 | ); 197 | }; 198 | 199 | export default ProfileScreen; 200 | 201 | const styles = StyleSheet.create({}); 202 | -------------------------------------------------------------------------------- /screens/LoginScreen.js: -------------------------------------------------------------------------------- 1 | import { 2 | Alert, 3 | Image, 4 | KeyboardAvoidingView, 5 | Pressable, 6 | StyleSheet, 7 | Text, 8 | TextInput, 9 | View, 10 | } from 'react-native'; 11 | import React, { useState } from 'react'; 12 | import { SafeAreaView } from 'react-native-safe-area-context'; 13 | import { MaterialIcons } from '@expo/vector-icons'; 14 | import { AntDesign } from '@expo/vector-icons'; 15 | import { useNavigation } from '@react-navigation/native'; 16 | import AsyncStorage from '@react-native-async-storage/async-storage'; 17 | 18 | import axios from 'axios'; 19 | import { useEffect } from 'react'; 20 | 21 | const LoginScreen = () => { 22 | const [email, setEmail] = useState(''); 23 | const [password, setPassword] = useState(''); 24 | 25 | const navigation = useNavigation(); 26 | 27 | useEffect(() => { 28 | const checkLoginStatus = async () => { 29 | try { 30 | const token = await AsyncStorage.getItem('authToken'); 31 | if (token) { 32 | navigation.replace('Main'); 33 | } 34 | } catch (err) { 35 | console.log('error message', err); 36 | } 37 | }; 38 | checkLoginStatus(); 39 | }, []); 40 | 41 | const handleLogin = () => { 42 | const user = { 43 | email: email, 44 | password: password, 45 | }; 46 | 47 | axios 48 | .post(`http://localhost:8000/login`, user) 49 | .then((response) => { 50 | console.log(response); 51 | const token = response.data.token; 52 | AsyncStorage.setItem('authToken', token); 53 | navigation.replace('Main'); 54 | }) 55 | .catch((error) => { 56 | Alert.alert('Login Error', 'Invalid Email or Password'); 57 | console.log(error); 58 | }); 59 | }; 60 | return ( 61 | 64 | 65 | 71 | 72 | 73 | 74 | 75 | 83 | Login to your Account 84 | 85 | 86 | 87 | 88 | 99 | 105 | setEmail(text)} 108 | style={{ 109 | color: 'gray', 110 | marginVertical: 10, 111 | width: 300, 112 | fontSize: email ? 16 : 16, 113 | }} 114 | placeholder="enter your Email" 115 | /> 116 | 117 | 118 | 119 | 120 | 131 | 137 | setPassword(text)} 140 | secureTextEntry={true} 141 | style={{ 142 | color: 'gray', 143 | marginVertical: 10, 144 | width: 300, 145 | fontSize: password ? 16 : 16, 146 | }} 147 | placeholder="enter your Password" 148 | /> 149 | 150 | 151 | 152 | 160 | Keep me logged in 161 | 162 | Forgot Password 163 | 164 | 165 | 166 | 167 | 168 | 179 | 187 | Login 188 | 189 | 190 | 191 | navigation.navigate('Register')} 194 | > 195 | 196 | Don't have an account? Sign Up 197 | 198 | 199 | 200 | 201 | ); 202 | }; 203 | 204 | export default LoginScreen; 205 | 206 | const styles = StyleSheet.create({}); 207 | -------------------------------------------------------------------------------- /screens/AddAddressScreen.js: -------------------------------------------------------------------------------- 1 | import { StyleSheet, Text, View } from 'react-native'; 2 | import React, { useCallback, useContext, useEffect, useState } from 'react'; 3 | import { ScrollView } from 'react-native'; 4 | import { TextInput } from 'react-native'; 5 | import { AntDesign, Feather, MaterialIcons, Entypo } from '@expo/vector-icons'; 6 | import { Pressable } from 'react-native'; 7 | import { useFocusEffect, useNavigation } from '@react-navigation/native'; 8 | import axios from 'axios'; 9 | import { UserType } from '../UserContext'; 10 | 11 | const AddAddressScreen = () => { 12 | const navigation = useNavigation(); 13 | const [addresses, setAddresses] = useState([]); 14 | 15 | const { userId, setUserId } = useContext(UserType); 16 | console.log(userId); 17 | useEffect(() => { 18 | fetchAddresses(); 19 | }, []); 20 | 21 | const fetchAddresses = async () => { 22 | try { 23 | const response = await axios.get( 24 | `http://localhost:8000/addresses/${userId}` 25 | ); 26 | const { addresses } = response.data; 27 | setAddresses(addresses); 28 | } catch (error) { 29 | console.log('Error', error); 30 | } 31 | }; 32 | // refress the addressess when the component come into focus 33 | useFocusEffect( 34 | useCallback(() => { 35 | fetchAddresses(); 36 | }) 37 | ); 38 | return ( 39 | 40 | 48 | 60 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | Your Addresses 73 | navigation.navigate('Add')} 75 | style={{ 76 | flexDirection: 'row', 77 | alignItems: 'center', 78 | justifyContent: 'space-between', 79 | marginTop: 10, 80 | borderColor: '#D0D0D0', 81 | borderWidth: 1, 82 | borderLeftWidth: 0, 83 | borderRightWidth: 0, 84 | paddingVertical: 7, 85 | paddingHorizontal: 5, 86 | }} 87 | > 88 | Add a new address 89 | 90 | 91 | 92 | 93 | {/* all the added addresses */} 94 | {addresses?.map((item, index) => ( 95 | 106 | 109 | 110 | {item.name} 111 | 112 | 113 | 114 | 115 | 116 | {item.houseNo}, {item.landmark} 117 | 118 | 119 | 120 | {item.street} 121 | 122 | 123 | 124 | India, Rajasthan 125 | 126 | 127 | 128 | Phone No : {item.mobileNo} 129 | 130 | 131 | Pin code : {item.postalCode} 132 | 133 | 134 | 142 | 152 | Edit 153 | 154 | 155 | 165 | Remove 166 | 167 | 168 | 178 | Set as Default 179 | 180 | 181 | 182 | ))} 183 | 184 | 185 | 186 | ); 187 | }; 188 | 189 | export default AddAddressScreen; 190 | 191 | const styles = StyleSheet.create({}); 192 | -------------------------------------------------------------------------------- /screens/AddressScreen.js: -------------------------------------------------------------------------------- 1 | import { 2 | Alert, 3 | Pressable, 4 | ScrollView, 5 | StyleSheet, 6 | Text, 7 | TextInput, 8 | View, 9 | } from 'react-native'; 10 | import React, { useContext, useEffect, useState } from 'react'; 11 | import { useNavigation } from '@react-navigation/native'; 12 | import AsyncStorage from '@react-native-async-storage/async-storage'; 13 | import jwt_decode from 'jwt-decode'; 14 | import { UserType } from '../UserContext'; 15 | import axios from 'axios'; 16 | 17 | const AddressScreen = () => { 18 | const navigation = useNavigation(); 19 | const [name, setName] = useState(''); 20 | const [mobileNo, setMobileNo] = useState(''); 21 | const [houseNo, setHouseNo] = useState(''); 22 | const [street, setStreet] = useState(''); 23 | const [landmark, setLandmark] = useState(''); 24 | const [postalCode, setPostalCode] = useState(''); 25 | 26 | const { userId, setUserId } = useContext(UserType); 27 | useEffect(() => { 28 | const fetchUser = async () => { 29 | const token = await AsyncStorage.getItem('authToken'); 30 | const decodedToken = jwt_decode(token); 31 | const userId = decodedToken.userId; 32 | setUserId(userId); 33 | }; 34 | fetchUser(); 35 | }, []); 36 | 37 | const handleAddAddress = () => { 38 | const address = { 39 | name, 40 | mobileNo, 41 | houseNo, 42 | street, 43 | landmark, 44 | postalCode, 45 | }; 46 | 47 | axios 48 | .post('http://localhost:8000/addresses', { userId, address }) 49 | .then((response) => { 50 | Alert.alert('Success', 'Address added successfully'); 51 | setName(''); 52 | setMobileNo(''); 53 | setHouseNo(''); 54 | setStreet(''); 55 | setLandmark(''); 56 | setPostalCode(''); 57 | 58 | setTimeout(() => { 59 | navigation.goBack(); 60 | }, 500); 61 | }) 62 | .catch((error) => { 63 | Alert.alert('Error', 'Failed to add address'); 64 | console.log('Error', error); 65 | }); 66 | }; 67 | return ( 68 | 69 | 70 | 71 | 72 | Add a new address 73 | 74 | 75 | 86 | 87 | 88 | 89 | Full name (first and last name) 90 | 91 | setName(text)} 94 | placeholderTextColor={'#000'} 95 | placeholder="Enter your name" 96 | style={{ 97 | padding: 10, 98 | borderColor: '#D0D0D0', 99 | borderWidth: 1, 100 | marginTop: 10, 101 | borderRadius: 5, 102 | }} 103 | /> 104 | 105 | 106 | 107 | 108 | Mobile Number 109 | 110 | setMobileNo(text)} 113 | placeholderTextColor={'#000'} 114 | placeholder="Mobile No" 115 | style={{ 116 | padding: 10, 117 | borderColor: '#D0D0D0', 118 | borderWidth: 1, 119 | marginTop: 10, 120 | borderRadius: 5, 121 | }} 122 | /> 123 | 124 | 125 | 126 | 127 | Flat, House No, Building, Company 128 | 129 | setHouseNo(text)} 132 | placeholderTextColor={'#000'} 133 | placeholder="" 134 | style={{ 135 | padding: 10, 136 | borderColor: '#D0D0D0', 137 | borderWidth: 1, 138 | marginTop: 10, 139 | borderRadius: 5, 140 | }} 141 | /> 142 | 143 | 144 | 145 | 146 | Area, Street, Sector, Village 147 | 148 | setStreet(text)} 151 | placeholderTextColor={'#000'} 152 | placeholder="" 153 | style={{ 154 | padding: 10, 155 | borderColor: '#D0D0D0', 156 | borderWidth: 1, 157 | marginTop: 10, 158 | borderRadius: 5, 159 | }} 160 | /> 161 | 162 | 163 | 164 | Landmark 165 | setLandmark(text)} 168 | placeholderTextColor={'#000'} 169 | placeholder="Eg near appollo Hospital" 170 | style={{ 171 | padding: 10, 172 | borderColor: '#D0D0D0', 173 | borderWidth: 1, 174 | marginTop: 10, 175 | borderRadius: 5, 176 | }} 177 | /> 178 | 179 | 180 | 181 | Pincode 182 | setPostalCode(text)} 185 | placeholderTextColor={'#000'} 186 | placeholder="Enter Pincode" 187 | style={{ 188 | padding: 10, 189 | borderColor: '#D0D0D0', 190 | borderWidth: 1, 191 | marginTop: 10, 192 | borderRadius: 5, 193 | }} 194 | /> 195 | 196 | 197 | 208 | Add Address 209 | 210 | 211 | 212 | ); 213 | }; 214 | 215 | export default AddressScreen; 216 | 217 | const styles = StyleSheet.create({}); 218 | -------------------------------------------------------------------------------- /screens/RegisterScreen.js: -------------------------------------------------------------------------------- 1 | import { 2 | Alert, 3 | Image, 4 | KeyboardAvoidingView, 5 | Pressable, 6 | StyleSheet, 7 | Text, 8 | TextInput, 9 | View, 10 | } from 'react-native'; 11 | import React, { useState } from 'react'; 12 | import { SafeAreaView } from 'react-native-safe-area-context'; 13 | import { MaterialIcons } from '@expo/vector-icons'; 14 | import { AntDesign } from '@expo/vector-icons'; 15 | import { Ionicons } from '@expo/vector-icons'; 16 | import { useNavigation } from '@react-navigation/native'; 17 | import axios from 'axios'; 18 | 19 | const RegisterScreen = () => { 20 | const [email, setEmail] = useState(''); 21 | const [name, setName] = useState(''); 22 | const [password, setPassword] = useState(''); 23 | 24 | const navigation = useNavigation(); 25 | 26 | const handleRegister = () => { 27 | const user = { 28 | name: name, 29 | email: email, 30 | password: password, 31 | }; 32 | 33 | // send a post request to the backend API 34 | axios 35 | .post(`http://locahost:8000/register`, user) 36 | .then((response) => { 37 | console.log(response); 38 | Alert.alert( 39 | 'Registration Successfull', 40 | 'You have registered successfully' 41 | ); 42 | setName(''); 43 | setEmail(''); 44 | setPassword(''); 45 | }) 46 | .catch((error) => { 47 | Alert.alert( 48 | 'Registration Error', 49 | 'An error occured during registration' 50 | ); 51 | setName(''); 52 | setEmail(''); 53 | setPassword(''); 54 | console.log('registration failed', error); 55 | }); 56 | }; 57 | 58 | return ( 59 | 62 | 63 | 69 | 70 | 71 | 72 | 73 | 81 | Register to your Account 82 | 83 | 84 | 85 | 86 | 97 | 103 | setName(text)} 106 | style={{ 107 | color: 'gray', 108 | marginVertical: 10, 109 | width: 300, 110 | fontSize: name ? 16 : 16, 111 | }} 112 | placeholder="enter your Name" 113 | /> 114 | 115 | 126 | 132 | setEmail(text)} 135 | style={{ 136 | color: 'gray', 137 | marginVertical: 10, 138 | width: 300, 139 | fontSize: email ? 16 : 16, 140 | }} 141 | placeholder="enter your Email" 142 | /> 143 | 144 | 145 | 146 | 157 | 163 | setPassword(text)} 167 | style={{ 168 | color: 'gray', 169 | marginVertical: 10, 170 | width: 300, 171 | fontSize: password ? 16 : 16, 172 | }} 173 | placeholder="enter your Password" 174 | /> 175 | 176 | 177 | 185 | Keep me logged in 186 | 187 | Forgot Password 188 | 189 | 190 | 191 | 192 | 193 | 204 | 212 | Register 213 | 214 | 215 | 216 | navigation.goBack()} 219 | > 220 | 221 | Already have an account? Sign In 222 | 223 | 224 | 225 | 226 | ); 227 | }; 228 | 229 | export default RegisterScreen; 230 | 231 | const styles = StyleSheet.create({}); 232 | -------------------------------------------------------------------------------- /screens/ProductInfoScreen.js: -------------------------------------------------------------------------------- 1 | import { 2 | Dimensions, 3 | Image, 4 | ImageBackground, 5 | Pressable, 6 | ScrollView, 7 | StyleSheet, 8 | Text, 9 | TextInput, 10 | View, 11 | } from 'react-native'; 12 | import React, { useState } from 'react'; 13 | import { AntDesign } from '@expo/vector-icons'; 14 | import { Feather } from '@expo/vector-icons'; 15 | import { MaterialCommunityIcons } from '@expo/vector-icons'; 16 | import { Ionicons } from '@expo/vector-icons'; 17 | import { useNavigation, useRoute } from '@react-navigation/native'; 18 | import { useDispatch, useSelector } from 'react-redux'; 19 | import { addToCart } from '../redux/CartReducer'; 20 | 21 | const ProductInfoScreen = () => { 22 | const route = useRoute(); 23 | const { width } = Dimensions.get('window'); 24 | const navigation = useNavigation(); 25 | 26 | const [addedToCart, setAddedToCart] = useState(false); 27 | 28 | const height = (width * 100) / 100; 29 | 30 | const dispatch = useDispatch(); 31 | 32 | const addItemToCart = (item) => { 33 | setAddedToCart(true); 34 | dispatch(addToCart(item)); 35 | setTimeout(() => { 36 | setAddedToCart(false); 37 | }, 60000); 38 | }; 39 | 40 | const cart = useSelector((state) => state.cart.cart); 41 | console.log(cart); 42 | return ( 43 | 44 | 52 | 64 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | {route.params.carouselImages.map((item, index) => ( 77 | 83 | 91 | 102 | 110 | 20% offer 111 | 112 | 113 | 124 | 129 | 130 | 131 | 145 | 146 | 147 | 148 | ))} 149 | 150 | 151 | 152 | 153 | {route?.params?.title} 154 | 155 | 156 | ₹{route.params.price} 157 | 158 | 159 | 160 | 167 | Color: 168 | 169 | {route.params.color} 170 | 171 | 172 | 173 | 180 | Size: 181 | 182 | {route.params.size} 183 | 184 | 185 | 186 | 187 | 188 | Total : ₹{route.params.price} 189 | 190 | 191 | FREE Delivery Tommorrow by 3 PM.Order within 10hrs 30mins 192 | 193 | 194 | 202 | 203 | 204 | Deliver to Jignesh - Udaipur 301302 205 | 206 | 207 | 208 | 209 | 210 | In Stock 211 | 212 | 213 | addItemToCart(route?.params.item)} 215 | style={{ 216 | backgroundColor: '#FFC72C', 217 | padding: 10, 218 | borderRadius: 20, 219 | justifyContent: 'center', 220 | alignItems: 'center', 221 | marginHorizontal: 10, 222 | marginVertical: 10, 223 | }} 224 | > 225 | 226 | {addedToCart ? ( 227 | 228 | Added to Cart 229 | 230 | ) : ( 231 | 232 | Add to Cart 233 | 234 | )} 235 | 236 | 237 | 238 | 249 | Buy Now 250 | 251 | 252 | ); 253 | }; 254 | 255 | export default ProductInfoScreen; 256 | 257 | const styles = StyleSheet.create({}); 258 | -------------------------------------------------------------------------------- /api/index.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const bodyParser = require('body-parser'); 3 | const mongoose = require('mongoose'); 4 | const crypto = require('crypto'); 5 | const nodemailer = require('nodemailer'); 6 | require('dotenv').config(); 7 | 8 | const app = express(); 9 | const port = 8000; 10 | 11 | const cors = require('cors'); 12 | app.use(cors()); 13 | 14 | app.use(bodyParser.urlencoded({ extended: false })); 15 | app.use(bodyParser.json()); 16 | 17 | const jwt = require('jsonwebtoken'); 18 | 19 | mongoose 20 | .connect(`${process.env.MONGO_URL}`, { 21 | useNewUrlParser: true, 22 | useUnifiedTopology: true, 23 | }) 24 | .then(() => { 25 | console.log('Connected to MongoDB'); 26 | }) 27 | .catch((err) => { 28 | console.log('Error connecting to MongoDB', err); 29 | }); 30 | 31 | app.listen(port, () => { 32 | console.log(`Server is running on Port ${port}`); 33 | }); 34 | 35 | // models 36 | const User = require('./models/user'); 37 | const Order = require('./models/order'); 38 | 39 | // function to send verification email to the user 40 | const sendVerificationEmail = async (email, verificationToken) => { 41 | // Create a Nodemailer transporter 42 | const transporter = nodemailer.createTransport({ 43 | // Configure the email service or SMTP details here 44 | service: 'gmail', 45 | auth: { 46 | user: process.env.SENDER_EMAIL, 47 | pass: process.env.SENDER_PASSWORD, 48 | }, 49 | }); 50 | 51 | // componse the email message 52 | const mailOptions = { 53 | from: 'amazon.com', 54 | to: email, 55 | subject: 'Email Verification', 56 | text: `Please click the following link to verify your email: http://localhost:8000/verify/${verificationToken}`, 57 | }; 58 | 59 | // send the email 60 | try { 61 | await transporter.sendMail(mailOptions); 62 | console.log('Verification email sent successfully'); 63 | } catch (error) { 64 | console.error('Error sending verification email:', error); 65 | } 66 | }; 67 | 68 | // endpoint to register user 69 | app.post('/register', async (req, res) => { 70 | try { 71 | const { name, email, password } = req.body; 72 | 73 | // Check if the email is already registered 74 | const existingUser = await User.findOne({ email }); 75 | if (existingUser) { 76 | console.log('Email already registered:', email); // Debugging statement 77 | return res.status(400).json({ message: 'Email already registered' }); 78 | } 79 | 80 | // Create a new user 81 | const newUser = new User({ name, email, password }); 82 | 83 | // Generate and store the verification token 84 | newUser.verificationToken = crypto.randomBytes(20).toString('hex'); 85 | 86 | // Save the user to the database 87 | await newUser.save(); 88 | 89 | // Debugging statement to verify data 90 | console.log('New User Registered:', newUser); 91 | 92 | // Send verification email to the user 93 | // Use your preferred email service or library to send the email 94 | sendVerificationEmail(newUser.email, newUser.verificationToken); 95 | 96 | res.status(201).json({ 97 | message: 98 | 'Registration successful. Please check your email for verification.', 99 | }); 100 | } catch (error) { 101 | console.log('Error during registration:', error); // Debugging statement 102 | res.status(500).json({ message: 'Registration failed' }); 103 | } 104 | }); 105 | 106 | //endpoint to verify the email 107 | app.get('/verify/:token', async (req, res) => { 108 | try { 109 | const token = req.params.token; 110 | 111 | //Find the user witht the given verification token 112 | const user = await User.findOne({ verificationToken: token }); 113 | if (!user) { 114 | return res.status(404).json({ message: 'Invalid verification token' }); 115 | } 116 | 117 | //Mark the user as verified 118 | user.verified = true; 119 | user.verificationToken = undefined; 120 | 121 | await user.save(); 122 | 123 | res.status(200).json({ message: 'Email verified successfully' }); 124 | } catch (error) { 125 | res.status(500).json({ message: 'Email Verificatioion Failed' }); 126 | } 127 | }); 128 | 129 | const generateSecretKey = () => { 130 | const secretKey = crypto.randomBytes(32).toString('hex'); 131 | return secretKey; 132 | }; 133 | const secretKey = generateSecretKey(); 134 | 135 | // endpoint to login the user 136 | app.post('/login', async (req, res) => { 137 | try { 138 | const { email, password } = req.body; 139 | 140 | // check if the user exist 141 | const user = await User.findOne({ email }); 142 | if (!user) { 143 | return res.status(401).json({ message: 'Invalid Credentials' }); 144 | } 145 | 146 | // check if password is right or not 147 | if (user.password !== password) { 148 | return res.status(401).json({ message: 'Invalid Credentials' }); 149 | } 150 | 151 | // generate a token 152 | const token = jwt.sign({ userId: user._id }, secretKey); 153 | 154 | res.status(200).json({ token }); 155 | } catch (error) { 156 | res.status(500).json({ message: 'Login Failed' }); 157 | } 158 | }); 159 | 160 | // endpoint to store a new address into the backend 161 | app.post('/addresses', async (req, res) => { 162 | try { 163 | const { userId, address } = req.body; 164 | 165 | // find the user by userid 166 | const user = await User.findById(userId); 167 | if (!user) { 168 | return res.status(404).json({ message: 'User not found' }); 169 | } 170 | 171 | // add the new address to the users addresses array 172 | user.addresses.push(address); 173 | 174 | // save the updated user in the backend 175 | await user.save(); 176 | 177 | res.status(200).json({ message: 'Address Created Successfully' }); 178 | } catch (error) { 179 | res.status(500).json({ message: 'Error Entering Address' }); 180 | } 181 | }); 182 | 183 | //endpoint to get all the addresses of a particular user 184 | app.get('/addresses/:userId', async (req, res) => { 185 | try { 186 | const userId = req.params.userId; 187 | 188 | const user = await User.findById(userId); 189 | 190 | if (!user) { 191 | return res.status(404).json({ message: 'User not found' }); 192 | } 193 | 194 | const addresses = user.addresses; 195 | res.status(200).json({ addresses }); 196 | } catch (error) { 197 | res.status(500).json({ message: 'Error retrieving the address' }); 198 | } 199 | }); 200 | 201 | //endpoint to store all the orders 202 | app.post('/orders', async (req, res) => { 203 | try { 204 | const { userId, cartItems, totalPrice, shippingAddress, paymentMethod } = 205 | req.body; 206 | 207 | const user = await User.findById(userId); 208 | if (!user) { 209 | return res.status(404).json({ message: 'User not found' }); 210 | } 211 | 212 | //create an array of product objects from the cart Items 213 | const products = cartItems.map((item) => ({ 214 | name: item?.title, 215 | quantity: item.quantity, 216 | price: item.price, 217 | image: item?.image, 218 | })); 219 | 220 | //create a new Order 221 | const order = new Order({ 222 | user: userId, 223 | products: products, 224 | totalPrice: totalPrice, 225 | shippingAddress: shippingAddress, 226 | paymentMethod: paymentMethod, 227 | }); 228 | 229 | await order.save(); 230 | 231 | res.status(200).json({ message: 'Order created successfully!' }); 232 | } catch (error) { 233 | console.log('error creating orders', error); 234 | res.status(500).json({ message: 'Error creating orders' }); 235 | } 236 | }); 237 | 238 | //get the user profile 239 | app.get('/profile/:userId', async (req, res) => { 240 | try { 241 | const userId = req.params.userId; 242 | 243 | const user = await User.findById(userId); 244 | 245 | if (!user) { 246 | return res.status(404).json({ message: 'User not found' }); 247 | } 248 | 249 | res.status(200).json({ user }); 250 | } catch (error) { 251 | res.status(500).json({ message: 'Error retrieving the user profile' }); 252 | } 253 | }); 254 | 255 | // get the order of that particular user 256 | app.get('/orders/:userId', async (req, res) => { 257 | try { 258 | const userId = req.params.userId; 259 | 260 | const orders = await Order.find({ user: userId }).populate('user'); 261 | 262 | if (!orders || orders.length === 0) { 263 | return res.status(404).json({ message: 'No orders found for this user' }); 264 | } 265 | 266 | res.status(200).json({ orders }); 267 | } catch (error) { 268 | res.status(500).json({ message: 'Error' }); 269 | } 270 | }); 271 | -------------------------------------------------------------------------------- /screens/CartScreen.js: -------------------------------------------------------------------------------- 1 | import { 2 | Image, 3 | Pressable, 4 | ScrollView, 5 | StyleSheet, 6 | Text, 7 | TextInput, 8 | View, 9 | } from 'react-native'; 10 | import React from 'react'; 11 | import { AntDesign, Feather } from '@expo/vector-icons'; 12 | import { useDispatch, useSelector } from 'react-redux'; 13 | import { 14 | decrementQuantity, 15 | incrementQuantity, 16 | removeFromCart, 17 | } from '../redux/CartReducer'; 18 | import { useNavigation } from '@react-navigation/native'; 19 | const CartScreen = () => { 20 | const navigation = useNavigation(); 21 | 22 | const cart = useSelector((state) => state.cart.cart); 23 | 24 | console.log(cart); 25 | const total = cart 26 | ?.map((item) => item.price * item.quantity) 27 | .reduce((curr, prev) => curr + prev, 0); 28 | console.log(total); 29 | 30 | const dispatch = useDispatch(); 31 | const increaseQuantity = (item) => { 32 | dispatch(incrementQuantity(item)); 33 | }; 34 | 35 | const decreaseQuantity = (item) => { 36 | dispatch(decrementQuantity(item)); 37 | }; 38 | 39 | const deleteItem = (item) => { 40 | dispatch(removeFromCart(item)); 41 | }; 42 | return ( 43 | 44 | 52 | 64 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | Subtotal : 77 | ₹{total} 78 | 79 | 80 | EMI details Available 81 | 82 | navigation.navigate('Confirm')} 84 | style={{ 85 | backgroundColor: '#FFC72C', 86 | padding: 10, 87 | borderRadius: 5, 88 | justifyContent: 'center', 89 | alignItems: 'center', 90 | marginHorizontal: 10, 91 | marginTop: 10, 92 | }} 93 | > 94 | Proceed to Buy ({cart.length}) item 95 | 96 | 104 | 105 | 106 | {cart?.map((item, index) => ( 107 | 119 | 126 | 127 | 131 | 132 | 133 | 134 | {item?.title} 135 | 136 | 139 | {item?.price} 140 | 141 | 147 | In Stock 148 | {/* 149 | {item?.rating?.rate} ratings 150 | */} 151 | 152 | 153 | 154 | 163 | 172 | {item?.quantity > 1 ? ( 173 | decreaseQuantity(item)} 175 | style={{ 176 | backgroundColor: '#D8D8D8', 177 | padding: 7, 178 | borderTopLeftRadius: 6, 179 | borderBottomLeftRadius: 6, 180 | }} 181 | > 182 | 183 | 184 | ) : ( 185 | deleteItem(item)} 187 | style={{ 188 | backgroundColor: '#D8D8D8', 189 | padding: 7, 190 | borderTopLeftRadius: 6, 191 | borderBottomLeftRadius: 6, 192 | }} 193 | > 194 | 195 | 196 | )} 197 | 198 | 199 | 206 | {item?.quantity} 207 | 208 | 209 | increaseQuantity(item)} 211 | style={{ 212 | backgroundColor: '#D8D8D8', 213 | padding: 7, 214 | borderTopLeftRadius: 6, 215 | borderBottomLeftRadius: 6, 216 | }} 217 | > 218 | 219 | 220 | 221 | deleteItem(item)} 223 | style={{ 224 | backgroundColor: 'white', 225 | paddingHorizontal: 8, 226 | paddingVertical: 10, 227 | borderRadius: 5, 228 | borderColor: '#C0C0C0', 229 | borderWidth: 0.6, 230 | }} 231 | > 232 | Delete 233 | 234 | 235 | 236 | 244 | 254 | Save for Later 255 | 256 | 257 | 267 | See More Like this 268 | 269 | 270 | 271 | ))} 272 | 273 | 274 | ); 275 | }; 276 | 277 | export default CartScreen; 278 | 279 | const styles = StyleSheet.create({}); 280 | -------------------------------------------------------------------------------- /screens/ConfirmationScreen.js: -------------------------------------------------------------------------------- 1 | import { Pressable, ScrollView, StyleSheet, Text, View } from 'react-native'; 2 | import React, { useContext, useEffect, useState } from 'react'; 3 | import axios from 'axios'; 4 | import { UserType } from '../UserContext'; 5 | import { Entypo, FontAwesome5, MaterialIcons } from '@expo/vector-icons'; 6 | import { useDispatch, useSelector } from 'react-redux'; 7 | import { useNavigation } from '@react-navigation/native'; 8 | import { cleanCart } from '../redux/CartReducer'; 9 | import { Alert } from 'react-native'; 10 | 11 | const ConfirmationScreen = () => { 12 | const steps = [ 13 | { title: 'Address', content: 'Address Form' }, 14 | { title: 'Delivery', content: 'Delivery Options' }, 15 | { title: 'Payment', content: 'Payment Details' }, 16 | { title: 'Place Order', content: 'Order Summary' }, 17 | ]; 18 | const navigation = useNavigation(); 19 | const [currentStep, setCurrentStep] = useState(0); 20 | const [addresses, setAddresses] = useState([]); 21 | const { userId, setUserId } = useContext(UserType); 22 | 23 | const cart = useSelector((state) => state.cart.cart); 24 | 25 | const total = cart 26 | ?.map((item) => item.price * item.quantity) 27 | .reduce((curr, prev) => curr + prev, 0); 28 | 29 | useEffect(() => { 30 | fetchAddresses(); 31 | }, []); 32 | 33 | const fetchAddresses = async () => { 34 | try { 35 | const response = await axios.get( 36 | `http://localhost:8000/addresses/${userId}` 37 | ); 38 | const { addresses } = response.data; 39 | setAddresses(addresses); 40 | } catch (error) { 41 | console.log('Error', error); 42 | } 43 | }; 44 | 45 | const dispatch = useDispatch(); 46 | const [selectedAddress, setSelectedAddress] = useState(''); 47 | const [options, setOptions] = useState(false); 48 | const [selectedOptions, setSelectedOptions] = useState(''); 49 | 50 | const handlePlaceOrder = async () => { 51 | try { 52 | const orderData = { 53 | userId: userId, 54 | cartItems: cart, 55 | totalPrice: total, 56 | shippingAddress: selectedAddress, 57 | paymentMethod: selectedOptions, 58 | }; 59 | 60 | const response = await axios.post( 61 | 'http://localhost:8000/orders', 62 | orderData 63 | ); 64 | 65 | if (response.status === 200) { 66 | navigation.navigate('Order'); 67 | dispatch(cleanCart()); 68 | console.log('order created successfully', response.data.order); 69 | } else { 70 | console.log('Error creating order', response.data.order); 71 | } 72 | } catch (error) { 73 | console.log('Error', error); 74 | } 75 | }; 76 | 77 | const pay = async () => { 78 | try { 79 | } catch (error) { 80 | console.log('Error', error); 81 | } 82 | }; 83 | 84 | return ( 85 | 86 | 87 | 95 | {steps?.map((step, index) => ( 96 | 100 | {index > 0 && ( 101 | 107 | )} 108 | 121 | {index < currentStep ? ( 122 | 125 | ✓ 126 | 127 | ) : ( 128 | 131 | {index + 1} 132 | 133 | )} 134 | 135 | 136 | {step.title} 137 | 138 | 139 | ))} 140 | 141 | 142 | {currentStep == 0 && ( 143 | 144 | 145 | Select Delivery Address 146 | 147 | 148 | 149 | {addresses.map((item, index) => ( 150 | 164 | {selectedAddress && selectedAddress._id === item?._id ? ( 165 | 166 | ) : ( 167 | setSelectedAddress(item)} 169 | name="circle" 170 | size={24} 171 | color="gray" 172 | /> 173 | )} 174 | 175 | 176 | 183 | 184 | {item.name} 185 | 186 | 187 | 188 | 189 | {item.houseNo}, {item.landmark} 190 | 191 | 192 | {item.street} 193 | 194 | 195 | India, Rajasthan 196 | 197 | 198 | Phone No : {item.mobileNo} 199 | 200 | 201 | Pin code : {item.postalCode} 202 | 203 | 211 | 221 | Edit 222 | 223 | 224 | 234 | Remove 235 | 236 | 237 | 247 | Set as Default 248 | 249 | 250 | 251 | {selectedAddress && selectedAddress._id === item?._id && ( 252 | setCurrentStep(1)} 254 | style={{ 255 | backgroundColor: '#008897', 256 | padding: 10, 257 | borderRadius: 20, 258 | justifyContent: 'center', 259 | alignItems: 'center', 260 | marginTop: 10, 261 | }} 262 | > 263 | 264 | Deliver to this address 265 | 266 | 267 | )} 268 | 269 | 270 | 271 | ))} 272 | 273 | 274 | )} 275 | 276 | {currentStep == 1 && ( 277 | 278 | 279 | Choose your delivery options 280 | 281 | 282 | 294 | {options ? ( 295 | setOptions(!options)} 297 | name="dot-circle" 298 | size={20} 299 | color="#008397" 300 | /> 301 | ) : ( 302 | setOptions(!options)} 304 | name="circle" 305 | size={20} 306 | color="gray" 307 | /> 308 | )} 309 | 310 | 311 | 312 | Tommorrow by 10pm 313 | 314 | - FREE Delivery with your Prime Membership 315 | 316 | 317 | 318 | setCurrentStep(2)} 320 | style={{ 321 | backgroundColor: '#ffc72c', 322 | padding: 10, 323 | borderRadius: 20, 324 | justifyContent: 'center', 325 | alignItems: 'center', 326 | marginTop: 15, 327 | }} 328 | > 329 | Continue 330 | 331 | 332 | )} 333 | 334 | {currentStep == 2 && ( 335 | 336 | 337 | Select your payment Method 338 | 339 | 340 | 352 | {selectedOptions == 'cash' ? ( 353 | 354 | ) : ( 355 | setSelectedOptions('cash')} 357 | name="circle" 358 | size={20} 359 | color="gray" 360 | /> 361 | )} 362 | 363 | Cash on Delivery 364 | 365 | 366 | 378 | {selectedOptions == 'card' ? ( 379 | 380 | ) : ( 381 | { 383 | setSelectedOptions('card'); 384 | Alert.alert('UPI/Debit cart', 'Pay Online', [ 385 | { 386 | text: 'Cancel', 387 | onPress: () => console.log('Cancelled is pressed'), 388 | }, 389 | { 390 | text: 'Ok', 391 | onPress: () => pay(), 392 | }, 393 | ]); 394 | }} 395 | name="circle" 396 | size={20} 397 | color="gray" 398 | /> 399 | )} 400 | 401 | UPI / Credit or Debit card 402 | 403 | setCurrentStep(3)} 405 | style={{ 406 | backgroundColor: '#ffc72c', 407 | padding: 10, 408 | borderRadius: 20, 409 | justifyContent: 'center', 410 | alignItems: 'center', 411 | marginTop: 15, 412 | }} 413 | > 414 | Continue 415 | 416 | 417 | )} 418 | 419 | {currentStep == 3 && selectedOptions === 'cash' && ( 420 | 421 | Order Now 422 | 423 | 436 | 437 | 438 | Save 50% and never run out 439 | 440 | 441 | Turn on auto deliveries 442 | 443 | 444 | 445 | 450 | 451 | 452 | 461 | Shipping to {selectedAddress?.name} 462 | 463 | 471 | 472 | Items 473 | 474 | ₹{total} 475 | 476 | 477 | 485 | 486 | Delivery 487 | 488 | ₹0 489 | 490 | 491 | 499 | 500 | Order Total 501 | 502 | 505 | ₹{total} 506 | 507 | 508 | 509 | 510 | 519 | Pay with 520 | 521 | Pay on delivery (Cash) 522 | 523 | 524 | 535 | Place your order 536 | 537 | 538 | )} 539 | 540 | ); 541 | }; 542 | 543 | export default ConfirmationScreen; 544 | 545 | const styles = StyleSheet.create({}); 546 | -------------------------------------------------------------------------------- /screens/HomeScreen.js: -------------------------------------------------------------------------------- 1 | import { 2 | Image, 3 | Platform, 4 | Pressable, 5 | SafeAreaView, 6 | ScrollView, 7 | StyleSheet, 8 | Text, 9 | TextInput, 10 | View, 11 | } from 'react-native'; 12 | import { AntDesign } from '@expo/vector-icons'; 13 | import { Feather } from '@expo/vector-icons'; 14 | import { Ionicons } from '@expo/vector-icons'; 15 | import { Entypo } from '@expo/vector-icons'; 16 | import { MaterialIcons } from '@expo/vector-icons'; 17 | import { SliderBox } from 'react-native-image-slider-box'; 18 | import { useCallback, useContext, useEffect, useState } from 'react'; 19 | import axios from 'axios'; 20 | import ProductItem from '../components/ProductItem'; 21 | import DropDownPicker from 'react-native-dropdown-picker'; 22 | import { useNavigation } from '@react-navigation/native'; 23 | import { useSelector } from 'react-redux'; 24 | import { BottomModal, ModalContent, SlideAnimation } from 'react-native-modals'; 25 | import AsyncStorage from '@react-native-async-storage/async-storage'; 26 | import { UserType } from '../UserContext'; 27 | import jwt_decode from 'jwt-decode'; 28 | 29 | const HomeScreen = () => { 30 | const list = [ 31 | { 32 | id: '0', 33 | image: 'https://m.media-amazon.com/images/I/41EcYoIZhIL._AC_SY400_.jpg', 34 | name: 'Home', 35 | }, 36 | { 37 | id: '1', 38 | image: 39 | 'https://m.media-amazon.com/images/G/31/img20/Events/Jup21dealsgrid/blockbuster.jpg', 40 | name: 'Deals', 41 | }, 42 | { 43 | id: '3', 44 | image: 45 | 'https://images-eu.ssl-images-amazon.com/images/I/31dXEvtxidL._AC_SX368_.jpg', 46 | name: 'Electronics', 47 | }, 48 | { 49 | id: '4', 50 | image: 51 | 'https://m.media-amazon.com/images/G/31/img20/Events/Jup21dealsgrid/All_Icons_Template_1_icons_01.jpg', 52 | name: 'Mobiles', 53 | }, 54 | { 55 | id: '5', 56 | image: 57 | 'https://m.media-amazon.com/images/G/31/img20/Events/Jup21dealsgrid/music.jpg', 58 | name: 'Music', 59 | }, 60 | { 61 | id: '6', 62 | image: 'https://m.media-amazon.com/images/I/51dZ19miAbL._AC_SY350_.jpg', 63 | name: 'Fashion', 64 | }, 65 | ]; 66 | 67 | const images = [ 68 | 'https://img.etimg.com/thumb/msid-93051525,width-1070,height-580,imgsize-2243475,overlay-economictimes/photo.jpg', 69 | 'https://images-eu.ssl-images-amazon.com/images/G/31/img22/Wireless/devjyoti/PD23/Launches/Updated_ingress1242x550_3.gif', 70 | 'https://images-eu.ssl-images-amazon.com/images/G/31/img23/Books/BB/JULY/1242x550_Header-BB-Jul23.jpg', 71 | ]; 72 | 73 | const deals = [ 74 | { 75 | id: '20', 76 | title: 'OnePlus Nord CE 3 Lite 5G (Pastel Lime, 8GB RAM, 128GB Storage)', 77 | oldPrice: 25000, 78 | price: 19000, 79 | image: 80 | 'https://images-eu.ssl-images-amazon.com/images/G/31/wireless_products/ssserene/weblab_wf/xcm_banners_2022_in_bau_wireless_dec_580x800_once3l_v2_580x800_in-en.jpg', 81 | carouselImages: [ 82 | 'https://m.media-amazon.com/images/I/61QRgOgBx0L._SX679_.jpg', 83 | 'https://m.media-amazon.com/images/I/61uaJPLIdML._SX679_.jpg', 84 | 'https://m.media-amazon.com/images/I/510YZx4v3wL._SX679_.jpg', 85 | 'https://m.media-amazon.com/images/I/61J6s1tkwpL._SX679_.jpg', 86 | ], 87 | color: 'Stellar Green', 88 | size: '6 GB RAM 128GB Storage', 89 | }, 90 | { 91 | id: '30', 92 | title: 93 | 'Samsung Galaxy S20 FE 5G (Cloud Navy, 8GB RAM, 128GB Storage) with No Cost EMI & Additional Exchange Offers', 94 | oldPrice: 74000, 95 | price: 26000, 96 | image: 97 | 'https://images-eu.ssl-images-amazon.com/images/G/31/img23/Wireless/Samsung/SamsungBAU/S20FE/GW/June23/BAU-27thJune/xcm_banners_2022_in_bau_wireless_dec_s20fe-rv51_580x800_in-en.jpg', 98 | carouselImages: [ 99 | 'https://m.media-amazon.com/images/I/81vDZyJQ-4L._SY879_.jpg', 100 | 'https://m.media-amazon.com/images/I/61vN1isnThL._SX679_.jpg', 101 | 'https://m.media-amazon.com/images/I/71yzyH-ohgL._SX679_.jpg', 102 | 'https://m.media-amazon.com/images/I/61vN1isnThL._SX679_.jpg', 103 | ], 104 | color: 'Cloud Navy', 105 | size: '8 GB RAM 128GB Storage', 106 | }, 107 | { 108 | id: '40', 109 | title: 110 | 'Samsung Galaxy M14 5G (ICY Silver, 4GB, 128GB Storage) | 50MP Triple Cam | 6000 mAh Battery | 5nm Octa-Core Processor | Android 13 | Without Charger', 111 | oldPrice: 16000, 112 | price: 14000, 113 | image: 114 | 'https://images-eu.ssl-images-amazon.com/images/G/31/img23/Wireless/Samsung/CatPage/Tiles/June/xcm_banners_m14_5g_rv1_580x800_in-en.jpg', 115 | carouselImages: [ 116 | 'https://m.media-amazon.com/images/I/817WWpaFo1L._SX679_.jpg', 117 | 'https://m.media-amazon.com/images/I/81KkF-GngHL._SX679_.jpg', 118 | 'https://m.media-amazon.com/images/I/61IrdBaOhbL._SX679_.jpg', 119 | ], 120 | color: 'Icy Silver', 121 | size: '6 GB RAM 64GB Storage', 122 | }, 123 | { 124 | id: '40', 125 | title: 126 | 'realme narzo N55 (Prime Blue, 4GB+64GB) 33W Segment Fastest Charging | Super High-res 64MP Primary AI Camera', 127 | oldPrice: 12999, 128 | price: 10999, 129 | image: 130 | 'https://images-eu.ssl-images-amazon.com/images/G/31/tiyesum/N55/June/xcm_banners_2022_in_bau_wireless_dec_580x800_v1-n55-marchv2-mayv3-v4_580x800_in-en.jpg', 131 | carouselImages: [ 132 | 'https://m.media-amazon.com/images/I/41Iyj5moShL._SX300_SY300_QL70_FMwebp_.jpg', 133 | 'https://m.media-amazon.com/images/I/61og60CnGlL._SX679_.jpg', 134 | 'https://m.media-amazon.com/images/I/61twx1OjYdL._SX679_.jpg', 135 | ], 136 | }, 137 | ]; 138 | 139 | const offers = [ 140 | { 141 | id: '0', 142 | title: 143 | 'Oppo Enco Air3 Pro True Wireless in Ear Earbuds with Industry First Composite Bamboo Fiber, 49dB ANC, 30H Playtime, 47ms Ultra Low Latency,Fast Charge,BT 5.3 (Green)', 144 | offer: '72% off', 145 | oldPrice: 7500, 146 | price: 4500, 147 | image: 148 | 'https://m.media-amazon.com/images/I/61a2y1FCAJL._AC_UL640_FMwebp_QL65_.jpg', 149 | carouselImages: [ 150 | 'https://m.media-amazon.com/images/I/61a2y1FCAJL._SX679_.jpg', 151 | 'https://m.media-amazon.com/images/I/71DOcYgHWFL._SX679_.jpg', 152 | 'https://m.media-amazon.com/images/I/71LhLZGHrlL._SX679_.jpg', 153 | 'https://m.media-amazon.com/images/I/61Rgefy4ndL._SX679_.jpg', 154 | ], 155 | color: 'Green', 156 | size: 'Normal', 157 | }, 158 | { 159 | id: '1', 160 | title: 161 | 'Fastrack Limitless FS1 Pro Smart Watch|1.96 Super AMOLED Arched Display with 410x502 Pixel Resolution|SingleSync BT Calling|NitroFast Charging|110+ Sports Modes|200+ Watchfaces|Upto 7 Days Battery', 162 | offer: '40%', 163 | oldPrice: 7955, 164 | price: 3495, 165 | image: 'https://m.media-amazon.com/images/I/41mQKmbkVWL._AC_SY400_.jpg', 166 | carouselImages: [ 167 | 'https://m.media-amazon.com/images/I/71h2K2OQSIL._SX679_.jpg', 168 | 'https://m.media-amazon.com/images/I/71BlkyWYupL._SX679_.jpg', 169 | 'https://m.media-amazon.com/images/I/71c1tSIZxhL._SX679_.jpg', 170 | ], 171 | color: 'black', 172 | size: 'Normal', 173 | }, 174 | { 175 | id: '2', 176 | title: 'Aishwariya System On Ear Wireless On Ear Bluetooth Headphones', 177 | offer: '40%', 178 | oldPrice: 7955, 179 | price: 3495, 180 | image: 'https://m.media-amazon.com/images/I/41t7Wa+kxPL._AC_SY400_.jpg', 181 | carouselImages: ['https://m.media-amazon.com/images/I/41t7Wa+kxPL.jpg'], 182 | color: 'black', 183 | size: 'Normal', 184 | }, 185 | { 186 | id: '3', 187 | title: 188 | 'Fastrack Limitless FS1 Pro Smart Watch|1.96 Super AMOLED Arched Display with 410x502 Pixel Resolution|SingleSync BT Calling|NitroFast Charging|110+ Sports Modes|200+ Watchfaces|Upto 7 Days Battery', 189 | offer: '40%', 190 | oldPrice: 24999, 191 | price: 19999, 192 | image: 'https://m.media-amazon.com/images/I/71k3gOik46L._AC_SY400_.jpg', 193 | carouselImages: [ 194 | 'https://m.media-amazon.com/images/I/41bLD50sZSL._SX300_SY300_QL70_FMwebp_.jpg', 195 | 'https://m.media-amazon.com/images/I/616pTr2KJEL._SX679_.jpg', 196 | 'https://m.media-amazon.com/images/I/71wSGO0CwQL._SX679_.jpg', 197 | ], 198 | color: 'Norway Blue', 199 | size: '8GB RAM, 128GB Storage', 200 | }, 201 | ]; 202 | 203 | const [products, setProducts] = useState([]); 204 | 205 | const navigation = useNavigation(); 206 | const [addresses, setAddresses] = useState([]); 207 | const [selectedAddress, setSelectedAddress] = useState(''); 208 | const [open, setOpen] = useState(false); 209 | const [category, setCategory] = useState('jewelery'); 210 | 211 | console.log(selectedAddress); 212 | const [items, setItems] = useState([ 213 | { label: "Men's clothing", value: "men's clothing" }, 214 | { label: 'jewelery', value: 'jewelery' }, 215 | { label: 'electronics', value: 'electronics' }, 216 | { label: "women's clothing", value: "women's clothing" }, 217 | ]); 218 | 219 | useEffect(() => { 220 | const fetchData = async () => { 221 | try { 222 | const response = await axios.get('https://fakestoreapi.com/products'); 223 | setProducts(response.data); 224 | } catch (error) { 225 | console.log('error message', error); 226 | } 227 | }; 228 | fetchData(); 229 | }, []); 230 | 231 | const onGenderOpen = useCallback(() => { 232 | setCompanyOpen(false); 233 | }, []); 234 | 235 | const cart = useSelector((state) => state.cart.cart); 236 | const [modalVisible, setModalVisible] = useState(false); 237 | const { userId, setUserId } = useContext(UserType); 238 | 239 | useEffect(() => { 240 | if (userId) { 241 | fetchAddresses(); 242 | } 243 | }, [userId, modalVisible]); 244 | 245 | const fetchAddresses = async () => { 246 | try { 247 | const response = await axios.get( 248 | `http://localhost:8000/addresses/${userId}` 249 | ); 250 | const { addresses } = response.data; 251 | setAddresses(addresses); 252 | } catch (error) { 253 | console.log('Error', error); 254 | } 255 | }; 256 | 257 | useEffect(() => { 258 | const fetchUser = async () => { 259 | const token = await AsyncStorage.getItem('authToken'); 260 | const decodedToken = jwt_decode(token); 261 | const userId = decodedToken.userId; 262 | setUserId(userId); 263 | }; 264 | fetchUser(); 265 | }, []); 266 | return ( 267 | <> 268 | 275 | 276 | 284 | 296 | 302 | 303 | 304 | 305 | 306 | setModalVisible(!modalVisible)} 308 | style={{ 309 | flexDirection: 'row', 310 | alignItems: 'center', 311 | gap: 5, 312 | padding: 10, 313 | backgroundColor: '#AFEEEE', 314 | }} 315 | > 316 | 317 | 318 | {selectedAddress ? ( 319 | 320 | Deliver to {selectedAddress?.name} - {selectedAddress?.street} 321 | 322 | ) : ( 323 | 324 | Add a Address{' '} 325 | 326 | )} 327 | 328 | 329 | 330 | 331 | 332 | {list.map((item, index) => ( 333 | 341 | 345 | 353 | {item?.name} 354 | 355 | 356 | ))} 357 | 358 | 366 | 367 | 368 | Trending Deals of the week 369 | 370 | 371 | 378 | {deals.map((item, index) => ( 379 | 381 | navigation.navigate('Info', { 382 | id: item.id, 383 | title: item.title, 384 | price: item?.price, 385 | carouselImages: item.carouselImages, 386 | color: item?.color, 387 | size: item?.size, 388 | oldPrice: item?.oldPrice, 389 | item: item, 390 | }) 391 | } 392 | key={index} 393 | style={{ 394 | marginVertical: 10, 395 | flexDirection: 'row', 396 | alignItems: 'center', 397 | }} 398 | > 399 | 403 | 404 | ))} 405 | 406 | 414 | 415 | 416 | Today's Deals 417 | 418 | 419 | {offers.map((item, index) => ( 420 | 422 | navigation.navigate('Info', { 423 | id: item.id, 424 | title: item.title, 425 | price: item?.price, 426 | carouselImages: item.carouselImages, 427 | color: item?.color, 428 | size: item?.size, 429 | oldPrice: item?.oldPrice, 430 | item: item, 431 | }) 432 | } 433 | key={index} 434 | style={{ 435 | marginVertical: 10, 436 | alignItems: 'center', 437 | justifyContent: 'center', 438 | }} 439 | > 440 | 444 | 455 | 463 | Upto {item?.offer} 464 | 465 | 466 | 467 | ))} 468 | 469 | 470 | 478 | 479 | 487 | 506 | 507 | 508 | 515 | {products 516 | ?.filter((item) => item.category === category) 517 | .map((item, index) => ( 518 | 519 | ))} 520 | 521 | 522 | 523 | 524 | setModalVisible(!modalVisible)} 526 | swipeDirection={['up', 'down']} 527 | swipeThreshold={200} 528 | modalAnimation={ 529 | new SlideAnimation({ 530 | slideFrom: 'bottom', 531 | }) 532 | } 533 | onHardwareBackPress={() => setModalVisible(!modalVisible)} 534 | visible={modalVisible} 535 | onTouchOutside={() => setModalVisible(!modalVisible)} 536 | > 537 | 538 | 539 | 540 | Choose your Location 541 | 542 | 543 | 544 | Select a delivery location to see product availability and 545 | delivery options 546 | 547 | 548 | 549 | 550 | {/* already added addresses */} 551 | 552 | {addresses?.map((item, index) => ( 553 | setSelectedAddress(item)} 555 | key={index} 556 | style={{ 557 | width: 140, 558 | height: 140, 559 | borderColor: '#D0D0D0', 560 | borderWidth: 1, 561 | padding: 10, 562 | justifyContent: 'center', 563 | alignItems: 'center', 564 | gap: 3, 565 | marginRight: 15, 566 | marginTop: 10, 567 | backgroundColor: 568 | selectedAddress === item ? '#FBCEB1' : 'white', 569 | }} 570 | > 571 | 574 | 575 | {item?.name} 576 | 577 | 578 | 579 | 580 | 584 | {item?.houseNo}, {item?.landmark} 585 | 586 | 587 | 591 | {item?.street} 592 | 593 | 594 | 598 | India, Rajasthan 599 | 600 | 601 | ))} 602 | { 604 | setModalVisible(false); 605 | navigation.navigate('Address'); 606 | }} 607 | style={{ 608 | width: 140, 609 | height: 140, 610 | borderColor: '#D0D0D0', 611 | borderWidth: 1, 612 | marginTop: 10, 613 | padding: 10, 614 | justifyContent: 'center', 615 | alignItems: 'center', 616 | }} 617 | > 618 | 625 | Add an Address or pick-up point 626 | 627 | 628 | 629 | 630 | 633 | 634 | 635 | Enter an Indian Pincode 636 | 637 | 638 | 639 | 642 | 643 | 644 | Use My Current Location 645 | 646 | 647 | 650 | 651 | 652 | Deliver outside Indian 653 | 654 | 655 | 656 | 657 | 658 | 659 | ); 660 | }; 661 | 662 | export default HomeScreen; 663 | 664 | const styles = StyleSheet.create({}); 665 | -------------------------------------------------------------------------------- /api/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@types/node@*": 6 | version "20.5.7" 7 | resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.7.tgz#4b8ecac87fbefbc92f431d09c30e176fc0a7c377" 8 | integrity sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA== 9 | 10 | "@types/webidl-conversions@*": 11 | version "7.0.0" 12 | resolved "https://registry.yarnpkg.com/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz#2b8e60e33906459219aa587e9d1a612ae994cfe7" 13 | integrity sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog== 14 | 15 | "@types/whatwg-url@^8.2.1": 16 | version "8.2.2" 17 | resolved "https://registry.yarnpkg.com/@types/whatwg-url/-/whatwg-url-8.2.2.tgz#749d5b3873e845897ada99be4448041d4cc39e63" 18 | integrity sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA== 19 | dependencies: 20 | "@types/node" "*" 21 | "@types/webidl-conversions" "*" 22 | 23 | abbrev@1: 24 | version "1.1.1" 25 | resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" 26 | integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== 27 | 28 | accepts@~1.3.8: 29 | version "1.3.8" 30 | resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" 31 | integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== 32 | dependencies: 33 | mime-types "~2.1.34" 34 | negotiator "0.6.3" 35 | 36 | anymatch@~3.1.2: 37 | version "3.1.3" 38 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" 39 | integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== 40 | dependencies: 41 | normalize-path "^3.0.0" 42 | picomatch "^2.0.4" 43 | 44 | array-flatten@1.1.1: 45 | version "1.1.1" 46 | resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" 47 | integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== 48 | 49 | balanced-match@^1.0.0: 50 | version "1.0.2" 51 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 52 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 53 | 54 | binary-extensions@^2.0.0: 55 | version "2.2.0" 56 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" 57 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== 58 | 59 | body-parser@1.20.1: 60 | version "1.20.1" 61 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" 62 | integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== 63 | dependencies: 64 | bytes "3.1.2" 65 | content-type "~1.0.4" 66 | debug "2.6.9" 67 | depd "2.0.0" 68 | destroy "1.2.0" 69 | http-errors "2.0.0" 70 | iconv-lite "0.4.24" 71 | on-finished "2.4.1" 72 | qs "6.11.0" 73 | raw-body "2.5.1" 74 | type-is "~1.6.18" 75 | unpipe "1.0.0" 76 | 77 | body-parser@^1.20.2: 78 | version "1.20.2" 79 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" 80 | integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== 81 | dependencies: 82 | bytes "3.1.2" 83 | content-type "~1.0.5" 84 | debug "2.6.9" 85 | depd "2.0.0" 86 | destroy "1.2.0" 87 | http-errors "2.0.0" 88 | iconv-lite "0.4.24" 89 | on-finished "2.4.1" 90 | qs "6.11.0" 91 | raw-body "2.5.2" 92 | type-is "~1.6.18" 93 | unpipe "1.0.0" 94 | 95 | brace-expansion@^1.1.7: 96 | version "1.1.11" 97 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 98 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 99 | dependencies: 100 | balanced-match "^1.0.0" 101 | concat-map "0.0.1" 102 | 103 | braces@~3.0.2: 104 | version "3.0.2" 105 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 106 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 107 | dependencies: 108 | fill-range "^7.0.1" 109 | 110 | bson@^5.4.0: 111 | version "5.4.0" 112 | resolved "https://registry.yarnpkg.com/bson/-/bson-5.4.0.tgz#0eea77276d490953ad8616b483298dbff07384c6" 113 | integrity sha512-WRZ5SQI5GfUuKnPTNmAYPiKIof3ORXAF4IRU5UcgmivNIon01rWQlw5RUH954dpu8yGL8T59YShVddIPaU/gFA== 114 | 115 | buffer-equal-constant-time@1.0.1: 116 | version "1.0.1" 117 | resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" 118 | integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== 119 | 120 | bytes@3.1.2: 121 | version "3.1.2" 122 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" 123 | integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== 124 | 125 | call-bind@^1.0.0: 126 | version "1.0.2" 127 | resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" 128 | integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== 129 | dependencies: 130 | function-bind "^1.1.1" 131 | get-intrinsic "^1.0.2" 132 | 133 | chokidar@^3.5.2: 134 | version "3.5.3" 135 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" 136 | integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== 137 | dependencies: 138 | anymatch "~3.1.2" 139 | braces "~3.0.2" 140 | glob-parent "~5.1.2" 141 | is-binary-path "~2.1.0" 142 | is-glob "~4.0.1" 143 | normalize-path "~3.0.0" 144 | readdirp "~3.6.0" 145 | optionalDependencies: 146 | fsevents "~2.3.2" 147 | 148 | concat-map@0.0.1: 149 | version "0.0.1" 150 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 151 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== 152 | 153 | content-disposition@0.5.4: 154 | version "0.5.4" 155 | resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" 156 | integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== 157 | dependencies: 158 | safe-buffer "5.2.1" 159 | 160 | content-type@~1.0.4, content-type@~1.0.5: 161 | version "1.0.5" 162 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" 163 | integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== 164 | 165 | cookie-signature@1.0.6: 166 | version "1.0.6" 167 | resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" 168 | integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== 169 | 170 | cookie@0.5.0: 171 | version "0.5.0" 172 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" 173 | integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== 174 | 175 | cors@^2.8.5: 176 | version "2.8.5" 177 | resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" 178 | integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== 179 | dependencies: 180 | object-assign "^4" 181 | vary "^1" 182 | 183 | debug@2.6.9: 184 | version "2.6.9" 185 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 186 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== 187 | dependencies: 188 | ms "2.0.0" 189 | 190 | debug@4.x: 191 | version "4.3.4" 192 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" 193 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== 194 | dependencies: 195 | ms "2.1.2" 196 | 197 | debug@^3.2.7: 198 | version "3.2.7" 199 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" 200 | integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== 201 | dependencies: 202 | ms "^2.1.1" 203 | 204 | depd@2.0.0: 205 | version "2.0.0" 206 | resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" 207 | integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== 208 | 209 | destroy@1.2.0: 210 | version "1.2.0" 211 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" 212 | integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== 213 | 214 | dotenv@^16.3.1: 215 | version "16.3.1" 216 | resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" 217 | integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== 218 | 219 | ecdsa-sig-formatter@1.0.11: 220 | version "1.0.11" 221 | resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" 222 | integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== 223 | dependencies: 224 | safe-buffer "^5.0.1" 225 | 226 | ee-first@1.1.1: 227 | version "1.1.1" 228 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" 229 | integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== 230 | 231 | encodeurl@~1.0.2: 232 | version "1.0.2" 233 | resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" 234 | integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== 235 | 236 | escape-html@~1.0.3: 237 | version "1.0.3" 238 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" 239 | integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== 240 | 241 | etag@~1.8.1: 242 | version "1.8.1" 243 | resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" 244 | integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== 245 | 246 | express@^4.18.2: 247 | version "4.18.2" 248 | resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" 249 | integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== 250 | dependencies: 251 | accepts "~1.3.8" 252 | array-flatten "1.1.1" 253 | body-parser "1.20.1" 254 | content-disposition "0.5.4" 255 | content-type "~1.0.4" 256 | cookie "0.5.0" 257 | cookie-signature "1.0.6" 258 | debug "2.6.9" 259 | depd "2.0.0" 260 | encodeurl "~1.0.2" 261 | escape-html "~1.0.3" 262 | etag "~1.8.1" 263 | finalhandler "1.2.0" 264 | fresh "0.5.2" 265 | http-errors "2.0.0" 266 | merge-descriptors "1.0.1" 267 | methods "~1.1.2" 268 | on-finished "2.4.1" 269 | parseurl "~1.3.3" 270 | path-to-regexp "0.1.7" 271 | proxy-addr "~2.0.7" 272 | qs "6.11.0" 273 | range-parser "~1.2.1" 274 | safe-buffer "5.2.1" 275 | send "0.18.0" 276 | serve-static "1.15.0" 277 | setprototypeof "1.2.0" 278 | statuses "2.0.1" 279 | type-is "~1.6.18" 280 | utils-merge "1.0.1" 281 | vary "~1.1.2" 282 | 283 | fill-range@^7.0.1: 284 | version "7.0.1" 285 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 286 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 287 | dependencies: 288 | to-regex-range "^5.0.1" 289 | 290 | finalhandler@1.2.0: 291 | version "1.2.0" 292 | resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" 293 | integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== 294 | dependencies: 295 | debug "2.6.9" 296 | encodeurl "~1.0.2" 297 | escape-html "~1.0.3" 298 | on-finished "2.4.1" 299 | parseurl "~1.3.3" 300 | statuses "2.0.1" 301 | unpipe "~1.0.0" 302 | 303 | forwarded@0.2.0: 304 | version "0.2.0" 305 | resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" 306 | integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== 307 | 308 | fresh@0.5.2: 309 | version "0.5.2" 310 | resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" 311 | integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== 312 | 313 | fsevents@~2.3.2: 314 | version "2.3.3" 315 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" 316 | integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== 317 | 318 | function-bind@^1.1.1: 319 | version "1.1.1" 320 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" 321 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== 322 | 323 | get-intrinsic@^1.0.2: 324 | version "1.2.1" 325 | resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" 326 | integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== 327 | dependencies: 328 | function-bind "^1.1.1" 329 | has "^1.0.3" 330 | has-proto "^1.0.1" 331 | has-symbols "^1.0.3" 332 | 333 | glob-parent@~5.1.2: 334 | version "5.1.2" 335 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 336 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 337 | dependencies: 338 | is-glob "^4.0.1" 339 | 340 | has-flag@^3.0.0: 341 | version "3.0.0" 342 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 343 | integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== 344 | 345 | has-proto@^1.0.1: 346 | version "1.0.1" 347 | resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" 348 | integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== 349 | 350 | has-symbols@^1.0.3: 351 | version "1.0.3" 352 | resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" 353 | integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== 354 | 355 | has@^1.0.3: 356 | version "1.0.3" 357 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" 358 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== 359 | dependencies: 360 | function-bind "^1.1.1" 361 | 362 | http-errors@2.0.0: 363 | version "2.0.0" 364 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" 365 | integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== 366 | dependencies: 367 | depd "2.0.0" 368 | inherits "2.0.4" 369 | setprototypeof "1.2.0" 370 | statuses "2.0.1" 371 | toidentifier "1.0.1" 372 | 373 | iconv-lite@0.4.24: 374 | version "0.4.24" 375 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" 376 | integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== 377 | dependencies: 378 | safer-buffer ">= 2.1.2 < 3" 379 | 380 | ignore-by-default@^1.0.1: 381 | version "1.0.1" 382 | resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" 383 | integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== 384 | 385 | inherits@2.0.4: 386 | version "2.0.4" 387 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 388 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 389 | 390 | ip@^2.0.0: 391 | version "2.0.0" 392 | resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" 393 | integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== 394 | 395 | ipaddr.js@1.9.1: 396 | version "1.9.1" 397 | resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" 398 | integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== 399 | 400 | is-binary-path@~2.1.0: 401 | version "2.1.0" 402 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" 403 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 404 | dependencies: 405 | binary-extensions "^2.0.0" 406 | 407 | is-extglob@^2.1.1: 408 | version "2.1.1" 409 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 410 | integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== 411 | 412 | is-glob@^4.0.1, is-glob@~4.0.1: 413 | version "4.0.3" 414 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" 415 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 416 | dependencies: 417 | is-extglob "^2.1.1" 418 | 419 | is-number@^7.0.0: 420 | version "7.0.0" 421 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 422 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 423 | 424 | jsonwebtoken@^9.0.1: 425 | version "9.0.1" 426 | resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.1.tgz#81d8c901c112c24e497a55daf6b2be1225b40145" 427 | integrity sha512-K8wx7eJ5TPvEjuiVSkv167EVboBDv9PZdDoF7BgeQnBLVvZWW9clr2PsQHVJDTKaEIH5JBIwHujGcHp7GgI2eg== 428 | dependencies: 429 | jws "^3.2.2" 430 | lodash "^4.17.21" 431 | ms "^2.1.1" 432 | semver "^7.3.8" 433 | 434 | jwa@^1.4.1: 435 | version "1.4.1" 436 | resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" 437 | integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== 438 | dependencies: 439 | buffer-equal-constant-time "1.0.1" 440 | ecdsa-sig-formatter "1.0.11" 441 | safe-buffer "^5.0.1" 442 | 443 | jws@^3.2.2: 444 | version "3.2.2" 445 | resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" 446 | integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== 447 | dependencies: 448 | jwa "^1.4.1" 449 | safe-buffer "^5.0.1" 450 | 451 | kareem@2.5.1: 452 | version "2.5.1" 453 | resolved "https://registry.yarnpkg.com/kareem/-/kareem-2.5.1.tgz#7b8203e11819a8e77a34b3517d3ead206764d15d" 454 | integrity sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA== 455 | 456 | lodash@^4.17.21: 457 | version "4.17.21" 458 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" 459 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== 460 | 461 | lru-cache@^6.0.0: 462 | version "6.0.0" 463 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" 464 | integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== 465 | dependencies: 466 | yallist "^4.0.0" 467 | 468 | media-typer@0.3.0: 469 | version "0.3.0" 470 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" 471 | integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== 472 | 473 | memory-pager@^1.0.2: 474 | version "1.5.0" 475 | resolved "https://registry.yarnpkg.com/memory-pager/-/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5" 476 | integrity sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg== 477 | 478 | merge-descriptors@1.0.1: 479 | version "1.0.1" 480 | resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" 481 | integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== 482 | 483 | methods@~1.1.2: 484 | version "1.1.2" 485 | resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" 486 | integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== 487 | 488 | mime-db@1.52.0: 489 | version "1.52.0" 490 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" 491 | integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== 492 | 493 | mime-types@~2.1.24, mime-types@~2.1.34: 494 | version "2.1.35" 495 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" 496 | integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== 497 | dependencies: 498 | mime-db "1.52.0" 499 | 500 | mime@1.6.0: 501 | version "1.6.0" 502 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" 503 | integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== 504 | 505 | minimatch@^3.1.2: 506 | version "3.1.2" 507 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" 508 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 509 | dependencies: 510 | brace-expansion "^1.1.7" 511 | 512 | mongodb-connection-string-url@^2.6.0: 513 | version "2.6.0" 514 | resolved "https://registry.yarnpkg.com/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz#57901bf352372abdde812c81be47b75c6b2ec5cf" 515 | integrity sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ== 516 | dependencies: 517 | "@types/whatwg-url" "^8.2.1" 518 | whatwg-url "^11.0.0" 519 | 520 | mongodb@5.7.0: 521 | version "5.7.0" 522 | resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-5.7.0.tgz#e16d2fcdfd9f8503ec2d88288392dc3235bb3ecc" 523 | integrity sha512-zm82Bq33QbqtxDf58fLWBwTjARK3NSvKYjyz997KSy6hpat0prjeX/kxjbPVyZY60XYPDNETaHkHJI2UCzSLuw== 524 | dependencies: 525 | bson "^5.4.0" 526 | mongodb-connection-string-url "^2.6.0" 527 | socks "^2.7.1" 528 | optionalDependencies: 529 | saslprep "^1.0.3" 530 | 531 | mongoose@^7.4.5: 532 | version "7.4.5" 533 | resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-7.4.5.tgz#7c843c6e3e8dcd22b0ff0f0981aca69b863e7723" 534 | integrity sha512-X7Mw7KHUYZmyOQmlu7D9TnZh/3vOrAYmZwEpXDU0VDvLPKT0T7PF6blwiv3aXOEMwv9T3rLTC9lJb3C5dWld2A== 535 | dependencies: 536 | bson "^5.4.0" 537 | kareem "2.5.1" 538 | mongodb "5.7.0" 539 | mpath "0.9.0" 540 | mquery "5.0.0" 541 | ms "2.1.3" 542 | sift "16.0.1" 543 | 544 | mpath@0.9.0: 545 | version "0.9.0" 546 | resolved "https://registry.yarnpkg.com/mpath/-/mpath-0.9.0.tgz#0c122fe107846e31fc58c75b09c35514b3871904" 547 | integrity sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew== 548 | 549 | mquery@5.0.0: 550 | version "5.0.0" 551 | resolved "https://registry.yarnpkg.com/mquery/-/mquery-5.0.0.tgz#a95be5dfc610b23862df34a47d3e5d60e110695d" 552 | integrity sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg== 553 | dependencies: 554 | debug "4.x" 555 | 556 | ms@2.0.0: 557 | version "2.0.0" 558 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 559 | integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== 560 | 561 | ms@2.1.2: 562 | version "2.1.2" 563 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 564 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 565 | 566 | ms@2.1.3, ms@^2.1.1: 567 | version "2.1.3" 568 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" 569 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 570 | 571 | negotiator@0.6.3: 572 | version "0.6.3" 573 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" 574 | integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== 575 | 576 | nodemailer@^6.9.4: 577 | version "6.9.4" 578 | resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.9.4.tgz#93bd4a60eb0be6fa088a0483340551ebabfd2abf" 579 | integrity sha512-CXjQvrQZV4+6X5wP6ZIgdehJamI63MFoYFGGPtHudWym9qaEHDNdPzaj5bfMCvxG1vhAileSWW90q7nL0N36mA== 580 | 581 | nodemon@^3.0.1: 582 | version "3.0.1" 583 | resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-3.0.1.tgz#affe822a2c5f21354466b2fc8ae83277d27dadc7" 584 | integrity sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw== 585 | dependencies: 586 | chokidar "^3.5.2" 587 | debug "^3.2.7" 588 | ignore-by-default "^1.0.1" 589 | minimatch "^3.1.2" 590 | pstree.remy "^1.1.8" 591 | semver "^7.5.3" 592 | simple-update-notifier "^2.0.0" 593 | supports-color "^5.5.0" 594 | touch "^3.1.0" 595 | undefsafe "^2.0.5" 596 | 597 | nopt@~1.0.10: 598 | version "1.0.10" 599 | resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" 600 | integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg== 601 | dependencies: 602 | abbrev "1" 603 | 604 | normalize-path@^3.0.0, normalize-path@~3.0.0: 605 | version "3.0.0" 606 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 607 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 608 | 609 | object-assign@^4: 610 | version "4.1.1" 611 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 612 | integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== 613 | 614 | object-inspect@^1.9.0: 615 | version "1.12.3" 616 | resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" 617 | integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== 618 | 619 | on-finished@2.4.1: 620 | version "2.4.1" 621 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" 622 | integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== 623 | dependencies: 624 | ee-first "1.1.1" 625 | 626 | parseurl@~1.3.3: 627 | version "1.3.3" 628 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" 629 | integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== 630 | 631 | path-to-regexp@0.1.7: 632 | version "0.1.7" 633 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" 634 | integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== 635 | 636 | picomatch@^2.0.4, picomatch@^2.2.1: 637 | version "2.3.1" 638 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" 639 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 640 | 641 | proxy-addr@~2.0.7: 642 | version "2.0.7" 643 | resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" 644 | integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== 645 | dependencies: 646 | forwarded "0.2.0" 647 | ipaddr.js "1.9.1" 648 | 649 | pstree.remy@^1.1.8: 650 | version "1.1.8" 651 | resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" 652 | integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== 653 | 654 | punycode@^2.1.1: 655 | version "2.3.0" 656 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" 657 | integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== 658 | 659 | qs@6.11.0: 660 | version "6.11.0" 661 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" 662 | integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== 663 | dependencies: 664 | side-channel "^1.0.4" 665 | 666 | range-parser@~1.2.1: 667 | version "1.2.1" 668 | resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" 669 | integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== 670 | 671 | raw-body@2.5.1: 672 | version "2.5.1" 673 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" 674 | integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== 675 | dependencies: 676 | bytes "3.1.2" 677 | http-errors "2.0.0" 678 | iconv-lite "0.4.24" 679 | unpipe "1.0.0" 680 | 681 | raw-body@2.5.2: 682 | version "2.5.2" 683 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" 684 | integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== 685 | dependencies: 686 | bytes "3.1.2" 687 | http-errors "2.0.0" 688 | iconv-lite "0.4.24" 689 | unpipe "1.0.0" 690 | 691 | readdirp@~3.6.0: 692 | version "3.6.0" 693 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" 694 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== 695 | dependencies: 696 | picomatch "^2.2.1" 697 | 698 | safe-buffer@5.2.1, safe-buffer@^5.0.1: 699 | version "5.2.1" 700 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 701 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 702 | 703 | "safer-buffer@>= 2.1.2 < 3": 704 | version "2.1.2" 705 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 706 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 707 | 708 | saslprep@^1.0.3: 709 | version "1.0.3" 710 | resolved "https://registry.yarnpkg.com/saslprep/-/saslprep-1.0.3.tgz#4c02f946b56cf54297e347ba1093e7acac4cf226" 711 | integrity sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag== 712 | dependencies: 713 | sparse-bitfield "^3.0.3" 714 | 715 | semver@^7.3.8, semver@^7.5.3: 716 | version "7.5.4" 717 | resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" 718 | integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== 719 | dependencies: 720 | lru-cache "^6.0.0" 721 | 722 | send@0.18.0: 723 | version "0.18.0" 724 | resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" 725 | integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== 726 | dependencies: 727 | debug "2.6.9" 728 | depd "2.0.0" 729 | destroy "1.2.0" 730 | encodeurl "~1.0.2" 731 | escape-html "~1.0.3" 732 | etag "~1.8.1" 733 | fresh "0.5.2" 734 | http-errors "2.0.0" 735 | mime "1.6.0" 736 | ms "2.1.3" 737 | on-finished "2.4.1" 738 | range-parser "~1.2.1" 739 | statuses "2.0.1" 740 | 741 | serve-static@1.15.0: 742 | version "1.15.0" 743 | resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" 744 | integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== 745 | dependencies: 746 | encodeurl "~1.0.2" 747 | escape-html "~1.0.3" 748 | parseurl "~1.3.3" 749 | send "0.18.0" 750 | 751 | setprototypeof@1.2.0: 752 | version "1.2.0" 753 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" 754 | integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== 755 | 756 | side-channel@^1.0.4: 757 | version "1.0.4" 758 | resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" 759 | integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== 760 | dependencies: 761 | call-bind "^1.0.0" 762 | get-intrinsic "^1.0.2" 763 | object-inspect "^1.9.0" 764 | 765 | sift@16.0.1: 766 | version "16.0.1" 767 | resolved "https://registry.yarnpkg.com/sift/-/sift-16.0.1.tgz#e9c2ccc72191585008cf3e36fc447b2d2633a053" 768 | integrity sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ== 769 | 770 | simple-update-notifier@^2.0.0: 771 | version "2.0.0" 772 | resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz#d70b92bdab7d6d90dfd73931195a30b6e3d7cebb" 773 | integrity sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w== 774 | dependencies: 775 | semver "^7.5.3" 776 | 777 | smart-buffer@^4.2.0: 778 | version "4.2.0" 779 | resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" 780 | integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== 781 | 782 | socks@^2.7.1: 783 | version "2.7.1" 784 | resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" 785 | integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== 786 | dependencies: 787 | ip "^2.0.0" 788 | smart-buffer "^4.2.0" 789 | 790 | sparse-bitfield@^3.0.3: 791 | version "3.0.3" 792 | resolved "https://registry.yarnpkg.com/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz#ff4ae6e68656056ba4b3e792ab3334d38273ca11" 793 | integrity sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ== 794 | dependencies: 795 | memory-pager "^1.0.2" 796 | 797 | statuses@2.0.1: 798 | version "2.0.1" 799 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" 800 | integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== 801 | 802 | supports-color@^5.5.0: 803 | version "5.5.0" 804 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 805 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 806 | dependencies: 807 | has-flag "^3.0.0" 808 | 809 | to-regex-range@^5.0.1: 810 | version "5.0.1" 811 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 812 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 813 | dependencies: 814 | is-number "^7.0.0" 815 | 816 | toidentifier@1.0.1: 817 | version "1.0.1" 818 | resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" 819 | integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== 820 | 821 | touch@^3.1.0: 822 | version "3.1.0" 823 | resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" 824 | integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== 825 | dependencies: 826 | nopt "~1.0.10" 827 | 828 | tr46@^3.0.0: 829 | version "3.0.0" 830 | resolved "https://registry.yarnpkg.com/tr46/-/tr46-3.0.0.tgz#555c4e297a950617e8eeddef633c87d4d9d6cbf9" 831 | integrity sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA== 832 | dependencies: 833 | punycode "^2.1.1" 834 | 835 | type-is@~1.6.18: 836 | version "1.6.18" 837 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" 838 | integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== 839 | dependencies: 840 | media-typer "0.3.0" 841 | mime-types "~2.1.24" 842 | 843 | undefsafe@^2.0.5: 844 | version "2.0.5" 845 | resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" 846 | integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== 847 | 848 | unpipe@1.0.0, unpipe@~1.0.0: 849 | version "1.0.0" 850 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" 851 | integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== 852 | 853 | utils-merge@1.0.1: 854 | version "1.0.1" 855 | resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" 856 | integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== 857 | 858 | vary@^1, vary@~1.1.2: 859 | version "1.1.2" 860 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" 861 | integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== 862 | 863 | webidl-conversions@^7.0.0: 864 | version "7.0.0" 865 | resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" 866 | integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== 867 | 868 | whatwg-url@^11.0.0: 869 | version "11.0.0" 870 | resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-11.0.0.tgz#0a849eebb5faf2119b901bb76fd795c2848d4018" 871 | integrity sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ== 872 | dependencies: 873 | tr46 "^3.0.0" 874 | webidl-conversions "^7.0.0" 875 | 876 | yallist@^4.0.0: 877 | version "4.0.0" 878 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" 879 | integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== 880 | -------------------------------------------------------------------------------- /assets/sparkle.json: -------------------------------------------------------------------------------- 1 | { 2 | "v": "5.6.2", 3 | "fr": 29.9700012207031, 4 | "ip": 0, 5 | "op": 41.0000016699642, 6 | "w": 400, 7 | "h": 400, 8 | "nm": "Particle Fireworks", 9 | "ddd": 0, 10 | "assets": [ 11 | { 12 | "id": "comp_0", 13 | "layers": [ 14 | { 15 | "ddd": 0, 16 | "ind": 1, 17 | "ty": 4, 18 | "nm": "Shape Layer 1", 19 | "sr": 1, 20 | "ks": { 21 | "o": { "a": 0, "k": 100, "ix": 11 }, 22 | "r": { "a": 0, "k": 0, "ix": 10 }, 23 | "p": { "a": 0, "k": [100.011, 99.792, 0], "ix": 2 }, 24 | "a": { "a": 0, "k": [-9.739, -21.058, 0], "ix": 1 }, 25 | "s": { "a": 0, "k": [65, 65, 100], "ix": 6 } 26 | }, 27 | "ao": 0, 28 | "shapes": [ 29 | { 30 | "ty": "gr", 31 | "it": [ 32 | { 33 | "ind": 0, 34 | "ty": "sh", 35 | "ix": 1, 36 | "ks": { 37 | "a": 0, 38 | "k": { 39 | "i": [ 40 | [0, 0], 41 | [0, 0], 42 | [0, 0] 43 | ], 44 | "o": [ 45 | [0, 0], 46 | [0, 0], 47 | [0, 0] 48 | ], 49 | "v": [ 50 | [2.261, -38.5], 51 | [30.022, 9.584], 52 | [-25.5, 9.584] 53 | ], 54 | "c": true 55 | }, 56 | "ix": 2 57 | }, 58 | "nm": "Path 1", 59 | "mn": "ADBE Vector Shape - Group", 60 | "hd": false 61 | }, 62 | { 63 | "ty": "st", 64 | "c": { 65 | "a": 0, 66 | "k": [0.124443884457, 0.064498265584, 0.913725490196, 1], 67 | "ix": 3 68 | }, 69 | "o": { "a": 0, "k": 100, "ix": 4 }, 70 | "w": { "a": 0, "k": 10, "ix": 5 }, 71 | "lc": 1, 72 | "lj": 1, 73 | "ml": 4, 74 | "bm": 0, 75 | "nm": "Stroke 1", 76 | "mn": "ADBE Vector Graphic - Stroke", 77 | "hd": false 78 | }, 79 | { 80 | "ty": "tr", 81 | "p": { "a": 0, "k": [-12, -14], "ix": 2 }, 82 | "a": { "a": 0, "k": [0, 0], "ix": 1 }, 83 | "s": { "a": 0, "k": [100, 100], "ix": 3 }, 84 | "r": { "a": 0, "k": 0, "ix": 6 }, 85 | "o": { "a": 0, "k": 100, "ix": 7 }, 86 | "sk": { "a": 0, "k": 0, "ix": 4 }, 87 | "sa": { "a": 0, "k": 0, "ix": 5 }, 88 | "nm": "Transform" 89 | } 90 | ], 91 | "nm": "Polystar 1", 92 | "np": 3, 93 | "cix": 2, 94 | "bm": 0, 95 | "ix": 1, 96 | "mn": "ADBE Vector Group", 97 | "hd": false 98 | } 99 | ], 100 | "ip": 0, 101 | "op": 152.000006191087, 102 | "st": 0, 103 | "bm": 0 104 | } 105 | ] 106 | }, 107 | { 108 | "id": "comp_1", 109 | "layers": [ 110 | { 111 | "ddd": 0, 112 | "ind": 1, 113 | "ty": 4, 114 | "nm": "Shape Layer 2", 115 | "sr": 1, 116 | "ks": { 117 | "o": { "a": 0, "k": 100, "ix": 11 }, 118 | "r": { "a": 0, "k": 0, "ix": 10 }, 119 | "p": { "a": 0, "k": [99.938, 99.937, 0], "ix": 2 }, 120 | "a": { "a": 0, "k": [91.25, -27.75, 0], "ix": 1 }, 121 | "s": { "a": 0, "k": [65, 65, 100], "ix": 6 } 122 | }, 123 | "ao": 0, 124 | "shapes": [ 125 | { 126 | "ty": "gr", 127 | "it": [ 128 | { 129 | "d": 1, 130 | "ty": "el", 131 | "s": { "a": 0, "k": [51.7, 51.7], "ix": 2 }, 132 | "p": { "a": 0, "k": [0, 0], "ix": 3 }, 133 | "nm": "Ellipse Path 1", 134 | "mn": "ADBE Vector Shape - Ellipse", 135 | "hd": false 136 | }, 137 | { 138 | "ty": "st", 139 | "c": { 140 | "a": 0, 141 | "k": [0.609390258789, 0.10614378686, 0.796078431373, 1], 142 | "ix": 3 143 | }, 144 | "o": { "a": 0, "k": 100, "ix": 4 }, 145 | "w": { "a": 0, "k": 10, "ix": 5 }, 146 | "lc": 1, 147 | "lj": 1, 148 | "ml": 4, 149 | "bm": 0, 150 | "nm": "Stroke 1", 151 | "mn": "ADBE Vector Graphic - Stroke", 152 | "hd": false 153 | }, 154 | { 155 | "ty": "tr", 156 | "p": { "a": 0, "k": [91.25, -27.75], "ix": 2 }, 157 | "a": { "a": 0, "k": [0, 0], "ix": 1 }, 158 | "s": { "a": 0, "k": [100, 100], "ix": 3 }, 159 | "r": { "a": 0, "k": 0, "ix": 6 }, 160 | "o": { "a": 0, "k": 100, "ix": 7 }, 161 | "sk": { "a": 0, "k": 0, "ix": 4 }, 162 | "sa": { "a": 0, "k": 0, "ix": 5 }, 163 | "nm": "Transform" 164 | } 165 | ], 166 | "nm": "Ellipse 1", 167 | "np": 3, 168 | "cix": 2, 169 | "bm": 0, 170 | "ix": 1, 171 | "mn": "ADBE Vector Group", 172 | "hd": false 173 | } 174 | ], 175 | "ip": 0, 176 | "op": 152.000006191087, 177 | "st": 0, 178 | "bm": 0 179 | } 180 | ] 181 | }, 182 | { 183 | "id": "comp_2", 184 | "layers": [ 185 | { 186 | "ddd": 0, 187 | "ind": 1, 188 | "ty": 4, 189 | "nm": "Shape Layer 3", 190 | "sr": 1, 191 | "ks": { 192 | "o": { "a": 0, "k": 100, "ix": 11 }, 193 | "r": { "a": 0, "k": 0, "ix": 10 }, 194 | "p": { "a": 0, "k": [100.062, 99.875, 0], "ix": 2 }, 195 | "a": { "a": 0, "k": [156, -27.5, 0], "ix": 1 }, 196 | "s": { "a": 0, "k": [65, 65, 100], "ix": 6 } 197 | }, 198 | "ao": 0, 199 | "shapes": [ 200 | { 201 | "ty": "gr", 202 | "it": [ 203 | { 204 | "ty": "rc", 205 | "d": 1, 206 | "s": { "a": 0, "k": [50, 50], "ix": 2 }, 207 | "p": { "a": 0, "k": [0, 0], "ix": 3 }, 208 | "r": { "a": 0, "k": 0, "ix": 4 }, 209 | "nm": "Rectangle Path 1", 210 | "mn": "ADBE Vector Shape - Rect", 211 | "hd": false 212 | }, 213 | { 214 | "ty": "st", 215 | "c": { 216 | "a": 0, 217 | "k": [0.835294117647, 0.680682911592, 0.062237597447, 1], 218 | "ix": 3 219 | }, 220 | "o": { "a": 0, "k": 100, "ix": 4 }, 221 | "w": { "a": 0, "k": 10, "ix": 5 }, 222 | "lc": 1, 223 | "lj": 1, 224 | "ml": 4, 225 | "bm": 0, 226 | "nm": "Stroke 1", 227 | "mn": "ADBE Vector Graphic - Stroke", 228 | "hd": false 229 | }, 230 | { 231 | "ty": "tr", 232 | "p": { "a": 0, "k": [156, -27.5], "ix": 2 }, 233 | "a": { "a": 0, "k": [0, 0], "ix": 1 }, 234 | "s": { "a": 0, "k": [100, 100], "ix": 3 }, 235 | "r": { "a": 0, "k": 0, "ix": 6 }, 236 | "o": { "a": 0, "k": 100, "ix": 7 }, 237 | "sk": { "a": 0, "k": 0, "ix": 4 }, 238 | "sa": { "a": 0, "k": 0, "ix": 5 }, 239 | "nm": "Transform" 240 | } 241 | ], 242 | "nm": "Rectangle 1", 243 | "np": 3, 244 | "cix": 2, 245 | "bm": 0, 246 | "ix": 1, 247 | "mn": "ADBE Vector Group", 248 | "hd": false 249 | } 250 | ], 251 | "ip": 0, 252 | "op": 152.000006191087, 253 | "st": 0, 254 | "bm": 0 255 | } 256 | ] 257 | }, 258 | { 259 | "id": "comp_3", 260 | "layers": [ 261 | { 262 | "ddd": 0, 263 | "ind": 1, 264 | "ty": 4, 265 | "nm": "Shape Layer 4", 266 | "sr": 1, 267 | "ks": { 268 | "o": { "a": 0, "k": 100, "ix": 11 }, 269 | "r": { "a": 0, "k": 0, "ix": 10 }, 270 | "p": { "a": 0, "k": [100.028, 99.92, 0], "ix": 2 }, 271 | "a": { "a": 0, "k": [148.5, -27.5, 0], "ix": 1 }, 272 | "s": { "a": 0, "k": [75, 75, 100], "ix": 6 } 273 | }, 274 | "ao": 0, 275 | "shapes": [ 276 | { 277 | "ty": "gr", 278 | "it": [ 279 | { 280 | "ty": "rc", 281 | "d": 1, 282 | "s": { "a": 0, "k": [12, 60], "ix": 2 }, 283 | "p": { "a": 0, "k": [0, 0], "ix": 3 }, 284 | "r": { "a": 0, "k": 0, "ix": 4 }, 285 | "nm": "Rectangle Path 1", 286 | "mn": "ADBE Vector Shape - Rect", 287 | "hd": false 288 | }, 289 | { 290 | "ty": "fl", 291 | "c": { 292 | "a": 0, 293 | "k": [0.054640519385, 0.819607843137, 0.486622081083, 1], 294 | "ix": 4 295 | }, 296 | "o": { "a": 0, "k": 100, "ix": 5 }, 297 | "r": 1, 298 | "bm": 0, 299 | "nm": "Fill 1", 300 | "mn": "ADBE Vector Graphic - Fill", 301 | "hd": false 302 | }, 303 | { 304 | "ty": "tr", 305 | "p": { "a": 0, "k": [148.5, -27.5], "ix": 2 }, 306 | "a": { "a": 0, "k": [0, 0], "ix": 1 }, 307 | "s": { "a": 0, "k": [100, 100], "ix": 3 }, 308 | "r": { "a": 0, "k": 0, "ix": 6 }, 309 | "o": { "a": 0, "k": 100, "ix": 7 }, 310 | "sk": { "a": 0, "k": 0, "ix": 4 }, 311 | "sa": { "a": 0, "k": 0, "ix": 5 }, 312 | "nm": "Transform" 313 | } 314 | ], 315 | "nm": "Rectangle 2", 316 | "np": 3, 317 | "cix": 2, 318 | "bm": 0, 319 | "ix": 1, 320 | "mn": "ADBE Vector Group", 321 | "hd": false 322 | }, 323 | { 324 | "ty": "gr", 325 | "it": [ 326 | { 327 | "ty": "rc", 328 | "d": 1, 329 | "s": { "a": 0, "k": [12, 60], "ix": 2 }, 330 | "p": { "a": 0, "k": [0, 0], "ix": 3 }, 331 | "r": { "a": 0, "k": 0, "ix": 4 }, 332 | "nm": "Rectangle Path 1", 333 | "mn": "ADBE Vector Shape - Rect", 334 | "hd": false 335 | }, 336 | { 337 | "ty": "fl", 338 | "c": { 339 | "a": 0, 340 | "k": [0.054640519385, 0.819607843137, 0.486622081083, 1], 341 | "ix": 4 342 | }, 343 | "o": { "a": 0, "k": 100, "ix": 5 }, 344 | "r": 1, 345 | "bm": 0, 346 | "nm": "Fill 1", 347 | "mn": "ADBE Vector Graphic - Fill", 348 | "hd": false 349 | }, 350 | { 351 | "ty": "tr", 352 | "p": { "a": 0, "k": [148.5, -27.5], "ix": 2 }, 353 | "a": { "a": 0, "k": [0, 0], "ix": 1 }, 354 | "s": { "a": 0, "k": [100, 100], "ix": 3 }, 355 | "r": { "a": 0, "k": 90, "ix": 6 }, 356 | "o": { "a": 0, "k": 100, "ix": 7 }, 357 | "sk": { "a": 0, "k": 0, "ix": 4 }, 358 | "sa": { "a": 0, "k": 0, "ix": 5 }, 359 | "nm": "Transform" 360 | } 361 | ], 362 | "nm": "Rectangle 1", 363 | "np": 3, 364 | "cix": 2, 365 | "bm": 0, 366 | "ix": 2, 367 | "mn": "ADBE Vector Group", 368 | "hd": false 369 | } 370 | ], 371 | "ip": 0, 372 | "op": 152.000006191087, 373 | "st": 0, 374 | "bm": 0 375 | } 376 | ] 377 | }, 378 | { 379 | "id": "comp_4", 380 | "layers": [ 381 | { 382 | "ddd": 0, 383 | "ind": 1, 384 | "ty": 4, 385 | "nm": "Shape Layer 1", 386 | "sr": 1, 387 | "ks": { 388 | "o": { "a": 0, "k": 100, "ix": 11 }, 389 | "r": { "a": 0, "k": 0, "ix": 10 }, 390 | "p": { "a": 0, "k": [100.011, 99.792, 0], "ix": 2 }, 391 | "a": { "a": 0, "k": [-9.739, -21.058, 0], "ix": 1 }, 392 | "s": { "a": 0, "k": [65, 65, 100], "ix": 6 } 393 | }, 394 | "ao": 0, 395 | "shapes": [ 396 | { 397 | "ty": "gr", 398 | "it": [ 399 | { 400 | "ind": 0, 401 | "ty": "sh", 402 | "ix": 1, 403 | "ks": { 404 | "a": 0, 405 | "k": { 406 | "i": [ 407 | [0, 0], 408 | [0, 0], 409 | [0, 0] 410 | ], 411 | "o": [ 412 | [0, 0], 413 | [0, 0], 414 | [0, 0] 415 | ], 416 | "v": [ 417 | [2.261, -38.5], 418 | [30.022, 9.584], 419 | [-25.5, 9.584] 420 | ], 421 | "c": true 422 | }, 423 | "ix": 2 424 | }, 425 | "nm": "Path 1", 426 | "mn": "ADBE Vector Shape - Group", 427 | "hd": false 428 | }, 429 | { 430 | "ty": "st", 431 | "c": { 432 | "a": 0, 433 | "k": [0.23617627013, 0.095271046956, 0.694117647059, 1], 434 | "ix": 3 435 | }, 436 | "o": { "a": 0, "k": 100, "ix": 4 }, 437 | "w": { "a": 0, "k": 10, "ix": 5 }, 438 | "lc": 1, 439 | "lj": 1, 440 | "ml": 4, 441 | "bm": 0, 442 | "nm": "Stroke 1", 443 | "mn": "ADBE Vector Graphic - Stroke", 444 | "hd": false 445 | }, 446 | { 447 | "ty": "tr", 448 | "p": { "a": 0, "k": [-12, -14], "ix": 2 }, 449 | "a": { "a": 0, "k": [0, 0], "ix": 1 }, 450 | "s": { "a": 0, "k": [100, 100], "ix": 3 }, 451 | "r": { "a": 0, "k": 0, "ix": 6 }, 452 | "o": { "a": 0, "k": 100, "ix": 7 }, 453 | "sk": { "a": 0, "k": 0, "ix": 4 }, 454 | "sa": { "a": 0, "k": 0, "ix": 5 }, 455 | "nm": "Transform" 456 | } 457 | ], 458 | "nm": "Polystar 1", 459 | "np": 3, 460 | "cix": 2, 461 | "bm": 0, 462 | "ix": 1, 463 | "mn": "ADBE Vector Group", 464 | "hd": false 465 | } 466 | ], 467 | "ip": 0, 468 | "op": 152.000006191087, 469 | "st": 0, 470 | "bm": 0 471 | } 472 | ] 473 | }, 474 | { 475 | "id": "comp_5", 476 | "layers": [ 477 | { 478 | "ddd": 0, 479 | "ind": 1, 480 | "ty": 4, 481 | "nm": "Shape Layer 2", 482 | "sr": 1, 483 | "ks": { 484 | "o": { "a": 0, "k": 100, "ix": 11 }, 485 | "r": { "a": 0, "k": 0, "ix": 10 }, 486 | "p": { "a": 0, "k": [99.938, 99.937, 0], "ix": 2 }, 487 | "a": { "a": 0, "k": [91.25, -27.75, 0], "ix": 1 }, 488 | "s": { "a": 0, "k": [65, 65, 100], "ix": 6 } 489 | }, 490 | "ao": 0, 491 | "shapes": [ 492 | { 493 | "ty": "gr", 494 | "it": [ 495 | { 496 | "d": 1, 497 | "ty": "el", 498 | "s": { "a": 0, "k": [51.7, 51.7], "ix": 2 }, 499 | "p": { "a": 0, "k": [0, 0], "ix": 3 }, 500 | "nm": "Ellipse Path 1", 501 | "mn": "ADBE Vector Shape - Ellipse", 502 | "hd": false 503 | }, 504 | { 505 | "ty": "st", 506 | "c": { 507 | "a": 0, 508 | "k": [0.886274509804, 0.093840819714, 0.336232233982, 1], 509 | "ix": 3 510 | }, 511 | "o": { "a": 0, "k": 100, "ix": 4 }, 512 | "w": { "a": 0, "k": 10, "ix": 5 }, 513 | "lc": 1, 514 | "lj": 1, 515 | "ml": 4, 516 | "bm": 0, 517 | "nm": "Stroke 1", 518 | "mn": "ADBE Vector Graphic - Stroke", 519 | "hd": false 520 | }, 521 | { 522 | "ty": "tr", 523 | "p": { "a": 0, "k": [91.25, -27.75], "ix": 2 }, 524 | "a": { "a": 0, "k": [0, 0], "ix": 1 }, 525 | "s": { "a": 0, "k": [100, 100], "ix": 3 }, 526 | "r": { "a": 0, "k": 0, "ix": 6 }, 527 | "o": { "a": 0, "k": 100, "ix": 7 }, 528 | "sk": { "a": 0, "k": 0, "ix": 4 }, 529 | "sa": { "a": 0, "k": 0, "ix": 5 }, 530 | "nm": "Transform" 531 | } 532 | ], 533 | "nm": "Ellipse 1", 534 | "np": 3, 535 | "cix": 2, 536 | "bm": 0, 537 | "ix": 1, 538 | "mn": "ADBE Vector Group", 539 | "hd": false 540 | } 541 | ], 542 | "ip": 0, 543 | "op": 152.000006191087, 544 | "st": 0, 545 | "bm": 0 546 | } 547 | ] 548 | }, 549 | { 550 | "id": "comp_6", 551 | "layers": [ 552 | { 553 | "ddd": 0, 554 | "ind": 1, 555 | "ty": 4, 556 | "nm": "Shape Layer 4", 557 | "sr": 1, 558 | "ks": { 559 | "o": { "a": 0, "k": 100, "ix": 11 }, 560 | "r": { "a": 0, "k": 0, "ix": 10 }, 561 | "p": { "a": 0, "k": [100.028, 99.92, 0], "ix": 2 }, 562 | "a": { "a": 0, "k": [148.5, -27.5, 0], "ix": 1 }, 563 | "s": { "a": 0, "k": [75, 75, 100], "ix": 6 } 564 | }, 565 | "ao": 0, 566 | "shapes": [ 567 | { 568 | "ty": "gr", 569 | "it": [ 570 | { 571 | "ty": "rc", 572 | "d": 1, 573 | "s": { "a": 0, "k": [12, 60], "ix": 2 }, 574 | "p": { "a": 0, "k": [0, 0], "ix": 3 }, 575 | "r": { "a": 0, "k": 0, "ix": 4 }, 576 | "nm": "Rectangle Path 1", 577 | "mn": "ADBE Vector Shape - Rect", 578 | "hd": false 579 | }, 580 | { 581 | "ty": "fl", 582 | "c": { 583 | "a": 0, 584 | "k": [0.061514798333, 0.486690566119, 0.78431372549, 1], 585 | "ix": 4 586 | }, 587 | "o": { "a": 0, "k": 100, "ix": 5 }, 588 | "r": 1, 589 | "bm": 0, 590 | "nm": "Fill 1", 591 | "mn": "ADBE Vector Graphic - Fill", 592 | "hd": false 593 | }, 594 | { 595 | "ty": "tr", 596 | "p": { "a": 0, "k": [148.5, -27.5], "ix": 2 }, 597 | "a": { "a": 0, "k": [0, 0], "ix": 1 }, 598 | "s": { "a": 0, "k": [100, 100], "ix": 3 }, 599 | "r": { "a": 0, "k": 0, "ix": 6 }, 600 | "o": { "a": 0, "k": 100, "ix": 7 }, 601 | "sk": { "a": 0, "k": 0, "ix": 4 }, 602 | "sa": { "a": 0, "k": 0, "ix": 5 }, 603 | "nm": "Transform" 604 | } 605 | ], 606 | "nm": "Rectangle 2", 607 | "np": 3, 608 | "cix": 2, 609 | "bm": 0, 610 | "ix": 1, 611 | "mn": "ADBE Vector Group", 612 | "hd": false 613 | }, 614 | { 615 | "ty": "gr", 616 | "it": [ 617 | { 618 | "ty": "rc", 619 | "d": 1, 620 | "s": { "a": 0, "k": [12, 60], "ix": 2 }, 621 | "p": { "a": 0, "k": [0, 0], "ix": 3 }, 622 | "r": { "a": 0, "k": 0, "ix": 4 }, 623 | "nm": "Rectangle Path 1", 624 | "mn": "ADBE Vector Shape - Rect", 625 | "hd": false 626 | }, 627 | { 628 | "ty": "fl", 629 | "c": { 630 | "a": 0, 631 | "k": [0.061514798333, 0.486690566119, 0.78431372549, 1], 632 | "ix": 4 633 | }, 634 | "o": { "a": 0, "k": 100, "ix": 5 }, 635 | "r": 1, 636 | "bm": 0, 637 | "nm": "Fill 1", 638 | "mn": "ADBE Vector Graphic - Fill", 639 | "hd": false 640 | }, 641 | { 642 | "ty": "tr", 643 | "p": { "a": 0, "k": [148.5, -27.5], "ix": 2 }, 644 | "a": { "a": 0, "k": [0, 0], "ix": 1 }, 645 | "s": { "a": 0, "k": [100, 100], "ix": 3 }, 646 | "r": { "a": 0, "k": 90, "ix": 6 }, 647 | "o": { "a": 0, "k": 100, "ix": 7 }, 648 | "sk": { "a": 0, "k": 0, "ix": 4 }, 649 | "sa": { "a": 0, "k": 0, "ix": 5 }, 650 | "nm": "Transform" 651 | } 652 | ], 653 | "nm": "Rectangle 1", 654 | "np": 3, 655 | "cix": 2, 656 | "bm": 0, 657 | "ix": 2, 658 | "mn": "ADBE Vector Group", 659 | "hd": false 660 | } 661 | ], 662 | "ip": 0, 663 | "op": 152.000006191087, 664 | "st": 0, 665 | "bm": 0 666 | } 667 | ] 668 | }, 669 | { 670 | "id": "comp_7", 671 | "layers": [ 672 | { 673 | "ddd": 0, 674 | "ind": 1, 675 | "ty": 4, 676 | "nm": "Shape Layer 4", 677 | "sr": 1, 678 | "ks": { 679 | "o": { "a": 0, "k": 100, "ix": 11 }, 680 | "r": { "a": 0, "k": 0, "ix": 10 }, 681 | "p": { "a": 0, "k": [100.028, 99.92, 0], "ix": 2 }, 682 | "a": { "a": 0, "k": [148.5, -27.5, 0], "ix": 1 }, 683 | "s": { "a": 0, "k": [75, 75, 100], "ix": 6 } 684 | }, 685 | "ao": 0, 686 | "shapes": [ 687 | { 688 | "ty": "gr", 689 | "it": [ 690 | { 691 | "ty": "rc", 692 | "d": 1, 693 | "s": { "a": 0, "k": [12, 60], "ix": 2 }, 694 | "p": { "a": 0, "k": [0, 0], "ix": 3 }, 695 | "r": { "a": 0, "k": 0, "ix": 4 }, 696 | "nm": "Rectangle Path 1", 697 | "mn": "ADBE Vector Shape - Rect", 698 | "hd": false 699 | }, 700 | { 701 | "ty": "fl", 702 | "c": { 703 | "a": 0, 704 | "k": [0.694117647059, 0.522629801432, 0, 1], 705 | "ix": 4 706 | }, 707 | "o": { "a": 0, "k": 100, "ix": 5 }, 708 | "r": 1, 709 | "bm": 0, 710 | "nm": "Fill 1", 711 | "mn": "ADBE Vector Graphic - Fill", 712 | "hd": false 713 | }, 714 | { 715 | "ty": "tr", 716 | "p": { "a": 0, "k": [148.5, -27.5], "ix": 2 }, 717 | "a": { "a": 0, "k": [0, 0], "ix": 1 }, 718 | "s": { "a": 0, "k": [100, 100], "ix": 3 }, 719 | "r": { "a": 0, "k": 0, "ix": 6 }, 720 | "o": { "a": 0, "k": 100, "ix": 7 }, 721 | "sk": { "a": 0, "k": 0, "ix": 4 }, 722 | "sa": { "a": 0, "k": 0, "ix": 5 }, 723 | "nm": "Transform" 724 | } 725 | ], 726 | "nm": "Rectangle 2", 727 | "np": 3, 728 | "cix": 2, 729 | "bm": 0, 730 | "ix": 1, 731 | "mn": "ADBE Vector Group", 732 | "hd": false 733 | }, 734 | { 735 | "ty": "gr", 736 | "it": [ 737 | { 738 | "ty": "rc", 739 | "d": 1, 740 | "s": { "a": 0, "k": [12, 60], "ix": 2 }, 741 | "p": { "a": 0, "k": [0, 0], "ix": 3 }, 742 | "r": { "a": 0, "k": 0, "ix": 4 }, 743 | "nm": "Rectangle Path 1", 744 | "mn": "ADBE Vector Shape - Rect", 745 | "hd": false 746 | }, 747 | { 748 | "ty": "fl", 749 | "c": { 750 | "a": 0, 751 | "k": [0.694117647059, 0.522629801432, 0, 1], 752 | "ix": 4 753 | }, 754 | "o": { "a": 0, "k": 100, "ix": 5 }, 755 | "r": 1, 756 | "bm": 0, 757 | "nm": "Fill 1", 758 | "mn": "ADBE Vector Graphic - Fill", 759 | "hd": false 760 | }, 761 | { 762 | "ty": "tr", 763 | "p": { "a": 0, "k": [148.5, -27.5], "ix": 2 }, 764 | "a": { "a": 0, "k": [0, 0], "ix": 1 }, 765 | "s": { "a": 0, "k": [100, 100], "ix": 3 }, 766 | "r": { "a": 0, "k": 90, "ix": 6 }, 767 | "o": { "a": 0, "k": 100, "ix": 7 }, 768 | "sk": { "a": 0, "k": 0, "ix": 4 }, 769 | "sa": { "a": 0, "k": 0, "ix": 5 }, 770 | "nm": "Transform" 771 | } 772 | ], 773 | "nm": "Rectangle 1", 774 | "np": 3, 775 | "cix": 2, 776 | "bm": 0, 777 | "ix": 2, 778 | "mn": "ADBE Vector Group", 779 | "hd": false 780 | } 781 | ], 782 | "ip": 0, 783 | "op": 152.000006191087, 784 | "st": 0, 785 | "bm": 0 786 | } 787 | ] 788 | }, 789 | { 790 | "id": "comp_8", 791 | "layers": [ 792 | { 793 | "ddd": 0, 794 | "ind": 1, 795 | "ty": 4, 796 | "nm": "Shape Layer 4", 797 | "sr": 1, 798 | "ks": { 799 | "o": { "a": 0, "k": 100, "ix": 11 }, 800 | "r": { "a": 0, "k": 0, "ix": 10 }, 801 | "p": { "a": 0, "k": [100.028, 99.92, 0], "ix": 2 }, 802 | "a": { "a": 0, "k": [148.5, -27.5, 0], "ix": 1 }, 803 | "s": { "a": 0, "k": [75, 75, 100], "ix": 6 } 804 | }, 805 | "ao": 0, 806 | "shapes": [ 807 | { 808 | "ty": "gr", 809 | "it": [ 810 | { 811 | "ty": "rc", 812 | "d": 1, 813 | "s": { "a": 0, "k": [12, 60], "ix": 2 }, 814 | "p": { "a": 0, "k": [0, 0], "ix": 3 }, 815 | "r": { "a": 0, "k": 0, "ix": 4 }, 816 | "nm": "Rectangle Path 1", 817 | "mn": "ADBE Vector Shape - Rect", 818 | "hd": false 819 | }, 820 | { 821 | "ty": "fl", 822 | "c": { 823 | "a": 0, 824 | "k": [0.098454441744, 0.550397027708, 0.760784313725, 1], 825 | "ix": 4 826 | }, 827 | "o": { "a": 0, "k": 100, "ix": 5 }, 828 | "r": 1, 829 | "bm": 0, 830 | "nm": "Fill 1", 831 | "mn": "ADBE Vector Graphic - Fill", 832 | "hd": false 833 | }, 834 | { 835 | "ty": "tr", 836 | "p": { "a": 0, "k": [148.5, -27.5], "ix": 2 }, 837 | "a": { "a": 0, "k": [0, 0], "ix": 1 }, 838 | "s": { "a": 0, "k": [100, 100], "ix": 3 }, 839 | "r": { "a": 0, "k": 0, "ix": 6 }, 840 | "o": { "a": 0, "k": 100, "ix": 7 }, 841 | "sk": { "a": 0, "k": 0, "ix": 4 }, 842 | "sa": { "a": 0, "k": 0, "ix": 5 }, 843 | "nm": "Transform" 844 | } 845 | ], 846 | "nm": "Rectangle 2", 847 | "np": 3, 848 | "cix": 2, 849 | "bm": 0, 850 | "ix": 1, 851 | "mn": "ADBE Vector Group", 852 | "hd": false 853 | }, 854 | { 855 | "ty": "gr", 856 | "it": [ 857 | { 858 | "ty": "rc", 859 | "d": 1, 860 | "s": { "a": 0, "k": [12, 60], "ix": 2 }, 861 | "p": { "a": 0, "k": [0, 0], "ix": 3 }, 862 | "r": { "a": 0, "k": 0, "ix": 4 }, 863 | "nm": "Rectangle Path 1", 864 | "mn": "ADBE Vector Shape - Rect", 865 | "hd": false 866 | }, 867 | { 868 | "ty": "fl", 869 | "c": { 870 | "a": 0, 871 | "k": [0.098454441744, 0.550397027708, 0.760784313725, 1], 872 | "ix": 4 873 | }, 874 | "o": { "a": 0, "k": 100, "ix": 5 }, 875 | "r": 1, 876 | "bm": 0, 877 | "nm": "Fill 1", 878 | "mn": "ADBE Vector Graphic - Fill", 879 | "hd": false 880 | }, 881 | { 882 | "ty": "tr", 883 | "p": { "a": 0, "k": [148.5, -27.5], "ix": 2 }, 884 | "a": { "a": 0, "k": [0, 0], "ix": 1 }, 885 | "s": { "a": 0, "k": [100, 100], "ix": 3 }, 886 | "r": { "a": 0, "k": 90, "ix": 6 }, 887 | "o": { "a": 0, "k": 100, "ix": 7 }, 888 | "sk": { "a": 0, "k": 0, "ix": 4 }, 889 | "sa": { "a": 0, "k": 0, "ix": 5 }, 890 | "nm": "Transform" 891 | } 892 | ], 893 | "nm": "Rectangle 1", 894 | "np": 3, 895 | "cix": 2, 896 | "bm": 0, 897 | "ix": 2, 898 | "mn": "ADBE Vector Group", 899 | "hd": false 900 | } 901 | ], 902 | "ip": 0, 903 | "op": 152.000006191087, 904 | "st": 0, 905 | "bm": 0 906 | } 907 | ] 908 | }, 909 | { 910 | "id": "comp_9", 911 | "layers": [ 912 | { 913 | "ddd": 0, 914 | "ind": 1, 915 | "ty": 4, 916 | "nm": "Shape Layer 3", 917 | "sr": 1, 918 | "ks": { 919 | "o": { "a": 0, "k": 100, "ix": 11 }, 920 | "r": { "a": 0, "k": 0, "ix": 10 }, 921 | "p": { "a": 0, "k": [100.062, 99.875, 0], "ix": 2 }, 922 | "a": { "a": 0, "k": [156, -27.5, 0], "ix": 1 }, 923 | "s": { "a": 0, "k": [65, 65, 100], "ix": 6 } 924 | }, 925 | "ao": 0, 926 | "shapes": [ 927 | { 928 | "ty": "gr", 929 | "it": [ 930 | { 931 | "ty": "rc", 932 | "d": 1, 933 | "s": { "a": 0, "k": [50, 50], "ix": 2 }, 934 | "p": { "a": 0, "k": [0, 0], "ix": 3 }, 935 | "r": { "a": 0, "k": 0, "ix": 4 }, 936 | "nm": "Rectangle Path 1", 937 | "mn": "ADBE Vector Shape - Rect", 938 | "hd": false 939 | }, 940 | { 941 | "ty": "st", 942 | "c": { 943 | "a": 0, 944 | "k": [0.373979306688, 0, 0.756862745098, 1], 945 | "ix": 3 946 | }, 947 | "o": { "a": 0, "k": 100, "ix": 4 }, 948 | "w": { "a": 0, "k": 10, "ix": 5 }, 949 | "lc": 1, 950 | "lj": 1, 951 | "ml": 4, 952 | "bm": 0, 953 | "nm": "Stroke 1", 954 | "mn": "ADBE Vector Graphic - Stroke", 955 | "hd": false 956 | }, 957 | { 958 | "ty": "tr", 959 | "p": { "a": 0, "k": [156, -27.5], "ix": 2 }, 960 | "a": { "a": 0, "k": [0, 0], "ix": 1 }, 961 | "s": { "a": 0, "k": [100, 100], "ix": 3 }, 962 | "r": { "a": 0, "k": 0, "ix": 6 }, 963 | "o": { "a": 0, "k": 100, "ix": 7 }, 964 | "sk": { "a": 0, "k": 0, "ix": 4 }, 965 | "sa": { "a": 0, "k": 0, "ix": 5 }, 966 | "nm": "Transform" 967 | } 968 | ], 969 | "nm": "Rectangle 1", 970 | "np": 3, 971 | "cix": 2, 972 | "bm": 0, 973 | "ix": 1, 974 | "mn": "ADBE Vector Group", 975 | "hd": false 976 | } 977 | ], 978 | "ip": 0, 979 | "op": 152.000006191087, 980 | "st": 0, 981 | "bm": 0 982 | } 983 | ] 984 | } 985 | ], 986 | "layers": [ 987 | { 988 | "ddd": 0, 989 | "ind": 1, 990 | "ty": 0, 991 | "nm": "Shape on Path 4", 992 | "refId": "comp_0", 993 | "sr": 1, 994 | "ks": { 995 | "o": { "a": 0, "k": 100, "ix": 11 }, 996 | "r": { 997 | "a": 1, 998 | "k": [ 999 | { 1000 | "i": { "x": [0.406], "y": [0.632] }, 1001 | "o": { "x": [0.144], "y": [-0.591] }, 1002 | "t": 0, 1003 | "s": [80] 1004 | }, 1005 | { "t": 45.0000018328876, "s": [-38.129] } 1006 | ], 1007 | "ix": 10 1008 | }, 1009 | "p": { 1010 | "a": 1, 1011 | "k": [ 1012 | { 1013 | "i": { "x": 0.207, "y": 1 }, 1014 | "o": { "x": 0.067, "y": 0 }, 1015 | "t": 0, 1016 | "s": [199.074, 196.852, 0], 1017 | "to": [0, -0.241, 0], 1018 | "ti": [0, 0, 0] 1019 | }, 1020 | { "t": 43.0000017514259, "s": [251.066, 275.155, 0] } 1021 | ], 1022 | "ix": 2 1023 | }, 1024 | "a": { "a": 0, "k": [100, 100, 0], "ix": 1 }, 1025 | "s": { 1026 | "a": 1, 1027 | "k": [ 1028 | { 1029 | "i": { "x": [0.38, 0.38, 0.843], "y": [1, 1, 1] }, 1030 | "o": { "x": [0.398, 0.398, 0.208], "y": [0, 0, 0] }, 1031 | "t": 0, 1032 | "s": [0, 0, 100] 1033 | }, 1034 | { 1035 | "i": { "x": [0.642, 0.642, 0.4], "y": [1, 1, 1] }, 1036 | "o": { "x": [0.45, 0.45, 0.6], "y": [0, 0, 0] }, 1037 | "t": 8, 1038 | "s": [40.741, 40.741, 100] 1039 | }, 1040 | { "t": 39.0000015885026, "s": [0, 0, 100] } 1041 | ], 1042 | "ix": 6 1043 | } 1044 | }, 1045 | "ao": 0, 1046 | "w": 200, 1047 | "h": 200, 1048 | "ip": 0, 1049 | "op": 41.0000016699642, 1050 | "st": 0, 1051 | "bm": 0 1052 | }, 1053 | { 1054 | "ddd": 0, 1055 | "ind": 2, 1056 | "ty": 0, 1057 | "nm": "Shape on Path 3", 1058 | "refId": "comp_1", 1059 | "sr": 1, 1060 | "ks": { 1061 | "o": { "a": 0, "k": 100, "ix": 11 }, 1062 | "r": { 1063 | "a": 1, 1064 | "k": [ 1065 | { 1066 | "i": { "x": [0.406], "y": [0.61] }, 1067 | "o": { "x": [0.144], "y": [-0.684] }, 1068 | "t": 0, 1069 | "s": [29] 1070 | }, 1071 | { "t": 45.0000018328876, "s": [-73.102] } 1072 | ], 1073 | "ix": 10 1074 | }, 1075 | "p": { 1076 | "a": 1, 1077 | "k": [ 1078 | { 1079 | "i": { "x": 0.207, "y": 1 }, 1080 | "o": { "x": 0.067, "y": 0 }, 1081 | "t": 0, 1082 | "s": [199.074, 196.111, 0], 1083 | "to": [0, -0.301, 0], 1084 | "ti": [0.123, 0.494, 0] 1085 | }, 1086 | { "t": 39.0000015885026, "s": [141.111, 102.267, 0] } 1087 | ], 1088 | "ix": 2 1089 | }, 1090 | "a": { "a": 0, "k": [100, 100, 0], "ix": 1 }, 1091 | "s": { 1092 | "a": 1, 1093 | "k": [ 1094 | { 1095 | "i": { "x": [0.38, 0.38, 0.843], "y": [1, 1, 1] }, 1096 | "o": { "x": [0.398, 0.398, 0.208], "y": [0, 0, 0] }, 1097 | "t": 0, 1098 | "s": [0, 0, 100] 1099 | }, 1100 | { 1101 | "i": { "x": [0.642, 0.642, 0.4], "y": [1, 1, 1] }, 1102 | "o": { "x": [0.45, 0.45, 0.6], "y": [0, 0, 0] }, 1103 | "t": 8, 1104 | "s": [44.444, 44.444, 100] 1105 | }, 1106 | { "t": 40.0000016292334, "s": [0, 0, 100] } 1107 | ], 1108 | "ix": 6 1109 | } 1110 | }, 1111 | "ao": 0, 1112 | "w": 200, 1113 | "h": 200, 1114 | "ip": 0, 1115 | "op": 41.0000016699642, 1116 | "st": 0, 1117 | "bm": 0 1118 | }, 1119 | { 1120 | "ddd": 0, 1121 | "ind": 3, 1122 | "ty": 0, 1123 | "nm": "Shape on Path 2", 1124 | "refId": "comp_2", 1125 | "sr": 1, 1126 | "ks": { 1127 | "o": { "a": 0, "k": 100, "ix": 11 }, 1128 | "r": { 1129 | "a": 1, 1130 | "k": [ 1131 | { 1132 | "i": { "x": [0.381], "y": [0.835] }, 1133 | "o": { "x": [0.052], "y": [0.239] }, 1134 | "t": 0, 1135 | "s": [115] 1136 | }, 1137 | { "t": 45.0000018328876, "s": [-43.191] } 1138 | ], 1139 | "ix": 10 1140 | }, 1141 | "p": { 1142 | "a": 1, 1143 | "k": [ 1144 | { 1145 | "i": { "x": 0.207, "y": 1 }, 1146 | "o": { "x": 0.067, "y": 0 }, 1147 | "t": 0, 1148 | "s": [201.852, 197.407, 0], 1149 | "to": [0, -0.156, 0], 1150 | "ti": [-0.197, 0.099, 0] 1151 | }, 1152 | { "t": 42.0000017106951, "s": [295, 133.656, 0] } 1153 | ], 1154 | "ix": 2 1155 | }, 1156 | "a": { "a": 0, "k": [100, 100, 0], "ix": 1 }, 1157 | "s": { 1158 | "a": 1, 1159 | "k": [ 1160 | { 1161 | "i": { "x": [0.38, 0.38, 0.843], "y": [1, 1, 1] }, 1162 | "o": { "x": [0.398, 0.398, 0.208], "y": [0, 0, 0] }, 1163 | "t": 0, 1164 | "s": [0, 0, 100] 1165 | }, 1166 | { 1167 | "i": { "x": [0.642, 0.642, 0.4], "y": [1, 1, 1] }, 1168 | "o": { "x": [0.45, 0.45, 0.6], "y": [0, 0, 0] }, 1169 | "t": 8, 1170 | "s": [37.037, 37.037, 100] 1171 | }, 1172 | { "t": 40.0000016292334, "s": [0, 0, 100] } 1173 | ], 1174 | "ix": 6 1175 | } 1176 | }, 1177 | "ao": 0, 1178 | "w": 200, 1179 | "h": 200, 1180 | "ip": 0, 1181 | "op": 41.0000016699642, 1182 | "st": 0, 1183 | "bm": 0 1184 | }, 1185 | { 1186 | "ddd": 0, 1187 | "ind": 4, 1188 | "ty": 0, 1189 | "nm": "Shape on Path 1", 1190 | "refId": "comp_3", 1191 | "sr": 1, 1192 | "ks": { 1193 | "o": { "a": 0, "k": 100, "ix": 11 }, 1194 | "r": { 1195 | "a": 1, 1196 | "k": [ 1197 | { 1198 | "i": { "x": [0.369], "y": [0.893] }, 1199 | "o": { "x": [0.006], "y": [0.482] }, 1200 | "t": 0, 1201 | "s": [162] 1202 | }, 1203 | { "t": 45.0000018328876, "s": [-15.236] } 1204 | ], 1205 | "ix": 10 1206 | }, 1207 | "p": { 1208 | "a": 1, 1209 | "k": [ 1210 | { 1211 | "i": { "x": 0.207, "y": 1 }, 1212 | "o": { "x": 0.067, "y": 0 }, 1213 | "t": 0, 1214 | "s": [199.074, 199.63, 0], 1215 | "to": [0, -0.26, 0], 1216 | "ti": [3.074, -26.019, 0] 1217 | }, 1218 | { "t": 40.0000016292334, "s": [160.319, 286.002, 0] } 1219 | ], 1220 | "ix": 2 1221 | }, 1222 | "a": { "a": 0, "k": [100, 100, 0], "ix": 1 }, 1223 | "s": { 1224 | "a": 1, 1225 | "k": [ 1226 | { 1227 | "i": { "x": [0.38, 0.38, 0.843], "y": [1, 1, 1] }, 1228 | "o": { "x": [0.398, 0.398, 0.208], "y": [0, 0, 0] }, 1229 | "t": 0, 1230 | "s": [0, 0, 100] 1231 | }, 1232 | { 1233 | "i": { "x": [0.642, 0.642, 0.4], "y": [1, 1, 1] }, 1234 | "o": { "x": [0.45, 0.45, 0.6], "y": [0, 0, 0] }, 1235 | "t": 8, 1236 | "s": [37.037, 37.037, 100] 1237 | }, 1238 | { "t": 34.0000013848484, "s": [0, 0, 100] } 1239 | ], 1240 | "ix": 6 1241 | } 1242 | }, 1243 | "ao": 0, 1244 | "w": 200, 1245 | "h": 200, 1246 | "ip": 0, 1247 | "op": 41.0000016699642, 1248 | "st": 0, 1249 | "bm": 0 1250 | }, 1251 | { 1252 | "ddd": 0, 1253 | "ind": 5, 1254 | "ty": 0, 1255 | "nm": "Placeholder 5", 1256 | "refId": "comp_4", 1257 | "sr": 1, 1258 | "ks": { 1259 | "o": { "a": 0, "k": 100, "ix": 11 }, 1260 | "r": { 1261 | "a": 1, 1262 | "k": [ 1263 | { 1264 | "i": { "x": [0.406], "y": [0.852] }, 1265 | "o": { "x": [0.144], "y": [0.318] }, 1266 | "t": 0, 1267 | "s": [-106] 1268 | }, 1269 | { "t": 45.0000018328876, "s": [113.369] } 1270 | ], 1271 | "ix": 10 1272 | }, 1273 | "p": { 1274 | "a": 1, 1275 | "k": [ 1276 | { 1277 | "i": { "x": 0.207, "y": 1 }, 1278 | "o": { "x": 0.067, "y": 0 }, 1279 | "t": 0, 1280 | "s": [200, 200, 0], 1281 | "to": [14.691, 6.049, 0], 1282 | "ti": [-14.691, -6.049, 0] 1283 | }, 1284 | { "t": 40.0000016292334, "s": [288.148, 236.296, 0] } 1285 | ], 1286 | "ix": 2 1287 | }, 1288 | "a": { "a": 0, "k": [100, 100, 0], "ix": 1 }, 1289 | "s": { 1290 | "a": 1, 1291 | "k": [ 1292 | { 1293 | "i": { "x": [0.38, 0.38, 0.843], "y": [1, 1, 1] }, 1294 | "o": { "x": [0.398, 0.398, 0.208], "y": [0, 0, 0] }, 1295 | "t": 0, 1296 | "s": [0, 0, 100] 1297 | }, 1298 | { 1299 | "i": { "x": [0.642, 0.642, 0.4], "y": [1, 1, 1] }, 1300 | "o": { "x": [0.45, 0.45, 0.6], "y": [0, 0, 0] }, 1301 | "t": 8, 1302 | "s": [18.519, 18.519, 100] 1303 | }, 1304 | { "t": 40.0000016292334, "s": [0, 0, 100] } 1305 | ], 1306 | "ix": 6 1307 | } 1308 | }, 1309 | "ao": 0, 1310 | "w": 200, 1311 | "h": 200, 1312 | "ip": 0, 1313 | "op": 41.0000016699642, 1314 | "st": 0, 1315 | "bm": 0 1316 | }, 1317 | { 1318 | "ddd": 0, 1319 | "ind": 6, 1320 | "ty": 0, 1321 | "nm": "Placeholder 6", 1322 | "refId": "comp_5", 1323 | "sr": 1, 1324 | "ks": { 1325 | "o": { "a": 0, "k": 100, "ix": 11 }, 1326 | "r": { 1327 | "a": 1, 1328 | "k": [ 1329 | { 1330 | "i": { "x": [0.406], "y": [0.913] }, 1331 | "o": { "x": [0.144], "y": [0.571] }, 1332 | "t": 0, 1333 | "s": [-75] 1334 | }, 1335 | { "t": 45.0000018328876, "s": [47.268] } 1336 | ], 1337 | "ix": 10 1338 | }, 1339 | "p": { 1340 | "a": 1, 1341 | "k": [ 1342 | { 1343 | "i": { "x": 0.207, "y": 1 }, 1344 | "o": { "x": 0.067, "y": 0 }, 1345 | "t": 0, 1346 | "s": [200, 200, 0], 1347 | "to": [0.247, 14.938, 0], 1348 | "ti": [-0.247, -14.938, 0] 1349 | }, 1350 | { "t": 37.0000015070409, "s": [201.481, 289.63, 0] } 1351 | ], 1352 | "ix": 2 1353 | }, 1354 | "a": { "a": 0, "k": [100, 100, 0], "ix": 1 }, 1355 | "s": { 1356 | "a": 1, 1357 | "k": [ 1358 | { 1359 | "i": { "x": [0.38, 0.38, 0.843], "y": [1, 1, 1] }, 1360 | "o": { "x": [0.398, 0.398, 0.208], "y": [0, 0, 0] }, 1361 | "t": 0, 1362 | "s": [0, 0, 100] 1363 | }, 1364 | { 1365 | "i": { "x": [0.642, 0.642, 0.4], "y": [1, 1, 1] }, 1366 | "o": { "x": [0.45, 0.45, 0.6], "y": [0, 0, 0] }, 1367 | "t": 8, 1368 | "s": [27.778, 27.778, 100] 1369 | }, 1370 | { "t": 38.0000015477717, "s": [0, 0, 100] } 1371 | ], 1372 | "ix": 6 1373 | } 1374 | }, 1375 | "ao": 0, 1376 | "w": 200, 1377 | "h": 200, 1378 | "ip": 0, 1379 | "op": 41.0000016699642, 1380 | "st": 0, 1381 | "bm": 0 1382 | }, 1383 | { 1384 | "ddd": 0, 1385 | "ind": 7, 1386 | "ty": 0, 1387 | "nm": "Placeholder 7", 1388 | "refId": "comp_6", 1389 | "sr": 1, 1390 | "ks": { 1391 | "o": { "a": 0, "k": 100, "ix": 11 }, 1392 | "r": { 1393 | "a": 1, 1394 | "k": [ 1395 | { 1396 | "i": { "x": [0.406], "y": [0.857] }, 1397 | "o": { "x": [0.144], "y": [0.34] }, 1398 | "t": 0, 1399 | "s": [0] 1400 | }, 1401 | { "t": 45.0000018328876, "s": [205.228] } 1402 | ], 1403 | "ix": 10 1404 | }, 1405 | "p": { 1406 | "a": 1, 1407 | "k": [ 1408 | { 1409 | "i": { "x": 0.207, "y": 1 }, 1410 | "o": { "x": 0.067, "y": 0 }, 1411 | "t": 0, 1412 | "s": [200, 200, 0], 1413 | "to": [-18.025, -0.617, 0], 1414 | "ti": [18.025, 0.617, 0] 1415 | }, 1416 | { "t": 42.0000017106951, "s": [91.852, 196.296, 0] } 1417 | ], 1418 | "ix": 2 1419 | }, 1420 | "a": { "a": 0, "k": [100, 100, 0], "ix": 1 }, 1421 | "s": { 1422 | "a": 1, 1423 | "k": [ 1424 | { 1425 | "i": { "x": [0.38, 0.38, 0.843], "y": [1, 1, 1] }, 1426 | "o": { "x": [0.398, 0.398, 0.208], "y": [0, 0, 0] }, 1427 | "t": 0, 1428 | "s": [0, 0, 100] 1429 | }, 1430 | { 1431 | "i": { "x": [0.642, 0.642, 0.4], "y": [1, 1, 1] }, 1432 | "o": { "x": [0.45, 0.45, 0.6], "y": [0, 0, 0] }, 1433 | "t": 8, 1434 | "s": [27.778, 27.778, 100] 1435 | }, 1436 | { "t": 36.0000014663101, "s": [0, 0, 100] } 1437 | ], 1438 | "ix": 6 1439 | } 1440 | }, 1441 | "ao": 0, 1442 | "w": 200, 1443 | "h": 200, 1444 | "ip": 0, 1445 | "op": 41.0000016699642, 1446 | "st": 0, 1447 | "bm": 0 1448 | }, 1449 | { 1450 | "ddd": 0, 1451 | "ind": 8, 1452 | "ty": 0, 1453 | "nm": "Placeholder 8", 1454 | "refId": "comp_7", 1455 | "sr": 1, 1456 | "ks": { 1457 | "o": { "a": 0, "k": 100, "ix": 11 }, 1458 | "r": { 1459 | "a": 1, 1460 | "k": [ 1461 | { 1462 | "i": { "x": [0.406], "y": [0.97] }, 1463 | "o": { "x": [0.144], "y": [0.807] }, 1464 | "t": 0, 1465 | "s": [0] 1466 | }, 1467 | { "t": 45.0000018328876, "s": [86.444] } 1468 | ], 1469 | "ix": 10 1470 | }, 1471 | "p": { 1472 | "a": 1, 1473 | "k": [ 1474 | { 1475 | "i": { "x": 0.207, "y": 1 }, 1476 | "o": { "x": 0.067, "y": 0 }, 1477 | "t": 0, 1478 | "s": [200, 200, 0], 1479 | "to": [8.519, -15.185, 0], 1480 | "ti": [-8.519, 15.185, 0] 1481 | }, 1482 | { "t": 45.0000018328876, "s": [251.111, 108.889, 0] } 1483 | ], 1484 | "ix": 2 1485 | }, 1486 | "a": { "a": 0, "k": [100, 100, 0], "ix": 1 }, 1487 | "s": { 1488 | "a": 1, 1489 | "k": [ 1490 | { 1491 | "i": { "x": [0.38, 0.38, 0.843], "y": [1, 1, 1] }, 1492 | "o": { "x": [0.398, 0.398, 0.208], "y": [0, 0, 0] }, 1493 | "t": 0, 1494 | "s": [0, 0, 100] 1495 | }, 1496 | { 1497 | "i": { "x": [0.642, 0.642, 0.4], "y": [1, 1, 1] }, 1498 | "o": { "x": [0.45, 0.45, 0.6], "y": [0, 0, 0] }, 1499 | "t": 8, 1500 | "s": [27.778, 27.778, 100] 1501 | }, 1502 | { "t": 39.0000015885026, "s": [0, 0, 100] } 1503 | ], 1504 | "ix": 6 1505 | } 1506 | }, 1507 | "ao": 0, 1508 | "w": 200, 1509 | "h": 200, 1510 | "ip": 0, 1511 | "op": 41.0000016699642, 1512 | "st": 0, 1513 | "bm": 0 1514 | }, 1515 | { 1516 | "ddd": 0, 1517 | "ind": 9, 1518 | "ty": 0, 1519 | "nm": "Placeholder 9", 1520 | "refId": "comp_8", 1521 | "sr": 1, 1522 | "ks": { 1523 | "o": { "a": 0, "k": 100, "ix": 11 }, 1524 | "r": { 1525 | "a": 1, 1526 | "k": [ 1527 | { 1528 | "i": { "x": [0.406], "y": [0.875] }, 1529 | "o": { "x": [0.144], "y": [0.414] }, 1530 | "t": 0, 1531 | "s": [0] 1532 | }, 1533 | { "t": 45.0000018328876, "s": [168.462] } 1534 | ], 1535 | "ix": 10 1536 | }, 1537 | "p": { 1538 | "a": 1, 1539 | "k": [ 1540 | { 1541 | "i": { "x": 0.207, "y": 1 }, 1542 | "o": { "x": 0.067, "y": 0 }, 1543 | "t": 0, 1544 | "s": [200, 200, 0], 1545 | "to": [0.37, -19.136, 0], 1546 | "ti": [-0.37, 19.136, 0] 1547 | }, 1548 | { "t": 34.0000013848484, "s": [202.222, 85.185, 0] } 1549 | ], 1550 | "ix": 2 1551 | }, 1552 | "a": { "a": 0, "k": [100, 100, 0], "ix": 1 }, 1553 | "s": { 1554 | "a": 1, 1555 | "k": [ 1556 | { 1557 | "i": { "x": [0.38, 0.38, 0.843], "y": [1, 1, 1] }, 1558 | "o": { "x": [0.398, 0.398, 0.208], "y": [0, 0, 0] }, 1559 | "t": 0, 1560 | "s": [0, 0, 100] 1561 | }, 1562 | { 1563 | "i": { "x": [0.642, 0.642, 0.4], "y": [1, 1, 1] }, 1564 | "o": { "x": [0.45, 0.45, 0.6], "y": [0, 0, 0] }, 1565 | "t": 8, 1566 | "s": [18.519, 18.519, 100] 1567 | }, 1568 | { "t": 34.0000013848484, "s": [0, 0, 100] } 1569 | ], 1570 | "ix": 6 1571 | } 1572 | }, 1573 | "ao": 0, 1574 | "w": 200, 1575 | "h": 200, 1576 | "ip": 0, 1577 | "op": 41.0000016699642, 1578 | "st": 0, 1579 | "bm": 0 1580 | }, 1581 | { 1582 | "ddd": 0, 1583 | "ind": 10, 1584 | "ty": 0, 1585 | "nm": "Placeholder 10", 1586 | "refId": "comp_9", 1587 | "sr": 1, 1588 | "ks": { 1589 | "o": { "a": 0, "k": 100, "ix": 11 }, 1590 | "r": { 1591 | "a": 1, 1592 | "k": [ 1593 | { 1594 | "i": { "x": [0.373], "y": [1] }, 1595 | "o": { "x": [0.127], "y": [0.545] }, 1596 | "t": 0, 1597 | "s": [0] 1598 | }, 1599 | { 1600 | "i": { "x": [0.833], "y": [1] }, 1601 | "o": { "x": [0.167], "y": [0] }, 1602 | "t": 40, 1603 | "s": [100] 1604 | }, 1605 | { "t": 45.0000018328876, "s": [100] } 1606 | ], 1607 | "ix": 10 1608 | }, 1609 | "p": { 1610 | "a": 1, 1611 | "k": [ 1612 | { 1613 | "i": { "x": 0.207, "y": 1 }, 1614 | "o": { "x": 0.067, "y": 0 }, 1615 | "t": 0, 1616 | "s": [200, 200, 0], 1617 | "to": [-11.728, 3.457, 0], 1618 | "ti": [11.728, -3.457, 0] 1619 | }, 1620 | { "t": 36.0000014663101, "s": [129.63, 220.741, 0] } 1621 | ], 1622 | "ix": 2 1623 | }, 1624 | "a": { "a": 0, "k": [100, 100, 0], "ix": 1 }, 1625 | "s": { 1626 | "a": 1, 1627 | "k": [ 1628 | { 1629 | "i": { "x": [0.38, 0.38, 0.843], "y": [1, 1, 1] }, 1630 | "o": { "x": [0.398, 0.398, 0.208], "y": [0, 0, 0] }, 1631 | "t": 0, 1632 | "s": [0, 0, 100] 1633 | }, 1634 | { 1635 | "i": { "x": [0.642, 0.642, 0.4], "y": [1, 1, 1] }, 1636 | "o": { "x": [0.45, 0.45, 0.6], "y": [0, 0, 0] }, 1637 | "t": 8, 1638 | "s": [18.519, 18.519, 100] 1639 | }, 1640 | { "t": 40.0000016292334, "s": [0, 0, 100] } 1641 | ], 1642 | "ix": 6 1643 | } 1644 | }, 1645 | "ao": 0, 1646 | "w": 200, 1647 | "h": 200, 1648 | "ip": 0, 1649 | "op": 41.0000016699642, 1650 | "st": 0, 1651 | "bm": 0 1652 | } 1653 | ], 1654 | "markers": [] 1655 | } 1656 | --------------------------------------------------------------------------------