From e7f0673de90532c5afab7a2a0ccc1463967fa77c Mon Sep 17 00:00:00 2001 From: Milan Paunovic Date: Tue, 22 Oct 2024 01:15:50 +0200 Subject: [PATCH 01/66] p list fix --- app.json | 2 +- ios/cally/Info.plist | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app.json b/app.json index 9ad190e..e9e5ea9 100644 --- a/app.json +++ b/app.json @@ -16,7 +16,7 @@ "supportsTablet": true, "bundleIdentifier": "com.cally.app", "googleServicesFile": "./ios/GoogleService-Info.plist", - "buildNumber": "40", + "buildNumber": "42", "usesAppleSignIn": true }, "android": { diff --git a/ios/cally/Info.plist b/ios/cally/Info.plist index 468c1d5..5d4fd82 100644 --- a/ios/cally/Info.plist +++ b/ios/cally/Info.plist @@ -47,7 +47,7 @@ CFBundleVersion - 40 + 42 LSRequiresIPhoneOS NSAppTransportSecurity @@ -118,6 +118,7 @@ $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route + $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route UILaunchStoryboardName SplashScreen From b653a173136e662dee25663253e1215ce352885c Mon Sep 17 00:00:00 2001 From: Milan Paunovic Date: Tue, 22 Oct 2024 08:40:16 +0200 Subject: [PATCH 02/66] build nr updt --- app.json | 2 +- ios/cally/Info.plist | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app.json b/app.json index e9e5ea9..4b0b002 100644 --- a/app.json +++ b/app.json @@ -16,7 +16,7 @@ "supportsTablet": true, "bundleIdentifier": "com.cally.app", "googleServicesFile": "./ios/GoogleService-Info.plist", - "buildNumber": "42", + "buildNumber": "45", "usesAppleSignIn": true }, "android": { diff --git a/ios/cally/Info.plist b/ios/cally/Info.plist index 5d4fd82..f065a6d 100644 --- a/ios/cally/Info.plist +++ b/ios/cally/Info.plist @@ -47,7 +47,7 @@ CFBundleVersion - 42 + 45 LSRequiresIPhoneOS NSAppTransportSecurity @@ -119,6 +119,8 @@ $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route + $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route + $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route UILaunchStoryboardName SplashScreen From 16cb35ff8f9dfccc9632efb7742a27b106ad79a7 Mon Sep 17 00:00:00 2001 From: Milan Paunovic Date: Tue, 22 Oct 2024 08:41:09 +0200 Subject: [PATCH 03/66] build nr updt --- yarn.lock | 937 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 552 insertions(+), 385 deletions(-) diff --git a/yarn.lock b/yarn.lock index 6703098..5b2f25a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,13 +10,6 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.24" -"@babel/code-frame@7.10.4", "@babel/code-frame@~7.10.4": - version "7.10.4" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz" - integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== - dependencies: - "@babel/highlight" "^7.10.4" - "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.24.7": version "7.24.7" resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz" @@ -25,6 +18,20 @@ "@babel/highlight" "^7.24.7" picocolors "^1.0.0" +"@babel/code-frame@~7.10.4": + version "7.10.4" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz" + integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== + dependencies: + "@babel/highlight" "^7.10.4" + +"@babel/code-frame@7.10.4": + version "7.10.4" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz" + integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== + dependencies: + "@babel/highlight" "^7.10.4" + "@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.25.2": version "7.25.2" resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.2.tgz" @@ -51,6 +58,16 @@ json5 "^2.2.3" semver "^6.3.1" +"@babel/generator@^7.20.0", "@babel/generator@^7.20.5", "@babel/generator@^7.25.0", "@babel/generator@^7.7.2": + version "7.25.0" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz" + integrity sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw== + dependencies: + "@babel/types" "^7.25.0" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + jsesc "^2.5.1" + "@babel/generator@7.2.0": version "7.2.0" resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.2.0.tgz" @@ -62,16 +79,6 @@ source-map "^0.5.0" trim-right "^1.0.1" -"@babel/generator@^7.20.0", "@babel/generator@^7.20.5", "@babel/generator@^7.25.0", "@babel/generator@^7.7.2": - version "7.25.0" - resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz" - integrity sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw== - dependencies: - "@babel/types" "^7.25.0" - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.25" - jsesc "^2.5.1" - "@babel/helper-annotate-as-pure@^7.24.7": version "7.24.7" resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz" @@ -961,27 +968,6 @@ node-forge "^1.2.1" nullthrows "^1.1.1" -"@expo/config-plugins@8.0.9", "@expo/config-plugins@~8.0.0-beta.0", "@expo/config-plugins@~8.0.8": - version "8.0.9" - resolved "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-8.0.9.tgz" - integrity sha512-dNCG45C7BbDPV9MdWvCbsFtJtVn4w/TJbb5b7Yr6FA8HYIlaaVM0wqUMzTPmGj54iYXw8X/Vge8uCPxg7RWgeA== - dependencies: - "@expo/config-types" "^51.0.0-unreleased" - "@expo/json-file" "~8.3.0" - "@expo/plist" "^0.1.0" - "@expo/sdk-runtime-versions" "^1.0.0" - chalk "^4.1.2" - debug "^4.3.1" - find-up "~5.0.0" - getenv "^1.0.0" - glob "7.1.6" - resolve-from "^5.0.0" - semver "^7.5.4" - slash "^3.0.0" - slugify "^1.6.6" - xcode "^3.0.1" - xml2js "0.6.0" - "@expo/config-plugins@~5.0.3": version "5.0.4" resolved "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-5.0.4.tgz" @@ -1003,6 +989,27 @@ xcode "^3.0.1" xml2js "0.4.23" +"@expo/config-plugins@~8.0.0-beta.0", "@expo/config-plugins@~8.0.8", "@expo/config-plugins@8.0.9": + version "8.0.9" + resolved "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-8.0.9.tgz" + integrity sha512-dNCG45C7BbDPV9MdWvCbsFtJtVn4w/TJbb5b7Yr6FA8HYIlaaVM0wqUMzTPmGj54iYXw8X/Vge8uCPxg7RWgeA== + dependencies: + "@expo/config-types" "^51.0.0-unreleased" + "@expo/json-file" "~8.3.0" + "@expo/plist" "^0.1.0" + "@expo/sdk-runtime-versions" "^1.0.0" + chalk "^4.1.2" + debug "^4.3.1" + find-up "~5.0.0" + getenv "^1.0.0" + glob "7.1.6" + resolve-from "^5.0.0" + semver "^7.5.4" + slash "^3.0.0" + slugify "^1.6.6" + xcode "^3.0.1" + xml2js "0.6.0" + "@expo/config-types@^47.0.0": version "47.0.0" resolved "https://registry.npmjs.org/@expo/config-types/-/config-types-47.0.0.tgz" @@ -1013,23 +1020,6 @@ resolved "https://registry.npmjs.org/@expo/config-types/-/config-types-51.0.2.tgz" integrity sha512-IglkIoiDwJMY01lYkF/ZSBoe/5cR+O3+Gx6fpLFjLfgZGBTdyPkKa1g8NWoWQCk+D3cKL2MDbszT2DyRRB0YqQ== -"@expo/config@9.0.3", "@expo/config@~9.0.0", "@expo/config@~9.0.0-beta.0": - version "9.0.3" - resolved "https://registry.npmjs.org/@expo/config/-/config-9.0.3.tgz" - integrity sha512-eOTNM8eOC8gZNHgenySRlc/lwmYY1NOgvjwA8LHuvPT7/eUwD93zrxu3lPD1Cc/P6C/2BcVdfH4hf0tLmDxnsg== - dependencies: - "@babel/code-frame" "~7.10.4" - "@expo/config-plugins" "~8.0.8" - "@expo/config-types" "^51.0.0-unreleased" - "@expo/json-file" "^8.3.0" - getenv "^1.0.0" - glob "7.1.6" - require-from-string "^2.0.2" - resolve-from "^5.0.0" - semver "^7.6.0" - slugify "^1.3.4" - sucrase "3.34.0" - "@expo/config@~7.0.2": version "7.0.3" resolved "https://registry.npmjs.org/@expo/config/-/config-7.0.3.tgz" @@ -1047,6 +1037,23 @@ slugify "^1.3.4" sucrase "^3.20.0" +"@expo/config@~9.0.0", "@expo/config@~9.0.0-beta.0", "@expo/config@9.0.3": + version "9.0.3" + resolved "https://registry.npmjs.org/@expo/config/-/config-9.0.3.tgz" + integrity sha512-eOTNM8eOC8gZNHgenySRlc/lwmYY1NOgvjwA8LHuvPT7/eUwD93zrxu3lPD1Cc/P6C/2BcVdfH4hf0tLmDxnsg== + dependencies: + "@babel/code-frame" "~7.10.4" + "@expo/config-plugins" "~8.0.8" + "@expo/config-types" "^51.0.0-unreleased" + "@expo/json-file" "^8.3.0" + getenv "^1.0.0" + glob "7.1.6" + require-from-string "^2.0.2" + resolve-from "^5.0.0" + semver "^7.6.0" + slugify "^1.3.4" + sucrase "3.34.0" + "@expo/configure-splash-screen@^0.6.0": version "0.6.0" resolved "https://registry.npmjs.org/@expo/configure-splash-screen/-/configure-splash-screen-0.6.0.tgz" @@ -1104,6 +1111,22 @@ resolve-from "^5.0.0" semver "^7.6.0" +"@expo/image-utils@^0.5.0": + version "0.5.1" + resolved "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.5.1.tgz" + integrity sha512-U/GsFfFox88lXULmFJ9Shfl2aQGcwoKPF7fawSCLixIKtMCpsI+1r0h+5i0nQnmt9tHuzXZDL8+Dg1z6OhkI9A== + dependencies: + "@expo/spawn-async" "^1.7.2" + chalk "^4.0.0" + fs-extra "9.0.0" + getenv "^1.0.0" + jimp-compact "0.16.1" + node-fetch "^2.6.0" + parse-png "^2.1.0" + resolve-from "^5.0.0" + semver "^7.6.0" + tempy "0.3.0" + "@expo/image-utils@0.3.22": version "0.3.22" resolved "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.3.22.tgz" @@ -1121,21 +1144,14 @@ semver "7.3.2" tempy "0.3.0" -"@expo/image-utils@^0.5.0": - version "0.5.1" - resolved "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.5.1.tgz" - integrity sha512-U/GsFfFox88lXULmFJ9Shfl2aQGcwoKPF7fawSCLixIKtMCpsI+1r0h+5i0nQnmt9tHuzXZDL8+Dg1z6OhkI9A== +"@expo/json-file@^8.3.0", "@expo/json-file@~8.3.0": + version "8.3.3" + resolved "https://registry.npmjs.org/@expo/json-file/-/json-file-8.3.3.tgz" + integrity sha512-eZ5dld9AD0PrVRiIWpRkm5aIoWBw3kAyd8VkuWEy92sEthBKDDDHAnK2a0dw0Eil6j7rK7lS/Qaq/Zzngv2h5A== dependencies: - "@expo/spawn-async" "^1.7.2" - chalk "^4.0.0" - fs-extra "9.0.0" - getenv "^1.0.0" - jimp-compact "0.16.1" - node-fetch "^2.6.0" - parse-png "^2.1.0" - resolve-from "^5.0.0" - semver "^7.6.0" - tempy "0.3.0" + "@babel/code-frame" "~7.10.4" + json5 "^2.2.2" + write-file-atomic "^2.3.0" "@expo/json-file@8.2.36": version "8.2.36" @@ -1146,15 +1162,6 @@ json5 "^1.0.1" write-file-atomic "^2.3.0" -"@expo/json-file@^8.3.0", "@expo/json-file@~8.3.0": - version "8.3.3" - resolved "https://registry.npmjs.org/@expo/json-file/-/json-file-8.3.3.tgz" - integrity sha512-eZ5dld9AD0PrVRiIWpRkm5aIoWBw3kAyd8VkuWEy92sEthBKDDDHAnK2a0dw0Eil6j7rK7lS/Qaq/Zzngv2h5A== - dependencies: - "@babel/code-frame" "~7.10.4" - json5 "^2.2.2" - write-file-atomic "^2.3.0" - "@expo/metro-config@0.18.11": version "0.18.11" resolved "https://registry.npmjs.org/@expo/metro-config/-/metro-config-0.18.11.tgz" @@ -1210,15 +1217,6 @@ split "^1.0.1" sudo-prompt "9.1.1" -"@expo/plist@0.0.18": - version "0.0.18" - resolved "https://registry.npmjs.org/@expo/plist/-/plist-0.0.18.tgz" - integrity sha512-+48gRqUiz65R21CZ/IXa7RNBXgAI/uPSdvJqoN9x1hfL44DNbUoWHgHiEXTx7XelcATpDwNTz6sHLfy0iNqf+w== - dependencies: - "@xmldom/xmldom" "~0.7.0" - base64-js "^1.2.3" - xmlbuilder "^14.0.0" - "@expo/plist@^0.1.0": version "0.1.3" resolved "https://registry.npmjs.org/@expo/plist/-/plist-0.1.3.tgz" @@ -1228,6 +1226,15 @@ base64-js "^1.2.3" xmlbuilder "^14.0.0" +"@expo/plist@0.0.18": + version "0.0.18" + resolved "https://registry.npmjs.org/@expo/plist/-/plist-0.0.18.tgz" + integrity sha512-+48gRqUiz65R21CZ/IXa7RNBXgAI/uPSdvJqoN9x1hfL44DNbUoWHgHiEXTx7XelcATpDwNTz6sHLfy0iNqf+w== + dependencies: + "@xmldom/xmldom" "~0.7.0" + base64-js "^1.2.3" + xmlbuilder "^14.0.0" + "@expo/prebuild-config@5.0.7": version "5.0.7" resolved "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-5.0.7.tgz" @@ -1306,13 +1313,6 @@ debug "^4.3.4" source-map-support "~0.5.21" -"@expo/spawn-async@1.5.0": - version "1.5.0" - resolved "https://registry.npmjs.org/@expo/spawn-async/-/spawn-async-1.5.0.tgz" - integrity sha512-LB7jWkqrHo+5fJHNrLAFdimuSXQ2MQ4lA7SQW5bf/HbsXuV2VrT/jN/M8f/KoWt0uJMGN4k/j7Opx4AvOOxSew== - dependencies: - cross-spawn "^6.0.5" - "@expo/spawn-async@^1.7.2": version "1.7.2" resolved "https://registry.npmjs.org/@expo/spawn-async/-/spawn-async-1.7.2.tgz" @@ -1320,6 +1320,13 @@ dependencies: cross-spawn "^7.0.3" +"@expo/spawn-async@1.5.0": + version "1.5.0" + resolved "https://registry.npmjs.org/@expo/spawn-async/-/spawn-async-1.5.0.tgz" + integrity sha512-LB7jWkqrHo+5fJHNrLAFdimuSXQ2MQ4lA7SQW5bf/HbsXuV2VrT/jN/M8f/KoWt0uJMGN4k/j7Opx4AvOOxSew== + dependencies: + cross-spawn "^6.0.5" + "@expo/vector-icons@^14.0.2", "@expo/vector-icons@^14.0.3": version "14.0.3" resolved "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-14.0.3.tgz" @@ -1474,7 +1481,7 @@ "@firebase/util" "1.9.6" tslib "^2.1.0" -"@firebase/database-compat@1.0.5", "@firebase/database-compat@^1.0.2": +"@firebase/database-compat@^1.0.2", "@firebase/database-compat@1.0.5": version "1.0.5" resolved "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-1.0.5.tgz" integrity sha512-NDSMaDjQ+TZEMDMmzJwlTL05kh1+0Y84C+kVMaOmNOzRGRM7VHi29I6YUhCetXH+/b1Wh4ZZRyp1CuWkd8s6hg== @@ -1486,7 +1493,7 @@ "@firebase/util" "1.9.6" tslib "^2.1.0" -"@firebase/database-types@1.0.3", "@firebase/database-types@^1.0.0": +"@firebase/database-types@^1.0.0", "@firebase/database-types@1.0.3": version "1.0.3" resolved "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.3.tgz" integrity sha512-39V/Riv2R3O/aUjYKh0xypj7NTNXNAK1bcgY5Kx+hdQPRS/aPTS8/5c0CGFYKgVuFbYlnlnhrCTYsh2uNhGwzA== @@ -2133,7 +2140,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": +"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -2640,16 +2647,16 @@ resolved "https://registry.npmjs.org/@react-native/normalize-color/-/normalize-color-2.1.0.tgz" integrity sha512-Z1jQI2NpdFJCVgpY+8Dq/Bt3d+YUi1928Q+/CZm/oh66fzM0RUl54vvuXlPJKybH4pdCZey1eDTPaLHkMPNgWA== +"@react-native/normalize-colors@^0.74.1", "@react-native/normalize-colors@0.74.85": + version "0.74.85" + resolved "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.74.85.tgz" + integrity sha512-pcE4i0X7y3hsAE0SpIl7t6dUc0B0NZLd1yv7ssm4FrLhWG+CGyIq4eFDXpmPU1XHmL5PPySxTAjEMiwv6tAmOw== + "@react-native/normalize-colors@0.74.84": version "0.74.84" resolved "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.74.84.tgz" integrity sha512-Y5W6x8cC5RuakUcTVUFNAIhUZ/tYpuqHZlRBoAuakrTwVuoNHXfQki8lj1KsYU7rW6e3VWgdEx33AfOQpdNp6A== -"@react-native/normalize-colors@0.74.85", "@react-native/normalize-colors@^0.74.1": - version "0.74.85" - resolved "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.74.85.tgz" - integrity sha512-pcE4i0X7y3hsAE0SpIl7t6dUc0B0NZLd1yv7ssm4FrLhWG+CGyIq4eFDXpmPU1XHmL5PPySxTAjEMiwv6tAmOw== - "@react-native/virtualized-lists@0.74.85": version "0.74.85" resolved "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.74.85.tgz" @@ -2928,15 +2935,6 @@ "@types/range-parser" "*" "@types/send" "*" -"@types/express@4.17.3": - version "4.17.3" - resolved "https://registry.npmjs.org/@types/express/-/express-4.17.3.tgz" - integrity sha512-I8cGRJj3pyOLs/HndoP+25vOqhqWkAZsWMEmq1qXy/b/M3ppufecUwaK2/TVDVxcV61/iSdhykUjQQ2DLSrTdg== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "*" - "@types/serve-static" "*" - "@types/express@^4.17.17": version "4.17.21" resolved "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz" @@ -2947,6 +2945,15 @@ "@types/qs" "*" "@types/serve-static" "*" +"@types/express@4.17.3": + version "4.17.3" + resolved "https://registry.npmjs.org/@types/express/-/express-4.17.3.tgz" + integrity sha512-I8cGRJj3pyOLs/HndoP+25vOqhqWkAZsWMEmq1qXy/b/M3ppufecUwaK2/TVDVxcV61/iSdhykUjQQ2DLSrTdg== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "*" + "@types/serve-static" "*" + "@types/graceful-fs@^4.1.3": version "4.1.9" resolved "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz" @@ -3037,7 +3044,7 @@ dependencies: "@types/node" "*" -"@types/node@*", "@types/node@>=12.12.47", "@types/node@>=13.7.0", "@types/node@^18.0.0": +"@types/node@*", "@types/node@^18.0.0", "@types/node@>=12.12.47", "@types/node@>=13.7.0": version "18.19.45" resolved "https://registry.npmjs.org/@types/node/-/node-18.19.45.tgz" integrity sha512-VZxPKNNhjKmaC1SUYowuXSRSMGyQGmQjvvA1xE4QZ0xce2kLtEhPDS+kqpCPBZYgqblCLQ2DAjSzmgCM5auvhA== @@ -3152,7 +3159,7 @@ dependencies: "@types/yargs-parser" "*" -"@urql/core@2.3.6", "@urql/core@>=2.3.1": +"@urql/core@>=2.3.1", "@urql/core@2.3.6": version "2.3.6" resolved "https://registry.npmjs.org/@urql/core/-/core-2.3.6.tgz" integrity sha512-PUxhtBh7/8167HJK6WqBv6Z0piuiaZHQGYbhwpNL9aIQmLROPEdaUYkY4wh45wPQXcTpnd11l0q3Pw+TI11pdw== @@ -3178,7 +3185,12 @@ resolved "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz" integrity sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw== -"@xmldom/xmldom@~0.7.0", "@xmldom/xmldom@~0.7.7": +"@xmldom/xmldom@~0.7.0": + version "0.7.13" + resolved "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.13.tgz" + integrity sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g== + +"@xmldom/xmldom@~0.7.7": version "0.7.13" resolved "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.13.tgz" integrity sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g== @@ -3233,13 +3245,6 @@ acorn@^8.1.0, acorn@^8.11.0, acorn@^8.8.1, acorn@^8.8.2: resolved "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz" integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== -agent-base@6: - version "6.0.2" - resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - agent-base@^7.0.2: version "7.1.1" resolved "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz" @@ -3247,6 +3252,13 @@ agent-base@^7.0.2: dependencies: debug "^4.3.4" +agent-base@6: + version "6.0.2" + resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + aggregate-error@^3.0.0: version "3.1.0" resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" @@ -3269,16 +3281,6 @@ ajv-keywords@^5.1.0: dependencies: fast-deep-equal "^3.1.3" -ajv@8.11.0: - version "8.11.0" - resolved "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz" - integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - ajv@^8.0.0, ajv@^8.11.0, ajv@^8.9.0: version "8.17.1" resolved "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz" @@ -3289,6 +3291,16 @@ ajv@^8.0.0, ajv@^8.11.0, ajv@^8.9.0: json-schema-traverse "^1.0.0" require-from-string "^2.0.2" +ajv@8.11.0: + version "8.11.0" + resolved "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz" + integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + anser@^1.4.9: version "1.4.10" resolved "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz" @@ -3315,7 +3327,12 @@ ansi-fragments@^0.2.1: slice-ansi "^2.0.0" strip-ansi "^5.0.0" -ansi-regex@^4.0.0, ansi-regex@^4.1.0: +ansi-regex@^4.0.0: + version "4.1.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz" + integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== + +ansi-regex@^4.1.0: version "4.1.1" resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz" integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== @@ -3330,7 +3347,14 @@ ansi-regex@^6.0.1: resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz" integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== -ansi-styles@^3.2.0, ansi-styles@^3.2.1: +ansi-styles@^3.2.0: + version "3.2.1" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== @@ -3660,7 +3684,7 @@ better-opn@~3.0.2: dependencies: open "^8.0.4" -big-integer@1.6.x, big-integer@^1.6.16: +big-integer@^1.6.16, big-integer@1.6.x: version "1.6.52" resolved "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz" integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg== @@ -3731,13 +3755,6 @@ bplist-creator@0.1.0: dependencies: stream-buffers "2.2.x" -bplist-parser@0.3.1: - version "0.3.1" - resolved "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.1.tgz" - integrity sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA== - dependencies: - big-integer "1.6.x" - bplist-parser@^0.3.1: version "0.3.2" resolved "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.2.tgz" @@ -3745,6 +3762,13 @@ bplist-parser@^0.3.1: dependencies: big-integer "1.6.x" +bplist-parser@0.3.1: + version "0.3.1" + resolved "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.1.tgz" + integrity sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA== + dependencies: + big-integer "1.6.x" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" @@ -3922,15 +3946,16 @@ caniuse-lite@^1.0.30001646: resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz" integrity sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg== -chalk@4, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== +chalk@^2.0.1: + version "2.4.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" -chalk@^2.0.1, chalk@^2.4.2: +chalk@^2.4.2: version "2.4.2" resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -3947,6 +3972,14 @@ chalk@^3.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" +chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2, chalk@4: + version "4.1.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + char-regex@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz" @@ -3957,7 +3990,7 @@ char-regex@^2.0.0: resolved "https://registry.npmjs.org/char-regex/-/char-regex-2.0.1.tgz" integrity sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw== -charenc@0.0.2, charenc@~0.0.1: +charenc@~0.0.1, charenc@0.0.2: version "0.0.2" resolved "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz" integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA== @@ -4087,7 +4120,7 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@1.1.3, color-name@^1.0.0: +color-name@^1.0.0, color-name@1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== @@ -4245,17 +4278,17 @@ convert-source-map@^2.0.0: resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" - integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== - cookie-signature@^1.1.0: version "1.2.1" resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.1.tgz" integrity sha512-78KWk9T26NhzXtuL26cIJ8/qNHANyJ/ZYrmEXFzUmhZdjpBv+DlWlOANRTGBt48YcyslsLrj0bMLFTmXvLRCOw== -cookie@0.6.0, cookie@^0.6.0: +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@^0.6.0, cookie@0.6.0: version "0.6.0" resolved "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz" integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== @@ -4310,7 +4343,18 @@ cross-fetch@^3.1.5: dependencies: node-fetch "^2.6.12" -cross-spawn@^6.0.0, cross-spawn@^6.0.5: +cross-spawn@^6.0.0: + version "6.0.5" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== @@ -4330,7 +4374,7 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -crypt@0.0.2, crypt@~0.0.1: +crypt@~0.0.1, crypt@0.0.2: version "0.0.2" resolved "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz" integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow== @@ -4466,19 +4510,19 @@ debounce@^2.1.1: resolved "https://registry.npmjs.org/debounce/-/debounce-2.1.1.tgz" integrity sha512-+xRWxgel9LgTC4PwKlm7TJUK6B6qsEK77NaiNvXmeQ7Y3e6OVVsBC4a9BSptS/mAYceyAz37Oa8JTTuPRft7uQ== -debug@2.6.9, debug@^2.2.0, debug@^2.6.9: +debug@^2.2.0: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: - version "4.3.6" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz" - integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg== +debug@^2.6.9: + version "2.6.9" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: - ms "2.1.2" + ms "2.0.0" debug@^3.1.0: version "3.2.7" @@ -4487,6 +4531,20 @@ debug@^3.1.0: dependencies: ms "^2.1.1" +debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@4: + version "4.3.6" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz" + integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg== + dependencies: + ms "2.1.2" + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + decamelize@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz" @@ -4694,7 +4752,7 @@ eastasianwidth@^0.2.0: resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== -ecdsa-sig-formatter@1.0.11, ecdsa-sig-formatter@^1.0.11: +ecdsa-sig-formatter@^1.0.11, ecdsa-sig-formatter@1.0.11: version "1.0.11" resolved "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz" integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== @@ -5232,13 +5290,6 @@ expo-router@~3.5.20: react-native-helmet-async "2.0.4" schema-utils "^4.0.1" -expo-splash-screen@0.27.5, expo-splash-screen@~0.27.5: - version "0.27.5" - resolved "https://registry.npmjs.org/expo-splash-screen/-/expo-splash-screen-0.27.5.tgz" - integrity sha512-9rdZuLkFCfgJBxrheUsOEOIW6Rp+9NVlpSE0hgXQwbTCLTncf00IHSE8/L2NbFyeDLNjof1yZBppaV7tXHRUzA== - dependencies: - "@expo/prebuild-config" "7.0.6" - expo-splash-screen@~0.17.0: version "0.17.5" resolved "https://registry.npmjs.org/expo-splash-screen/-/expo-splash-screen-0.17.5.tgz" @@ -5247,6 +5298,13 @@ expo-splash-screen@~0.17.0: "@expo/configure-splash-screen" "^0.6.0" "@expo/prebuild-config" "5.0.7" +expo-splash-screen@~0.27.5, expo-splash-screen@0.27.5: + version "0.27.5" + resolved "https://registry.npmjs.org/expo-splash-screen/-/expo-splash-screen-0.27.5.tgz" + integrity sha512-9rdZuLkFCfgJBxrheUsOEOIW6Rp+9NVlpSE0hgXQwbTCLTncf00IHSE8/L2NbFyeDLNjof1yZBppaV7tXHRUzA== + dependencies: + "@expo/prebuild-config" "7.0.6" + expo-status-bar@~1.12.1: version "1.12.1" resolved "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-1.12.1.tgz" @@ -5527,7 +5585,15 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" -find-up@^4.0.0, find-up@^4.1.0: +find-up@^4.0.0: + version "4.1.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +find-up@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== @@ -5701,17 +5767,7 @@ fresh@0.5.2: resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== -fs-extra@9.0.0: - version "9.0.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.0.tgz" - integrity sha512-pmEYSk3vYsG/bF651KPUXZ+hvjpgWYw/Gc7W9NFUe3ZVLczKKWIij3IKpOrQcdw4TILtibFslZ0UmR8Vvzig4g== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^1.0.0" - -fs-extra@^8.1.0, fs-extra@~8.1.0: +fs-extra@^8.1.0: version "8.1.0" resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz" integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== @@ -5730,6 +5786,25 @@ fs-extra@^9.0.0, fs-extra@^9.1.0: jsonfile "^6.0.1" universalify "^2.0.0" +fs-extra@~8.1.0: + version "8.1.0" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@9.0.0: + version "9.0.0" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.0.tgz" + integrity sha512-pmEYSk3vYsG/bF651KPUXZ+hvjpgWYw/Gc7W9NFUe3ZVLczKKWIij3IKpOrQcdw4TILtibFslZ0UmR8Vvzig4g== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^1.0.0" + fs-minipass@^2.0.0: version "2.1.0" resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz" @@ -5879,19 +5954,19 @@ glob-parent@^5.1.2: dependencies: is-glob "^4.0.1" -glob@7.1.6: - version "7.1.6" - resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== +glob@^10.2.2: + version "10.4.5" + resolved "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz" + integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" + foreground-child "^3.1.0" + jackspeak "^3.1.2" + minimatch "^9.0.4" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^1.11.1" -glob@^10.2.2, glob@^10.4.2: +glob@^10.4.2: version "10.4.5" resolved "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz" integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== @@ -5915,6 +5990,18 @@ glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.1.7, glob@^7.2.3: once "^1.3.0" path-is-absolute "^1.0.0" +glob@7.1.6: + version "7.1.6" + resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + globals@^11.1.0: version "11.12.0" resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" @@ -6231,7 +6318,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: +inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@2, inherits@2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -6266,7 +6353,7 @@ internal-slot@^1.0.7: hasown "^2.0.0" side-channel "^1.0.4" -invariant@*, invariant@2.2.4, invariant@^2.2.4: +invariant@*, invariant@^2.2.4, invariant@2.2.4: version "2.2.4" resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz" integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== @@ -6278,7 +6365,7 @@ ip-regex@^2.1.0: resolved "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz" integrity sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw== -ipaddr.js@1.9.1, ipaddr.js@^1.9.0: +ipaddr.js@^1.9.0, ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== @@ -7338,41 +7425,6 @@ lightningcss-darwin-arm64@1.19.0: resolved "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.19.0.tgz" integrity sha512-wIJmFtYX0rXHsXHSr4+sC5clwblEMji7HHQ4Ub1/CznVRxtCFha6JIt5JZaNf8vQrfdZnBxLLC6R8pC818jXqg== -lightningcss-darwin-x64@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.19.0.tgz#c867308b88859ba61a2c46c82b1ca52ff73a1bd0" - integrity sha512-Lif1wD6P4poaw9c/4Uh2z+gmrWhw/HtXFoeZ3bEsv6Ia4tt8rOJBdkfVaUJ6VXmpKHALve+iTyP2+50xY1wKPw== - -lightningcss-linux-arm-gnueabihf@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.19.0.tgz#0f921dc45f2e5c3aea70fab98844ac0e5f2f81be" - integrity sha512-P15VXY5682mTXaiDtbnLYQflc8BYb774j2R84FgDLJTN6Qp0ZjWEFyN1SPqyfTj2B2TFjRHRUvQSSZ7qN4Weig== - -lightningcss-linux-arm64-gnu@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.19.0.tgz#027f9df9c7f4ffa127c37a71726245a5794d7ba2" - integrity sha512-zwXRjWqpev8wqO0sv0M1aM1PpjHz6RVIsBcxKszIG83Befuh4yNysjgHVplF9RTU7eozGe3Ts7r6we1+Qkqsww== - -lightningcss-linux-arm64-musl@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.19.0.tgz#85ea987da868524eac6db94f8e1eaa23d0b688a3" - integrity sha512-vSCKO7SDnZaFN9zEloKSZM5/kC5gbzUjoJQ43BvUpyTFUX7ACs/mDfl2Eq6fdz2+uWhUh7vf92c4EaaP4udEtA== - -lightningcss-linux-x64-gnu@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.19.0.tgz#02bec89579ab4153dccc0def755d1fd9e3ee7f3c" - integrity sha512-0AFQKvVzXf9byrXUq9z0anMGLdZJS+XSDqidyijI5njIwj6MdbvX2UZK/c4FfNmeRa2N/8ngTffoIuOUit5eIQ== - -lightningcss-linux-x64-musl@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.19.0.tgz#e36a5df8193ae961d22974635e4c100a1823bb8c" - integrity sha512-SJoM8CLPt6ECCgSuWe+g0qo8dqQYVcPiW2s19dxkmSI5+Uu1GIRzyKA0b7QqmEXolA+oSJhQqCmJpzjY4CuZAg== - -lightningcss-win32-x64-msvc@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.19.0.tgz#0854dbd153035eca1396e2227c708ad43655a61c" - integrity sha512-C+VuUTeSUOAaBZZOPT7Etn/agx/MatzJzGRkeV+zEABmPuntv1zihncsi+AyGmjkkzq3wVedEy7h0/4S84mUtg== - lightningcss@~1.19.0: version "1.19.0" resolved "https://registry.npmjs.org/lightningcss/-/lightningcss-1.19.0.tgz" @@ -7431,7 +7483,7 @@ lodash.clonedeep@^4.5.0: resolved "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz" integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== -lodash.debounce@4.0.8, lodash.debounce@^4.0.8: +lodash.debounce@^4.0.8, lodash.debounce@4.0.8: version "4.0.8" resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== @@ -7517,13 +7569,6 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" -lru-cache@6.0.0, lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - lru-cache@^10.0.1, lru-cache@^10.2.0: version "10.4.3" resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz" @@ -7536,6 +7581,20 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +lru-cache@6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + lru-memoizer@^2.2.0: version "2.3.0" resolved "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.3.0.tgz" @@ -7680,7 +7739,7 @@ metro-cache@0.80.10: flow-enums-runtime "^0.0.6" metro-core "0.80.10" -metro-config@0.80.10, metro-config@^0.80.3: +metro-config@^0.80.3, metro-config@0.80.10: version "0.80.10" resolved "https://registry.npmjs.org/metro-config/-/metro-config-0.80.10.tgz" integrity sha512-0GYAw0LkmGbmA81FepKQepL1KU/85Cyv7sAiWm6QWeV6AcVCpsKg6jGLqGHJ0LLPL60rWzA4TV1DQAlzdJAEtA== @@ -7694,7 +7753,7 @@ metro-config@0.80.10, metro-config@^0.80.3: metro-core "0.80.10" metro-runtime "0.80.10" -metro-core@0.80.10, metro-core@^0.80.3: +metro-core@^0.80.3, metro-core@0.80.10: version "0.80.10" resolved "https://registry.npmjs.org/metro-core/-/metro-core-0.80.10.tgz" integrity sha512-nwBB6HbpGlNsZMuzxVqxqGIOsn5F3JKpsp8PziS7Z4mV8a/jA1d44mVOgYmDa2q5WlH5iJfRIIhdz24XRNDlLA== @@ -7737,7 +7796,7 @@ metro-resolver@0.80.10: dependencies: flow-enums-runtime "^0.0.6" -metro-runtime@0.80.10, metro-runtime@^0.80.3: +metro-runtime@^0.80.3, metro-runtime@0.80.10: version "0.80.10" resolved "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.80.10.tgz" integrity sha512-Xh0N589ZmSIgJYAM+oYwlzTXEHfASZac9TYPCNbvjNTn0EHKqpoJ/+Im5G3MZT4oZzYv4YnvzRtjqS5k0tK94A== @@ -7745,7 +7804,7 @@ metro-runtime@0.80.10, metro-runtime@^0.80.3: "@babel/runtime" "^7.0.0" flow-enums-runtime "^0.0.6" -metro-source-map@0.80.10, metro-source-map@^0.80.3: +metro-source-map@^0.80.3, metro-source-map@0.80.10: version "0.80.10" resolved "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.80.10.tgz" integrity sha512-EyZswqJW8Uukv/HcQr6K19vkMXW1nzHAZPWJSEyJFKIbgp708QfRZ6vnZGmrtFxeJEaFdNup4bGnu8/mIOYlyA== @@ -7804,7 +7863,7 @@ metro-transform-worker@0.80.10: metro-transform-plugins "0.80.10" nullthrows "^1.1.1" -metro@0.80.10, metro@^0.80.3: +metro@^0.80.3, metro@0.80.10: version "0.80.10" resolved "https://registry.npmjs.org/metro/-/metro-0.80.10.tgz" integrity sha512-FDPi0X7wpafmDREXe1lgg3WzETxtXh6Kpq8+IwsG35R2tMyp2kFIqDdshdohuvDt1J/qDARcEPq7V/jElTb1kA== @@ -7866,7 +7925,7 @@ microseconds@0.2.0: resolved "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz" integrity sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA== -mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": +"mime-db@>= 1.43.0 < 2", mime-db@1.52.0: version "1.52.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== @@ -7878,12 +7937,12 @@ mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.24, mime-types@~2.1.34: dependencies: mime-db "1.52.0" -mime@1.6.0: - version "1.6.0" - resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +mime@^2.4.1: + version "2.6.0" + resolved "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== -mime@^2.4.1, mime@^2.4.4: +mime@^2.4.4: version "2.6.0" resolved "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz" integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== @@ -7893,6 +7952,11 @@ mime@^3.0.0: resolved "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz" integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== +mime@1.6.0: + version "1.6.0" + resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz" @@ -7950,16 +8014,16 @@ minipass@^3.0.0: dependencies: yallist "^4.0.0" -minipass@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz" - integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== - "minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.3, minipass@^7.1.2: version "7.1.2" resolved "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz" integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== +minipass@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz" + integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== + minizlib@^2.1.1: version "2.1.2" resolved "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz" @@ -7983,7 +8047,12 @@ mkdirp@^0.5.1: dependencies: minimist "^1.2.6" -mkdirp@^1.0.3, mkdirp@^1.0.4: +mkdirp@^1.0.3: + version "1.0.4" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== @@ -7998,16 +8067,16 @@ mrmime@^1.0.0: resolved "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz" integrity sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw== +ms@^2.1.1, ms@2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + ms@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== -ms@2.1.2, ms@^2.1.1: - version "2.1.2" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - ms@2.1.3: version "2.1.3" resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" @@ -8213,13 +8282,6 @@ oblivious-set@1.0.0: resolved "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.0.0.tgz" integrity sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw== -on-finished@2.4.1: - version "2.4.1" - resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" - integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== - dependencies: - ee-first "1.1.1" - on-finished@~2.3.0: version "2.3.0" resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" @@ -8227,6 +8289,13 @@ on-finished@~2.3.0: dependencies: ee-first "1.1.1" +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + on-headers@~1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz" @@ -8277,7 +8346,7 @@ open@^8.0.4, open@^8.3.0: is-docker "^2.1.1" is-wsl "^2.2.0" -ora@3.4.0, ora@^3.4.0: +ora@^3.4.0: version "3.4.0" resolved "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz" integrity sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg== @@ -8304,6 +8373,18 @@ ora@^5.4.1: strip-ansi "^6.0.0" wcwidth "^1.0.1" +ora@3.4.0: + version "3.4.0" + resolved "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz" + integrity sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg== + dependencies: + chalk "^2.4.2" + cli-cursor "^2.1.0" + cli-spinners "^2.0.0" + log-symbols "^2.2.0" + strip-ansi "^5.2.0" + wcwidth "^1.0.1" + os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz" @@ -8332,7 +8413,14 @@ p-finally@^2.0.0: resolved "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz" integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw== -p-limit@^2.0.0, p-limit@^2.2.0: +p-limit@^2.0.0: + version "2.3.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^2.2.0: version "2.3.0" resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== @@ -8574,7 +8662,17 @@ pretty-format@^24: ansi-styles "^3.2.0" react-is "^16.8.4" -pretty-format@^26.5.2, pretty-format@^26.6.2: +pretty-format@^26.5.2: + version "26.6.2" + resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz" + integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg== + dependencies: + "@jest/types" "^26.6.2" + ansi-regex "^5.0.0" + ansi-styles "^4.0.0" + react-is "^17.0.1" + +pretty-format@^26.6.2: version "26.6.2" resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz" integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg== @@ -8625,7 +8723,7 @@ prompts@^2.0.1, prompts@^2.2.1, prompts@^2.3.2, prompts@^2.4.2: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@*, prop-types@15.8.1, prop-types@^15.5.10, prop-types@^15.7.2, prop-types@^15.8.0, prop-types@^15.8.1: +prop-types@*, prop-types@^15.5.10, prop-types@^15.7.2, prop-types@^15.8.0, prop-types@^15.8.1, prop-types@15.8.1: version "15.8.1" resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -8809,7 +8907,12 @@ react-is@^17.0.1: resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -react-is@^18.0.0, react-is@^18.2.0: +react-is@^18.0.0: + version "18.3.1" + resolved "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz" + integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== + +react-is@^18.2.0: version "18.3.1" resolved "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz" integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== @@ -9289,7 +9392,7 @@ reusify@^1.0.4: resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@3.0.2, rimraf@^3.0.2: +rimraf@^3.0.2, rimraf@3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== @@ -9325,15 +9428,20 @@ safe-array-concat@^1.1.2: has-symbols "^1.0.3" isarray "^2.0.5" -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@^5.0.1, safe-buffer@>=5.1.0, safe-buffer@~5.2.0, safe-buffer@5.2.1: + version "5.2.1" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-buffer@5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== safe-regex-test@^1.0.3: version "1.0.3" @@ -9349,7 +9457,7 @@ safe-regex-test@^1.0.3: resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sax@>=0.6.0, sax@^1.2.4: +sax@^1.2.4, sax@>=0.6.0: version "1.4.1" resolved "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz" integrity sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg== @@ -9361,13 +9469,6 @@ saxes@^6.0.0: dependencies: xmlchars "^2.2.0" -scheduler@0.24.0-canary-efb381bbf-20230505: - version "0.24.0-canary-efb381bbf-20230505" - resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.24.0-canary-efb381bbf-20230505.tgz" - integrity sha512-ABvovCDe/k9IluqSh4/ISoq8tIJnW8euVAWYt5j/bg6dRnqwQwiGO1F/V4AyK96NGF/FB04FhOUDuWj8IKfABA== - dependencies: - loose-envify "^1.1.0" - scheduler@^0.23.0: version "0.23.2" resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz" @@ -9375,6 +9476,13 @@ scheduler@^0.23.0: dependencies: loose-envify "^1.1.0" +scheduler@0.24.0-canary-efb381bbf-20230505: + version "0.24.0-canary-efb381bbf-20230505" + resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.24.0-canary-efb381bbf-20230505.tgz" + integrity sha512-ABvovCDe/k9IluqSh4/ISoq8tIJnW8euVAWYt5j/bg6dRnqwQwiGO1F/V4AyK96NGF/FB04FhOUDuWj8IKfABA== + dependencies: + loose-envify "^1.1.0" + schema-utils@^4.0.1: version "4.2.0" resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz" @@ -9393,17 +9501,27 @@ selfsigned@^2.4.1: "@types/node-forge" "^1.3.0" node-forge "^1" -semver@7.3.2: - version "7.3.2" - resolved "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz" - integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== - -semver@^5.2.0, semver@^5.5.0, semver@^5.6.0: +semver@^5.2.0: version "5.7.2" resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^6.3.0, semver@^6.3.1: +semver@^5.5.0: + version "5.7.2" + resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + +semver@^5.6.0: + version "5.7.2" + resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + +semver@^6.3.0: + version "6.3.1" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^6.3.1: version "6.3.1" resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== @@ -9413,24 +9531,10 @@ semver@^7.3.5, semver@^7.5.2, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0: resolved "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== -send@0.19.0: - version "0.19.0" - resolved "https://registry.npmjs.org/send/-/send-0.19.0.tgz" - integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== - dependencies: - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "2.0.0" - mime "1.6.0" - ms "2.1.3" - on-finished "2.4.1" - range-parser "~1.2.1" - statuses "2.0.1" +semver@7.3.2: + version "7.3.2" + resolved "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz" + integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== send@^0.18.0: version "0.18.0" @@ -9451,12 +9555,31 @@ send@^0.18.0: range-parser "~1.2.1" statuses "2.0.1" +send@0.19.0: + version "0.19.0" + resolved "https://registry.npmjs.org/send/-/send-0.19.0.tgz" + integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + serialize-error@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz" integrity sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw== -serve-static@1.16.2, serve-static@^1.13.1: +serve-static@^1.13.1, serve-static@1.16.2: version "1.16.2" resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz" integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw== @@ -9628,14 +9751,6 @@ source-map-js@^1.2.0: resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz" integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== -source-map-support@0.5.13: - version "0.5.13" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz" - integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - source-map-support@^0.5.16, source-map-support@^0.5.21, source-map-support@~0.5.20, source-map-support@~0.5.21: version "0.5.21" resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" @@ -9644,12 +9759,20 @@ source-map-support@^0.5.16, source-map-support@^0.5.21, source-map-support@~0.5. buffer-from "^1.0.0" source-map "^0.6.0" -source-map@0.5.6: - version "0.5.6" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz" - integrity sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA== +source-map-support@0.5.13: + version "0.5.13" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" -source-map@^0.5.0, source-map@^0.5.6: +source-map@^0.5.0: + version "0.5.7" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== + +source-map@^0.5.6: version "0.5.7" resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== @@ -9664,6 +9787,11 @@ source-map@^0.7.3: resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz" integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== +source-map@0.5.6: + version "0.5.6" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz" + integrity sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA== + split-on-first@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz" @@ -9731,17 +9859,17 @@ stacktrace-parser@^0.1.10: dependencies: type-fest "^0.7.1" -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - statuses@~1.5.0: version "1.5.0" resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -stream-buffers@2.2.x, stream-buffers@~2.2.0: +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +stream-buffers@~2.2.0, stream-buffers@2.2.x: version "2.2.0" resolved "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz" integrity sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg== @@ -9768,6 +9896,20 @@ strict-uri-encode@^2.0.0: resolved "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz" integrity sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ== +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + string-length@^4.0.1: version "4.0.2" resolved "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz" @@ -9839,20 +9981,6 @@ string.prototype.trimstart@^1.0.8: define-properties "^1.2.1" es-object-atoms "^1.0.0" -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - "strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" @@ -9860,7 +9988,14 @@ string_decoder@~1.1.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^5.0.0, strip-ansi@^5.2.0: +strip-ansi@^5.0.0: + version "5.2.0" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz" integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== @@ -9926,7 +10061,7 @@ styleq@^0.1.3: resolved "https://registry.npmjs.org/styleq/-/styleq-0.1.3.tgz" integrity sha512-3ZUifmCDCQanjeej1f6kyl/BeP/Vae5EYkQ9iJfUm/QwZvlgnZzyflqAsAWYURdtea8Vkvswu2GrC57h3qffcA== -sucrase@3.34.0, sucrase@^3.20.0: +sucrase@^3.20.0, sucrase@3.34.0: version "3.34.0" resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz" integrity sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw== @@ -9939,11 +10074,6 @@ sucrase@3.34.0, sucrase@^3.20.0: pirates "^4.0.1" ts-interface-checker "^0.1.9" -sudo-prompt@9.1.1: - version "9.1.1" - resolved "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-9.1.1.tgz" - integrity sha512-es33J1g2HjMpyAhz8lOR+ICmXXAqTuKbuXuUWLhOLew20oN9oUCgCJx615U/v7aioZg7IX5lIh9x34vwneu4pA== - sudo-prompt@^8.2.0: version "8.2.5" resolved "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-8.2.5.tgz" @@ -9954,6 +10084,11 @@ sudo-prompt@^9.0.0: resolved "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-9.2.1.tgz" integrity sha512-Mu7R0g4ig9TUuGSxJavny5Rv0egCEtpZRNMrZaYS1vxkiIxGiGUwoezU3LazIQ+KE04hTrTfNPgxU5gzi7F5Pw== +sudo-prompt@9.1.1: + version "9.1.1" + resolved "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-9.1.1.tgz" + integrity sha512-es33J1g2HjMpyAhz8lOR+ICmXXAqTuKbuXuUWLhOLew20oN9oUCgCJx615U/v7aioZg7IX5lIh9x34vwneu4pA== + superstruct@^0.6.2: version "0.6.2" resolved "https://registry.npmjs.org/superstruct/-/superstruct-0.6.2.tgz" @@ -10046,15 +10181,6 @@ temp@^0.8.4: dependencies: rimraf "~2.6.2" -tempy@0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/tempy/-/tempy-0.3.0.tgz" - integrity sha512-WrH/pui8YCwmeiAoxV+lpRH9HpRtgBhSR2ViBPgpGb/wnYDzp21R4MN45fsCGvLROvY67o3byhJRYRONJyImVQ== - dependencies: - temp-dir "^1.0.0" - type-fest "^0.3.1" - unique-string "^1.0.0" - tempy@^0.7.1: version "0.7.1" resolved "https://registry.npmjs.org/tempy/-/tempy-0.7.1.tgz" @@ -10066,6 +10192,15 @@ tempy@^0.7.1: type-fest "^0.16.0" unique-string "^2.0.0" +tempy@0.3.0: + version "0.3.0" + resolved "https://registry.npmjs.org/tempy/-/tempy-0.3.0.tgz" + integrity sha512-WrH/pui8YCwmeiAoxV+lpRH9HpRtgBhSR2ViBPgpGb/wnYDzp21R4MN45fsCGvLROvY67o3byhJRYRONJyImVQ== + dependencies: + temp-dir "^1.0.0" + type-fest "^0.3.1" + unique-string "^1.0.0" + terminal-link@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz" @@ -10130,6 +10265,11 @@ throat@^5.0.0: resolved "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz" integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA== +through@2: + version "2.3.8" + resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + through2@^2.0.1: version "2.0.5" resolved "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz" @@ -10138,11 +10278,6 @@ through2@^2.0.1: readable-stream "~2.3.6" xtend "~4.0.1" -through@2: - version "2.3.8" - resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" - integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== - timezonecomplete@^5.13.1: version "5.13.1" resolved "https://registry.npmjs.org/timezonecomplete/-/timezonecomplete-5.13.1.tgz" @@ -10339,16 +10474,16 @@ typical@^2.6.0: resolved "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz" integrity sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg== -tzdata@1.0.25: - version "1.0.25" - resolved "https://registry.npmjs.org/tzdata/-/tzdata-1.0.25.tgz" - integrity sha512-yAZ/Tv/tBFIPHJGYrOexxW8Swyjszt7rDhIjnIPSqLaP8mzrr3T7D0w4cxQBtToXnQrlFqkEU0stGC/auz0JcQ== - tzdata@^1.0.42: version "1.0.42" resolved "https://registry.npmjs.org/tzdata/-/tzdata-1.0.42.tgz" integrity sha512-hVA4V8g27yz1YB4Ty4UliwJlWrFOoFrFBYFMd9rKUlRlaF+9Fl3gyzxF/+MQOtCH50pPE+XZ/bYOYkRnBDscVQ== +tzdata@1.0.25: + version "1.0.25" + resolved "https://registry.npmjs.org/tzdata/-/tzdata-1.0.25.tgz" + integrity sha512-yAZ/Tv/tBFIPHJGYrOexxW8Swyjszt7rDhIjnIPSqLaP8mzrr3T7D0w4cxQBtToXnQrlFqkEU0stGC/auz0JcQ== + ua-parser-js@^0.7.33: version "0.7.39" resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.39.tgz" @@ -10379,6 +10514,11 @@ undici-types@~6.19.2: resolved "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz" integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== +undici@^6.11.1: + version "6.19.8" + resolved "https://registry.npmjs.org/undici/-/undici-6.19.8.tgz" + integrity sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g== + undici@5.28.4: version "5.28.4" resolved "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz" @@ -10386,11 +10526,6 @@ undici@5.28.4: dependencies: "@fastify/busboy" "^2.0.0" -undici@^6.11.1: - version "6.19.8" - resolved "https://registry.npmjs.org/undici/-/undici-6.19.8.tgz" - integrity sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g== - unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz" @@ -10470,7 +10605,7 @@ unload@2.2.0: "@babel/runtime" "^7.6.2" detect-node "^2.0.4" -unpipe@1.0.0, unpipe@~1.0.0: +unpipe@~1.0.0, unpipe@1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== @@ -10549,7 +10684,12 @@ uuid@^8.0.0, uuid@^8.3.2: resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -uuid@^9.0.0, uuid@^9.0.1: +uuid@^9.0.0: + version "9.0.1" + resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== + +uuid@^9.0.1: version "9.0.1" resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz" integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== @@ -10599,7 +10739,7 @@ walker@^1.0.7, walker@^1.0.8: dependencies: makeerror "1.0.12" -warn-once@0.1.1, warn-once@^0.1.0: +warn-once@^0.1.0, warn-once@0.1.1: version "0.1.1" resolved "https://registry.npmjs.org/warn-once/-/warn-once-0.1.1.tgz" integrity sha512-VkQZJbO8zVImzYFteBXvBOZEl1qL175WH8VmZcxF2fZAoudNhNDvHi+doCaAEdU2l2vtcIwa2zn0QK5+I1HQ3Q== @@ -10823,12 +10963,22 @@ ws@^6.2.2: dependencies: async-limiter "~1.0.0" -ws@^7, ws@^7.5.10: +ws@^7: version "7.5.10" resolved "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz" integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== -ws@^8.11.0, ws@^8.12.1: +ws@^7.5.10: + version "7.5.10" + resolved "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz" + integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== + +ws@^8.11.0: + version "8.18.0" + resolved "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz" + integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== + +ws@^8.12.1: version "8.18.0" resolved "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz" integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== @@ -10937,7 +11087,24 @@ yargs-parser@^21.1.1: resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== -yargs@^15.1.0, yargs@^15.3.1: +yargs@^15.1.0: + version "15.4.1" + resolved "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz" + integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== + dependencies: + cliui "^6.0.0" + decamelize "^1.2.0" + find-up "^4.1.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^4.2.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^18.1.2" + +yargs@^15.3.1: version "15.4.1" resolved "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz" integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== From 802d0d9cd11846d481c5276125abdcb5b0929ffc Mon Sep 17 00:00:00 2001 From: Milan Paunovic Date: Tue, 22 Oct 2024 08:41:33 +0200 Subject: [PATCH 04/66] build nr updt --- app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.json b/app.json index 4b0b002..c8c22e9 100644 --- a/app.json +++ b/app.json @@ -16,7 +16,7 @@ "supportsTablet": true, "bundleIdentifier": "com.cally.app", "googleServicesFile": "./ios/GoogleService-Info.plist", - "buildNumber": "45", + "buildNumber": "46", "usesAppleSignIn": true }, "android": { From 2be5e7c4e4a61cea1c1d616bdd5679e95f5843e1 Mon Sep 17 00:00:00 2001 From: Milan Paunovic Date: Tue, 22 Oct 2024 10:33:05 +0200 Subject: [PATCH 05/66] clear edit event --- app.json | 2 +- components/pages/calendar/ManuallyAddEventModal.tsx | 1 + ios/cally/Info.plist | 5 ++++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app.json b/app.json index c8c22e9..aee25f1 100644 --- a/app.json +++ b/app.json @@ -16,7 +16,7 @@ "supportsTablet": true, "bundleIdentifier": "com.cally.app", "googleServicesFile": "./ios/GoogleService-Info.plist", - "buildNumber": "46", + "buildNumber": "47", "usesAppleSignIn": true }, "android": { diff --git a/components/pages/calendar/ManuallyAddEventModal.tsx b/components/pages/calendar/ManuallyAddEventModal.tsx index aacb252..1d9d7b6 100644 --- a/components/pages/calendar/ManuallyAddEventModal.tsx +++ b/components/pages/calendar/ManuallyAddEventModal.tsx @@ -161,6 +161,7 @@ export const ManuallyAddEventModal = () => { if (editEvent?.id) eventData.id = editEvent?.id await createEvent(eventData); + setEditEvent(undefined) close(); }; diff --git a/ios/cally/Info.plist b/ios/cally/Info.plist index f065a6d..c6a0e8d 100644 --- a/ios/cally/Info.plist +++ b/ios/cally/Info.plist @@ -47,7 +47,7 @@ CFBundleVersion - 45 + 47 LSRequiresIPhoneOS NSAppTransportSecurity @@ -121,6 +121,9 @@ $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route + $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route + $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route + $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route UILaunchStoryboardName SplashScreen From 1f45f5d21f4899adec6b1e1137f76c7155dbe094 Mon Sep 17 00:00:00 2001 From: Milan Paunovic Date: Tue, 22 Oct 2024 12:04:06 +0200 Subject: [PATCH 06/66] send notifications only if the event has no email address --- firebase/functions/index.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/firebase/functions/index.js b/firebase/functions/index.js index 475f6d8..292b51c 100644 --- a/firebase/functions/index.js +++ b/firebase/functions/index.js @@ -18,7 +18,12 @@ exports.sendNotificationOnEventCreation = functions.firestore .document('Events/{eventId}') .onCreate(async (snapshot, context) => { const eventData = snapshot.data(); - const {familyId, creatorId} = eventData; + const {familyId, creatorId, email} = eventData; + + if (email) { + console.log('Event has an email field. Skipping notification.'); + return; + } if (!familyId || !creatorId) { console.error('Missing familyId or creatorId in event data'); @@ -33,14 +38,12 @@ exports.sendNotificationOnEventCreation = functions.firestore } } - // Increment event count for debouncing eventCount++; if (notificationTimeout) { - clearTimeout(notificationTimeout); // Reset the timer if events keep coming + clearTimeout(notificationTimeout); } - // Set a debounce time (e.g., 5 seconds) notificationTimeout = setTimeout(async () => { const eventMessage = eventCount === 1 ? `An event "${eventData.title}" has been added. Check it out!` @@ -88,7 +91,7 @@ exports.sendNotificationOnEventCreation = functions.firestore eventCount = 0; // Reset the event count after sending notification pushTokens = []; // Reset push tokens for the next round - }, 5000); // Debounce time (5 seconds) + }, 5000); }); From bc54c902d9239eae4ca6d216e59b0a434bd7864d Mon Sep 17 00:00:00 2001 From: Milan Paunovic Date: Tue, 22 Oct 2024 12:28:43 +0200 Subject: [PATCH 07/66] Fix adding devices and fetching events --- .../settings/user_settings_views/MyGroup.tsx | 8 ++-- hooks/firebase/useGetEvents.ts | 42 ++++++++++++------- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/components/pages/settings/user_settings_views/MyGroup.tsx b/components/pages/settings/user_settings_views/MyGroup.tsx index e138682..fc313a7 100644 --- a/components/pages/settings/user_settings_views/MyGroup.tsx +++ b/components/pages/settings/user_settings_views/MyGroup.tsx @@ -67,10 +67,10 @@ const MyGroup = () => { return; } - if (selectedStatus !== ProfileType.FAMILY_DEVICE && !email) { - console.error("Email is required for non-family device users"); - return; - } + // if (selectedStatus !== ProfileType.FAMILY_DEVICE && !email) { + // console.error("Email is required for non-family device users"); + // return; + // } if (email && !email.includes("@")) { console.error("Invalid email address"); diff --git a/hooks/firebase/useGetEvents.ts b/hooks/firebase/useGetEvents.ts index c8c64d2..3b7254a 100644 --- a/hooks/firebase/useGetEvents.ts +++ b/hooks/firebase/useGetEvents.ts @@ -1,23 +1,24 @@ -import {useQuery} from "react-query"; +import { useQuery } from "react-query"; import firestore from "@react-native-firebase/firestore"; -import {useAuthContext} from "@/contexts/AuthContext"; -import {useAtomValue} from "jotai"; -import {isFamilyViewAtom} from "@/components/pages/calendar/atoms"; -import {colorMap} from "@/constants/colorMap"; +import { useAuthContext } from "@/contexts/AuthContext"; +import { useAtomValue } from "jotai"; +import { isFamilyViewAtom } from "@/components/pages/calendar/atoms"; +import { colorMap } from "@/constants/colorMap"; export const useGetEvents = () => { - const {user, profileData} = useAuthContext(); + const { user, profileData } = useAuthContext(); const isFamilyView = useAtomValue(isFamilyViewAtom); return useQuery({ queryKey: ["events", user?.uid, isFamilyView], queryFn: async () => { const db = firestore(); - const userId = user?.uid; const familyId = profileData?.familyId; + let allEvents = []; + // If family view is active, include family, creator, and attendee events if (isFamilyView) { const familyQuery = db.collection("Events").where("familyID", "==", familyId); const creatorQuery = db.collection("Events").where("creatorId", "==", userId); @@ -29,12 +30,14 @@ export const useGetEvents = () => { attendeeQuery.get(), ]); + // Collect all events const familyEvents = familySnapshot.docs.map(doc => doc.data()); const creatorEvents = creatorSnapshot.docs.map(doc => doc.data()); const attendeeEvents = attendeeSnapshot.docs.map(doc => doc.data()); allEvents = [...familyEvents, ...creatorEvents, ...attendeeEvents]; } else { + // Only include creator and attendee events when family view is off const creatorQuery = db.collection("Events").where("creatorId", "==", userId); const attendeeQuery = db.collection("Events").where("attendees", "array-contains", userId); @@ -49,19 +52,28 @@ export const useGetEvents = () => { allEvents = [...creatorEvents, ...attendeeEvents]; } - allEvents = allEvents.filter((event, index, self) => - index === self.findIndex(e => e.id === event.id) - ); + // Use a Map to ensure uniqueness only for events with IDs + const uniqueEventsMap = new Map(); + allEvents.forEach(event => { + if (event.id) { + uniqueEventsMap.set(event.id, event); // Ensure uniqueness for events with IDs + } else { + uniqueEventsMap.set(Math.random().toString(36), event); // Generate a temp key for events without ID + } + }); + const uniqueEvents = Array.from(uniqueEventsMap.values()); - allEvents = allEvents.filter(event => { + // Filter out private events unless the user is the creator + const filteredEvents = uniqueEvents.filter(event => { if (event.private) { return event.creatorId === userId; } return true; }); + // Attach event colors and return the final list of events return await Promise.all( - allEvents.map(async (event) => { + filteredEvents.map(async (event) => { const profileSnapshot = await db .collection("Profiles") .doc(event.creatorId) @@ -71,13 +83,13 @@ export const useGetEvents = () => { const eventColor = profileData?.eventColor || colorMap.pink; return { - id: event.id, + id: event.id || Math.random().toString(36).substr(2, 9), // Generate temp ID if missing title: event.title, start: new Date(event.startDate.seconds * 1000), end: new Date(event.endDate.seconds * 1000), hideHours: event.allDay, - eventColor: eventColor, - notes: event.notes + eventColor, + notes: event.notes, }; }) ); From 0b11381fce4e6283fd29d40d34cb072bb64e5c95 Mon Sep 17 00:00:00 2001 From: Dejan Date: Thu, 24 Oct 2024 20:35:42 +0200 Subject: [PATCH 08/66] - Implemented handling of repeat days change --- components/pages/todos/AddChoreDialog.tsx | 18 ++++++++++++++++-- components/pages/todos/RepeatFreq.tsx | 23 ++++++++++++++--------- hooks/firebase/types/todoData.ts | 11 +++++++++++ 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/components/pages/todos/AddChoreDialog.tsx b/components/pages/todos/AddChoreDialog.tsx index d93b20f..30bfaa7 100644 --- a/components/pages/todos/AddChoreDialog.tsx +++ b/components/pages/todos/AddChoreDialog.tsx @@ -48,12 +48,14 @@ const AddChoreDialog = (addChoreDialogProps: IAddChoreDialog) => { ); const { width, height } = Dimensions.get("screen"); const [points, setPoints] = useState(todo.points); + const [selectedDays, setSelectedDays] = useState([]); const { data: members } = useGetFamilyMembers(); const handleClose = () => { setTodo(defaultTodo); setSelectedAssignees([]); + setSelectedDays([]); addChoreDialogProps.setIsVisible(false); }; @@ -67,6 +69,17 @@ const AddChoreDialog = (addChoreDialogProps: IAddChoreDialog) => { } }; + const handleRepeatDaysChange = (day: string, set: boolean) => { + if (set) { + setSelectedDays((prevState) => [...prevState, day]); + } else { + const array = selectedDays; + let index = array.indexOf(day); + array.splice(index, 1); + setSelectedDays(array); + } + } + return ( { updateToDo({ ...todo, points: points, - assignees: selectedAssignees, + assignees: selectedAssignees }); } else { addToDo({ @@ -118,6 +131,7 @@ const AddChoreDialog = (addChoreDialogProps: IAddChoreDialog) => { done: false, points: points, assignees: selectedAssignees, + repeatDays: selectedDays }); } handleClose(); @@ -199,7 +213,7 @@ const AddChoreDialog = (addChoreDialogProps: IAddChoreDialog) => { ))} - {todo.repeatType == "Every week" && } + {todo.repeatType == "Every week" && } diff --git a/components/pages/todos/RepeatFreq.tsx b/components/pages/todos/RepeatFreq.tsx index fb2fea5..a7b9354 100644 --- a/components/pages/todos/RepeatFreq.tsx +++ b/components/pages/todos/RepeatFreq.tsx @@ -1,7 +1,8 @@ import { View, Text, TouchableOpacity, Picker } from "react-native-ui-lib"; import React, { useEffect, useState } from "react"; +import {DAYS_OF_WEEK_ENUM} from "@/hooks/firebase/types/todoData"; -const RepeatFreq = () => { +const RepeatFreq = ({ handleRepeatDaysChange }: { handleRepeatDaysChange: Function }) => { const [weeks, setWeeks] = useState(1); const weekOptions: number[] = Array.from({ length: 52 }, (_, i) => i + 1); @@ -9,21 +10,25 @@ const RepeatFreq = () => { return ( - - - - - - - + + + + + + + ); }; export default RepeatFreq; -const RepeatOption = ({ value }: { value: string }) => { +const RepeatOption = ({ value, handleRepeatDaysChange }: { value: string, handleRepeatDaysChange: Function }) => { const [isSet, setisSet] = useState(false); + + useEffect(() => { + handleRepeatDaysChange(value, isSet); + }, [isSet]) return ( setisSet(!isSet)}> Date: Thu, 24 Oct 2024 23:55:49 +0200 Subject: [PATCH 09/66] - Implemented creation of the repeatable todos for every repeat type --- hooks/firebase/types/todoData.ts | 7 +++ hooks/firebase/useCreateTodo.ts | 86 ++++++++++++++++++++++++++++++-- 2 files changed, 89 insertions(+), 4 deletions(-) diff --git a/hooks/firebase/types/todoData.ts b/hooks/firebase/types/todoData.ts index 9a852b2..32542c0 100644 --- a/hooks/firebase/types/todoData.ts +++ b/hooks/firebase/types/todoData.ts @@ -23,3 +23,10 @@ export const DAYS_OF_WEEK_ENUM = { SATURDAY: "Saturday", SUNDAY: "Sunday" } + +export const REPEAT_TYPE = { + NONE: "None", + EVERY_WEEK: "Every week", + ONCE_A_MONTH: "Once a month", + ONCE_A_YEAR: "Once a year" +} \ No newline at end of file diff --git a/hooks/firebase/useCreateTodo.ts b/hooks/firebase/useCreateTodo.ts index d065fc5..fefffcf 100644 --- a/hooks/firebase/useCreateTodo.ts +++ b/hooks/firebase/useCreateTodo.ts @@ -1,7 +1,17 @@ -import { useMutation, useQueryClient } from "react-query"; +import {useMutation, useQueryClient} from "react-query"; import firestore from "@react-native-firebase/firestore"; -import { useAuthContext } from "@/contexts/AuthContext"; -import { IToDo } from "@/hooks/firebase/types/todoData"; +import {useAuthContext} from "@/contexts/AuthContext"; +import {DAYS_OF_WEEK_ENUM, IToDo, REPEAT_TYPE} from "@/hooks/firebase/types/todoData"; +import {addDays, addMonths, addWeeks, compareAsc, format, getDay, subDays} from "date-fns"; + +const daysOfWeek = [ + DAYS_OF_WEEK_ENUM.MONDAY, + DAYS_OF_WEEK_ENUM.TUESDAY, + DAYS_OF_WEEK_ENUM.WEDNESDAY, + DAYS_OF_WEEK_ENUM.THURSDAY, + DAYS_OF_WEEK_ENUM.FRIDAY, + DAYS_OF_WEEK_ENUM.SATURDAY, + DAYS_OF_WEEK_ENUM.SUNDAY]; export const useCreateTodo = () => { const { user: currentUser, profileData } = useAuthContext(); @@ -11,10 +21,78 @@ export const useCreateTodo = () => { mutationKey: ["createTodo"], mutationFn: async (todoData: Partial) => { try { + // Create the one original to do const newDoc = firestore().collection('Todos').doc(); + let originalTodo = {...todoData, id: newDoc.id, familyId: profileData?.familyId, creatorId: currentUser?.uid} await firestore() .collection("Todos") - .add({...todoData, id: newDoc.id, familyId: profileData?.familyId, creatorId: currentUser?.uid}) + .add(originalTodo); + + if (todoData.repeatType !== REPEAT_TYPE.NONE) { + const batch = firestore().batch(); + + if (todoData.repeatType === REPEAT_TYPE.EVERY_WEEK) { + + let date = originalTodo.date; + let repeatDays = originalTodo.repeatDays; + const dates = []; + + const originalDateDay = format(date, 'EEEE'); + const originalNumber = daysOfWeek.indexOf(originalDateDay); + repeatDays?.forEach((day) => { + let number = daysOfWeek.indexOf(day); + let newDate; + if (originalNumber > number) { + let diff = originalNumber - number; + newDate = subDays(date, diff); + } else { + let diff = number - originalNumber; + newDate = addDays(date, diff); + } + dates.push(newDate); + }); + + // TODO: for the next 52 weeks + for (let i = 0; i < 4; i++) { + dates?.forEach((dateToAdd) => { + let newTodoDate = addWeeks(dateToAdd, i); + if (compareAsc(newTodoDate, originalTodo.date) !== 0) { + const newTodo = { ...originalTodo, date: newTodoDate, connectedTodoId: newDoc.id }; + + let docRef = firestore().collection("Todos").doc(); + batch.set(docRef, newTodo); + console.log(newTodo); + } + }) + } + } else if (todoData.repeatType === REPEAT_TYPE.ONCE_A_MONTH) { + + // for the next 12 months + for (let i = 0; i < 12; i++) { + let date = originalTodo.date; + const nextMonth = addMonths(date, i + 1); + const newTodo = { ...originalTodo, date: nextMonth, connectedTodoId: newDoc.id }; + console.log(newTodo); + + let docRef = firestore().collection("Todos").doc(); + batch.set(docRef, newTodo); + } + } else if (todoData.repeatType === REPEAT_TYPE.ONCE_A_YEAR) { + + // for the next 5 years + for (let i = 0; i < 5; i++) { + let date = originalTodo.date; + const nextMonth = addMonths(date, i + 1); + const newTodo = { ...originalTodo, date: nextMonth, connectedTodoId: newDoc.id }; + console.log(newTodo); + + let docRef = firestore().collection("Todos").doc(); + batch.set(docRef, newTodo); + } + } + + await batch.commit(); + } } catch (e) { console.error(e) } From 04f9e31ce4665ecde2e01ac38e625cc28ddc7763 Mon Sep 17 00:00:00 2001 From: Dejan Date: Fri, 25 Oct 2024 12:18:23 +0200 Subject: [PATCH 10/66] - Added the repeat days selected for the created todos in the edit dialog --- components/pages/todos/AddChoreDialog.tsx | 5 +++-- components/pages/todos/RepeatFreq.tsx | 20 ++++++++++---------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/components/pages/todos/AddChoreDialog.tsx b/components/pages/todos/AddChoreDialog.tsx index 30bfaa7..0a05bd9 100644 --- a/components/pages/todos/AddChoreDialog.tsx +++ b/components/pages/todos/AddChoreDialog.tsx @@ -123,7 +123,8 @@ const AddChoreDialog = (addChoreDialogProps: IAddChoreDialog) => { updateToDo({ ...todo, points: points, - assignees: selectedAssignees + assignees: selectedAssignees, + repeatDays: selectedDays, }); } else { addToDo({ @@ -213,7 +214,7 @@ const AddChoreDialog = (addChoreDialogProps: IAddChoreDialog) => { ))} - {todo.repeatType == "Every week" && } + {todo.repeatType == "Every week" && } diff --git a/components/pages/todos/RepeatFreq.tsx b/components/pages/todos/RepeatFreq.tsx index a7b9354..068c303 100644 --- a/components/pages/todos/RepeatFreq.tsx +++ b/components/pages/todos/RepeatFreq.tsx @@ -2,7 +2,7 @@ import { View, Text, TouchableOpacity, Picker } from "react-native-ui-lib"; import React, { useEffect, useState } from "react"; import {DAYS_OF_WEEK_ENUM} from "@/hooks/firebase/types/todoData"; -const RepeatFreq = ({ handleRepeatDaysChange }: { handleRepeatDaysChange: Function }) => { +const RepeatFreq = ({ repeatDays, handleRepeatDaysChange }: { repeatDays: string[], handleRepeatDaysChange: Function }) => { const [weeks, setWeeks] = useState(1); const weekOptions: number[] = Array.from({ length: 52 }, (_, i) => i + 1); @@ -10,21 +10,21 @@ const RepeatFreq = ({ handleRepeatDaysChange }: { handleRepeatDaysChange: Functi return ( - - - - - - - + + + + + + + ); }; export default RepeatFreq; -const RepeatOption = ({ value, handleRepeatDaysChange }: { value: string, handleRepeatDaysChange: Function }) => { - const [isSet, setisSet] = useState(false); +const RepeatOption = ({ value, handleRepeatDaysChange, repeatDays }: { value: string, handleRepeatDaysChange: Function, repeatDays: string[] }) => { + const [isSet, setisSet] = useState(repeatDays.includes(value)); useEffect(() => { handleRepeatDaysChange(value, isSet); From f35033f5e7ad911f258661b7c6f863be30db0d2c Mon Sep 17 00:00:00 2001 From: Dejan Date: Fri, 25 Oct 2024 14:04:13 +0200 Subject: [PATCH 11/66] - Fixed an issue with the Tod dialog - Implementation of update todo and adding new days in the rule for a repeatable todo --- components/pages/todos/AddChore.tsx | 2 +- components/pages/todos/AddChoreDialog.tsx | 22 ++++-- components/pages/todos/RepeatFreq.tsx | 11 ++- hooks/firebase/useCreateTodo.ts | 2 +- hooks/firebase/useGetTodos.ts | 2 +- hooks/firebase/useUpdateTodo.ts | 96 +++++++++++++++++++++-- 6 files changed, 115 insertions(+), 20 deletions(-) diff --git a/components/pages/todos/AddChore.tsx b/components/pages/todos/AddChore.tsx index 955e11c..4ba3fc8 100644 --- a/components/pages/todos/AddChore.tsx +++ b/components/pages/todos/AddChore.tsx @@ -31,7 +31,7 @@ const AddChore = () => { - + {isVisible && } ); }; diff --git a/components/pages/todos/AddChoreDialog.tsx b/components/pages/todos/AddChoreDialog.tsx index 0a05bd9..13cbdc7 100644 --- a/components/pages/todos/AddChoreDialog.tsx +++ b/components/pages/todos/AddChoreDialog.tsx @@ -36,6 +36,7 @@ const defaultTodo = { rotate: false, repeatType: "Every week", assignees: [], + repeatDays: [] }; const AddChoreDialog = (addChoreDialogProps: IAddChoreDialog) => { @@ -48,14 +49,12 @@ const AddChoreDialog = (addChoreDialogProps: IAddChoreDialog) => { ); const { width, height } = Dimensions.get("screen"); const [points, setPoints] = useState(todo.points); - const [selectedDays, setSelectedDays] = useState([]); const { data: members } = useGetFamilyMembers(); const handleClose = () => { setTodo(defaultTodo); setSelectedAssignees([]); - setSelectedDays([]); addChoreDialogProps.setIsVisible(false); }; @@ -71,12 +70,20 @@ const AddChoreDialog = (addChoreDialogProps: IAddChoreDialog) => { const handleRepeatDaysChange = (day: string, set: boolean) => { if (set) { - setSelectedDays((prevState) => [...prevState, day]); + const updatedTodo = { + ...todo, + repeatDays: [...todo.repeatDays, day] + } + setTodo(updatedTodo); } else { - const array = selectedDays; + const array = todo.repeatDays ?? []; let index = array.indexOf(day); array.splice(index, 1); - setSelectedDays(array); + const updatedTodo = { + ...todo, + repeatDays: array + } + setTodo(updatedTodo); } } @@ -123,8 +130,7 @@ const AddChoreDialog = (addChoreDialogProps: IAddChoreDialog) => { updateToDo({ ...todo, points: points, - assignees: selectedAssignees, - repeatDays: selectedDays, + assignees: selectedAssignees }); } else { addToDo({ @@ -132,7 +138,7 @@ const AddChoreDialog = (addChoreDialogProps: IAddChoreDialog) => { done: false, points: points, assignees: selectedAssignees, - repeatDays: selectedDays + repeatDays: todo.repeatDays ?? [] }); } handleClose(); diff --git a/components/pages/todos/RepeatFreq.tsx b/components/pages/todos/RepeatFreq.tsx index 068c303..8399c8c 100644 --- a/components/pages/todos/RepeatFreq.tsx +++ b/components/pages/todos/RepeatFreq.tsx @@ -26,11 +26,14 @@ export default RepeatFreq; const RepeatOption = ({ value, handleRepeatDaysChange, repeatDays }: { value: string, handleRepeatDaysChange: Function, repeatDays: string[] }) => { const [isSet, setisSet] = useState(repeatDays.includes(value)); - useEffect(() => { - handleRepeatDaysChange(value, isSet); - }, [isSet]) + + const handleDayChange = () => { + handleRepeatDaysChange(value, !isSet) + setisSet(!isSet); + } + return ( - setisSet(!isSet)}> + { @@ -23,6 +22,7 @@ export const useGetTodos = () => { ...data, id: doc.id, date: data.date ? new Date(data.date.seconds * 1000) : null, + repeatDays: data.repeatDays ?? [] }; }) as IToDo[]; } diff --git a/hooks/firebase/useUpdateTodo.ts b/hooks/firebase/useUpdateTodo.ts index b1b985f..33a363e 100644 --- a/hooks/firebase/useUpdateTodo.ts +++ b/hooks/firebase/useUpdateTodo.ts @@ -1,6 +1,8 @@ import { useMutation, useQueryClient } from "react-query"; import firestore from "@react-native-firebase/firestore"; -import { IToDo } from "@/hooks/firebase/types/todoData"; +import {IToDo} from "@/hooks/firebase/types/todoData"; +import {addDays, addWeeks, compareAsc, format, subDays} from "date-fns"; +import {daysOfWeek} from "@/hooks/firebase/useCreateTodo"; export const useUpdateTodo = () => { const queryClients = useQueryClient() @@ -9,10 +11,94 @@ export const useUpdateTodo = () => { mutationKey: ["updateTodo"], mutationFn: async (todoData: Partial) => { try { - await firestore() - .collection("Todos") - .doc(todoData.id) - .update(todoData); + if (todoData.connectedTodoId) { + console.log("CONNECTED TODO"); + const snapshot = await firestore() + .collection("Todos") + .where("connectedTodoId", "==", todoData.connectedTodoId) + .get(); + + + const connectedTodos = snapshot.docs.map((doc) => { + const data = doc.data(); + + return { + ...data, + id: doc.id, + date: data.date ? new Date(data.date.seconds * 1000) : null, + ref: doc.ref + }; + }) as IToDo[]; + + let filteredTodos = connectedTodos?.filter((item) => item.date >= todoData.date).sort((a,b) =>{ + return b.date?.getSeconds() - a.date?.getSeconds(); + }); + console.log(filteredTodos); + + let firstTodo = filteredTodos?.[0]; + // resolve the repeating + const batch = firestore().batch(); + const todosToAddCycles = filteredTodos?.length / firstTodo?.repeatDays?.length; + console.log(todosToAddCycles); + if (firstTodo?.repeatDays !== todoData.repeatDays) { + let newRepeatDays = todoData.repeatDays?.filter((element) => firstTodo?.repeatDays?.indexOf(element) === -1); + const dates = []; + + let date = firstTodo?.date; + const originalDateDay = format(date, 'EEEE'); + const originalNumber = daysOfWeek.indexOf(originalDateDay); + newRepeatDays?.forEach((day) => { + let number = daysOfWeek.indexOf(day); + let newDate; + if (originalNumber > number) { + let diff = originalNumber - number; + newDate = subDays(date, diff); + } else { + let diff = number - originalNumber; + newDate = addDays(date, diff); + } + dates.push(newDate); + }); + + console.log("REPEAT") + console.log(newRepeatDays); + console.log(dates); + + filteredTodos?.forEach((item) => { + + batch.update(item.ref, {...todoData, date: item.date}); + }) + // TODO: for the next connected -> filtered todos - number of weeks + for (let i = 0; i < todosToAddCycles; i++) { + dates?.forEach((dateToAdd) => { + let newTodoDate = addWeeks(dateToAdd, i); + if (compareAsc(newTodoDate, firstTodo?.date) !== 0) { + const newTodo = { ...todoData, date: newTodoDate }; + + let docRef = firestore().collection("Todos").doc(); + batch.set(docRef, newTodo); + console.log("ADD") + console.log(newTodo); + } + }) + } + } else { + filteredTodos?.forEach((item) => { + + console.log("UPDATE"); + batch.update(item.ref, {...todoData, date: item.date}); + }) + } + + await batch.commit(); + } else { + console.log("Update"); + console.log(todoData); + await firestore() + .collection("Todos") + .doc(todoData.id) + .update(todoData); + } } catch (e) { console.error(e) } From 2ec014bcc73621c8d01dd82ba6d69f518bcdfbe7 Mon Sep 17 00:00:00 2001 From: Dejan Date: Fri, 25 Oct 2024 16:49:32 +0200 Subject: [PATCH 12/66] - Implementation of update todo and removing days in the rule for a repeatable todo --- hooks/firebase/useUpdateTodo.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/hooks/firebase/useUpdateTodo.ts b/hooks/firebase/useUpdateTodo.ts index 33a363e..de7a263 100644 --- a/hooks/firebase/useUpdateTodo.ts +++ b/hooks/firebase/useUpdateTodo.ts @@ -42,6 +42,7 @@ export const useUpdateTodo = () => { console.log(todosToAddCycles); if (firstTodo?.repeatDays !== todoData.repeatDays) { let newRepeatDays = todoData.repeatDays?.filter((element) => firstTodo?.repeatDays?.indexOf(element) === -1); + let removeRepeatDays = firstTodo?.repeatDays?.filter((element) => todoData?.repeatDays?.indexOf(element) === -1); const dates = []; let date = firstTodo?.date; @@ -62,6 +63,7 @@ export const useUpdateTodo = () => { console.log("REPEAT") console.log(newRepeatDays); + console.log(removeRepeatDays); console.log(dates); filteredTodos?.forEach((item) => { @@ -82,6 +84,19 @@ export const useUpdateTodo = () => { } }) } + + removeRepeatDays?.forEach((removeDay) => { + filteredTodos?.forEach((item) => { + + let todoDate = item.date; + const todoDateDay = format(todoDate, 'EEEE'); + console.log(todoDateDay); + if (todoDateDay === removeDay) { + batch.delete(item.ref); + } + }) + }) + } else { filteredTodos?.forEach((item) => { From d064d5c9c2254a9ddecfec1348864fdc750ac777 Mon Sep 17 00:00:00 2001 From: ivic00 <102467664+ivic00@users.noreply.github.com> Date: Sat, 26 Oct 2024 01:38:19 +0200 Subject: [PATCH 13/66] calendar ui changes --- app/(auth)/_layout.tsx | 19 +- components/pages/calendar/CalendarHeader.tsx | 210 ++++++++++-------- components/pages/calendar/EventCalendar.tsx | 214 ++++++++++--------- 3 files changed, 249 insertions(+), 194 deletions(-) diff --git a/app/(auth)/_layout.tsx b/app/(auth)/_layout.tsx index 2b7927b..31de7c7 100644 --- a/app/(auth)/_layout.tsx +++ b/app/(auth)/_layout.tsx @@ -7,7 +7,7 @@ import { DrawerItemList, } from "@react-navigation/drawer"; import { Button, View, Text, ButtonSize } from "react-native-ui-lib"; -import { StyleSheet } from "react-native"; +import { ImageBackground, StyleSheet } from "react-native"; import Feather from "@expo/vector-icons/Feather"; import DrawerButton from "@/components/shared/DrawerButton"; import { @@ -43,7 +43,16 @@ export default function TabLayout() { drawerContent={(props) => { return ( - + + Welcome to Cally { - const [selectedDate, setSelectedDate] = useAtom(selectedDateAtom); - const [mode, setMode] = useAtom(modeAtom); + const [selectedDate, setSelectedDate] = useAtom(selectedDateAtom); + const [mode, setMode] = useAtom(modeAtom); + const { profileData } = useAuthContext(); - const handleSegmentChange = (index: number) => { - const selectedMode = modeMap.get(index); - if (selectedMode) { - setTimeout(() => { - setMode(selectedMode as "day" | "week" | "month"); - }, 150); - } - }; + const handleSegmentChange = (index: number) => { + const selectedMode = modeMap.get(index); + if (selectedMode) { + setTimeout(() => { + setMode(selectedMode as "day" | "week" | "month"); + }, 150); + } + }; - const handleMonthChange = (month: string) => { - const currentDay = selectedDate.getDate(); - const currentYear = selectedDate.getFullYear(); - const newMonthIndex = months.indexOf(month); + const handleMonthChange = (month: string) => { + const currentDay = selectedDate.getDate(); + const currentYear = selectedDate.getFullYear(); + const newMonthIndex = months.indexOf(month); - const updatedDate = new Date(currentYear, newMonthIndex, currentDay); - setSelectedDate(updatedDate); - }; + const updatedDate = new Date(currentYear, newMonthIndex, currentDay); + setSelectedDate(updatedDate); + }; - const isSelectedDateToday = isSameDay(selectedDate, new Date()) + const isSelectedDateToday = isSameDay(selectedDate, new Date()); - return ( - + + + {selectedDate.getFullYear()} + + handleMonthChange(itemValue as string)} + trailingAccessory={} + topBarProps={{ + title: selectedDate.getFullYear().toString(), + titleStyle: { fontFamily: "Manrope_500Medium", fontSize: 17 }, + }} > - - - {selectedDate.getFullYear()} - - handleMonthChange(itemValue as string)} - trailingAccessory={} - topBarProps={{ - title: selectedDate.getFullYear().toString(), - titleStyle: {fontFamily: "Manrope_500Medium", fontSize: 17}, - }} - > - {months.map((month) => ( - - ))} - - + {months.map((month) => ( + + ))} + + - - {!isSelectedDateToday && ( - - - ); + {/* Camera Dialog */} + setShowCameraDialog(false)} + bottom + width="100%" + height="70%" + containerStyle={{ padding: 0 }} + > + {hasPermission === null ? ( + Requesting camera permissions... + ) : !hasPermission ? ( + No access to camera + ) : ( + + )} + + + ); }; const styles = StyleSheet.create({ - textfield: { - backgroundColor: "white", - marginVertical: 10, - padding: 30, - height: 45, - borderRadius: 50, - }, + textfield: { + backgroundColor: "white", + marginVertical: 10, + padding: 30, + height: 45, + borderRadius: 50, + fontFamily: "PlusJakartaSans_300Light", + }, + jakartaLight: { + fontFamily: "PlusJakartaSans_300Light", + fontSize: 16, + color: "#484848", + }, + jakartaMedium: { + fontFamily: "PlusJakartaSans_500Medium", + fontSize: 16, + color: "#919191", + textDecorationLine: "underline", + }, }); export default SignInPage; diff --git a/components/pages/main/SignUpPage.tsx b/components/pages/main/SignUpPage.tsx index e48e351..b2dc9ac 100644 --- a/components/pages/main/SignUpPage.tsx +++ b/components/pages/main/SignUpPage.tsx @@ -11,7 +11,7 @@ import { } from "react-native-ui-lib"; import { useSignUp } from "@/hooks/firebase/useSignUp"; import { ProfileType } from "@/contexts/AuthContext"; -import { StyleSheet } from "react-native"; +import { Dimensions, StyleSheet } from "react-native"; import { AntDesign } from "@expo/vector-icons"; const SignUpPage = ({ @@ -40,19 +40,21 @@ const SignUpPage = ({ }; return ( - - - Get started with Cally + + Get started with Cally + + Please enter your details. - Please enter your details. {lnameRef.current?.focus()}} + onSubmitEditing={() => { + lnameRef.current?.focus(); + }} blurOnSubmit={false} /> {emailRef.current?.focus()}} + onSubmitEditing={() => { + emailRef.current?.focus(); + }} blurOnSubmit={false} /> {passwordRef.current?.focus()}} + onSubmitEditing={() => { + passwordRef.current?.focus(); + }} blurOnSubmit={false} /> - setIsPasswordVisible(!isPasswordVisible)} - > - - - } - /> - + + setIsPasswordVisible(!isPasswordVisible)} + > + + + } + /> + + { setAllowFaceID(value); }} /> - + Allow FaceID for login in future setAcceptTerms(value)} /> - + I accept the - + {" "} terms and conditions - and + and - + {" "} privacy policy @@ -132,16 +147,24 @@ const SignUpPage = ({ - - - - ); + + + + + ); }; const styles = StyleSheet.create({ - searchField: { - borderWidth: 0.7, - borderColor: "#9b9b9b", - borderRadius: 15, - height: 42, - paddingLeft: 10, - marginVertical: 20, - }, + searchField: { + borderWidth: 0.7, + borderColor: "#9b9b9b", + borderRadius: 15, + height: 42, + paddingLeft: 10, + marginVertical: 20, + }, }); export default BrainDumpPage; diff --git a/components/pages/calendar/CalendarHeader.tsx b/components/pages/calendar/CalendarHeader.tsx index fbf2c7d..e8830da 100644 --- a/components/pages/calendar/CalendarHeader.tsx +++ b/components/pages/calendar/CalendarHeader.tsx @@ -1,134 +1,125 @@ -import React, { memo } from "react"; -import { - Button, - Picker, - PickerModes, - SegmentedControl, - Text, - View, -} from "react-native-ui-lib"; -import { MaterialIcons } from "@expo/vector-icons"; -import { modeMap, months } from "./constants"; -import { StyleSheet } from "react-native"; -import { useAtom } from "jotai"; -import { modeAtom, selectedDateAtom } from "@/components/pages/calendar/atoms"; -import { isSameDay } from "date-fns"; -import { useAuthContext } from "@/contexts/AuthContext"; +import React, {memo} from "react"; +import {Button, Picker, PickerModes, SegmentedControl, Text, View,} from "react-native-ui-lib"; +import {MaterialIcons} from "@expo/vector-icons"; +import {modeMap, months} from "./constants"; +import {StyleSheet} from "react-native"; +import {useAtom} from "jotai"; +import {modeAtom, selectedDateAtom} from "@/components/pages/calendar/atoms"; +import {isSameDay} from "date-fns"; +import {useAuthContext} from "@/contexts/AuthContext"; export const CalendarHeader = memo(() => { - const [selectedDate, setSelectedDate] = useAtom(selectedDateAtom); - const [mode, setMode] = useAtom(modeAtom); - const { profileData } = useAuthContext(); + const [selectedDate, setSelectedDate] = useAtom(selectedDateAtom); + const [mode, setMode] = useAtom(modeAtom); + const {profileData} = useAuthContext(); - const handleSegmentChange = (index: number) => { - const selectedMode = modeMap.get(index); - if (selectedMode) { - setTimeout(() => { - setMode(selectedMode as "day" | "week" | "month"); - }, 150); - } - }; + const handleSegmentChange = (index: number) => { + const selectedMode = modeMap.get(index); + if (selectedMode) { + setTimeout(() => { + setMode(selectedMode as "day" | "week" | "month"); + }, 150); + } + }; - const handleMonthChange = (month: string) => { - const currentDay = selectedDate.getDate(); - const currentYear = selectedDate.getFullYear(); - const newMonthIndex = months.indexOf(month); + const handleMonthChange = (month: string) => { + const currentDay = selectedDate.getDate(); + const currentYear = selectedDate.getFullYear(); + const newMonthIndex = months.indexOf(month); - const updatedDate = new Date(currentYear, newMonthIndex, currentDay); - setSelectedDate(updatedDate); - }; + const updatedDate = new Date(currentYear, newMonthIndex, currentDay); + setSelectedDate(updatedDate); + }; - const isSelectedDateToday = isSameDay(selectedDate, new Date()); + const isSelectedDateToday = isSameDay(selectedDate, new Date()); - return ( - - - - {selectedDate.getFullYear()} - - handleMonthChange(itemValue as string)} - trailingAccessory={} - topBarProps={{ - title: selectedDate.getFullYear().toString(), - titleStyle: { fontFamily: "Manrope_500Medium", fontSize: 17 }, - }} - > - {months.map((month) => ( - - ))} - - - - - {!isSelectedDateToday && ( - - - - setShowAddUserDialog(false)} - center - marginT-30 - > - Return to user settings - + + + + + {member.userType === ProfileType.PARENT + ? `Admin${ + member.uid === user?.uid ? " (You)" : "" + }` + : "Child"} + + setShowQRCodeDialog(val)} + showQRCodeDialog={showQRCodeDialog === member?.uid} + userId={member?.uid!} + /> + - + ))} + + )} - setShowNewUserInfoDialog(false)} - > - - - - - - New User Information - - { - setShowNewUserInfoDialog(false) - }}> - - - - + {!!caregivers.length && ( + <> + + Caregivers + + {caregivers?.map((member) => ( + + + + + {member.firstName} {member.lastName} + + + Caregiver + + - - - } - backgroundColor={Colors.grey60} - style={{borderRadius: 25}} - center - /> - { - }}> - - Upload User Profile Photo - - - + - Member Status - - setSelectedStatus(item)} - showSearch - floatingPlaceholder - style={styles.inViewPicker} - trailingAccessory={ - - - - } - > - - - - - - + setShowQRCodeDialog(val)} + showQRCodeDialog={showQRCodeDialog === member?.uid} + userId={member?.uid!} + /> + + ))} + + )} - - {selectedStatus === ProfileType.FAMILY_DEVICE - ? "Device Name" - : "First Name"} - - { - lNameRef.current?.focus() - }} - blurOnSubmit={false} - returnKeyType="next" - /> + {!!familyDevices.length && ( + <> + + Family Devices + + {familyDevices?.map((member, index) => ( + + + + {member.firstName} + + Family Device + + - {selectedStatus !== ProfileType.FAMILY_DEVICE && ( - <> - Last Name - { - emailRef.current?.focus() - }} - blurOnSubmit={false} - returnKeyType="next" + - /> - - )} + setShowQRCodeDialog(val)} + showQRCodeDialog={showQRCodeDialog === member?.uid} + userId={member?.uid!} + /> + + ))} + + )} + + - {selectedStatus !== ProfileType.FAMILY_DEVICE && ( - <> - Email Address (Optional) - - - )} + setShowNewUserInfoDialog(true), + style: styles.bottomButton, + }} + /> - - - ); + setShowAddUserDialog(false)} + panDirection={PanningProvider.Directions.DOWN} + > + + + Add a new user device + + + + + + setShowAddUserDialog(false)} + center + marginT-30 + > + Return to user settings + + + + + setShowNewUserInfoDialog(false)} + > + + + + + + New User Information + + { + setShowNewUserInfoDialog(false); + }} + > + + + + + + + + } + backgroundColor={Colors.grey60} + style={{ borderRadius: 25 }} + center + /> + {}}> + + Upload User Profile Photo + + + + + Member Status + + setSelectedStatus(item)} + showSearch + floatingPlaceholder + style={styles.inViewPicker} + trailingAccessory={ + + + + } + > + + + + + + + + + {selectedStatus === ProfileType.FAMILY_DEVICE + ? "Device Name" + : "First Name"} + + { + lNameRef.current?.focus(); + }} + blurOnSubmit={false} + returnKeyType="next" + /> + + {selectedStatus !== ProfileType.FAMILY_DEVICE && ( + <> + Last Name + { + emailRef.current?.focus(); + }} + blurOnSubmit={false} + returnKeyType="next" + /> + + )} + + {selectedStatus !== ProfileType.FAMILY_DEVICE && ( + <> + Email Address (Optional) + + + )} + + + + ); }; const styles = StyleSheet.create({ - dialogBtn: { - height: 47, - width: 279, - }, - dialogTitle: {fontFamily: "Manrope_600SemiBold", fontSize: 22}, - dialogBackBtn: { - fontFamily: "PlusJakartaSans_500Medium", - fontSize: 15, - color: "#a7a7a7", - }, - card: { - marginVertical: 15, - backgroundColor: "white", - width: "100%", - borderRadius: 15, - padding: 20, - }, - bottomButton: { - position: "absolute", - bottom: 80, - width: "100%", - }, - familyCard: { - marginBottom: 10, - borderRadius: 10, - backgroundColor: Colors.white, - width: "100%", - }, - inputField: { - fontFamily: "PlusJakartaSans_500Medium", - fontSize: 13, - color: "#565656", - borderRadius: 50, - paddingVertical: 12, - paddingHorizontal: 16, - backgroundColor: Colors.grey80, - marginBottom: 16, - borderColor: Colors.grey50, - borderWidth: 1, - height: 40, - }, - picker: { - borderRadius: 50, - paddingVertical: 12, - paddingHorizontal: 16, - backgroundColor: Colors.grey80, - marginBottom: 16, - borderColor: Colors.grey50, - borderWidth: 1, - marginTop: -20, - height: 40, - zIndex: 10, - }, - viewPicker: { - borderRadius: 50, - backgroundColor: Colors.grey80, - marginBottom: 16, - borderColor: Colors.grey50, - borderWidth: 1, - marginTop: 0, - height: 40, - zIndex: 10, - }, - inViewPicker: { - borderRadius: 50, - paddingVertical: 12, - paddingHorizontal: 16, - marginBottom: 16, - marginTop: -20, - height: 40, - zIndex: 10, - }, - label: { - marginBottom: 5, - fontSize: 12, - color: Colors.grey40, - }, - dialogCard: { - borderRadius: 10, - gap: 10, - }, - subTit: { - fontFamily: "Manrope_500Medium", - fontSize: 15, - }, - dialogBtnLbl: { - fontFamily: "PlusJakartaSans_500Medium", - fontSize: 15, - color: "white", - }, - divider: {height: 0.7, backgroundColor: "#e6e6e6", width: "100%"}, - jakarta12: { - fontFamily: "PlusJakartaSans_500Medium", - fontSize: 12, - color: "#a1a1a1", - }, - jakarta13: { - fontFamily: "PlusJakartaSans_500Medium", - fontSize: 13, - }, + dialogBtn: { + height: 47, + width: 279, + }, + dialogTitle: { fontFamily: "Manrope_600SemiBold", fontSize: 22 }, + dialogBackBtn: { + fontFamily: "PlusJakartaSans_500Medium", + fontSize: 15, + color: "#a7a7a7", + }, + card: { + marginVertical: 15, + backgroundColor: "white", + width: "100%", + borderRadius: 12, + paddingHorizontal: 21, + paddingVertical: 20, + }, + bottomButton: { + position: "absolute", + bottom: 80, + width: "100%", + }, + familyCard: { + marginBottom: 10, + borderRadius: 10, + backgroundColor: Colors.white, + width: "100%", + }, + inputField: { + fontFamily: "PlusJakartaSans_500Medium", + fontSize: 13, + color: "#565656", + borderRadius: 50, + paddingVertical: 12, + paddingHorizontal: 16, + backgroundColor: Colors.grey80, + marginBottom: 16, + borderColor: Colors.grey50, + borderWidth: 1, + height: 40, + }, + picker: { + borderRadius: 50, + paddingVertical: 12, + paddingHorizontal: 16, + backgroundColor: Colors.grey80, + marginBottom: 16, + borderColor: Colors.grey50, + borderWidth: 1, + marginTop: -20, + height: 40, + zIndex: 10, + }, + viewPicker: { + borderRadius: 50, + backgroundColor: Colors.grey80, + marginBottom: 16, + borderColor: Colors.grey50, + borderWidth: 1, + marginTop: 0, + height: 40, + zIndex: 10, + }, + inViewPicker: { + borderRadius: 50, + paddingVertical: 12, + paddingHorizontal: 16, + marginBottom: 16, + marginTop: -20, + height: 40, + zIndex: 10, + }, + label: { + marginBottom: 5, + fontSize: 12, + color: Colors.grey40, + }, + dialogCard: { + borderRadius: 10, + gap: 10, + }, + subTit: { + fontFamily: "Manrope_500Medium", + fontSize: 15, + }, + dialogBtnLbl: { + fontFamily: "PlusJakartaSans_500Medium", + fontSize: 15, + color: "white", + }, + divider: { height: 0.7, backgroundColor: "#e6e6e6", width: "100%" }, + jakarta12: { + fontFamily: "PlusJakartaSans_500Medium", + fontSize: 12, + color: "#a1a1a1", + }, + jakarta13: { + fontFamily: "PlusJakartaSans_500Medium", + fontSize: 13, + }, + pfp: { aspectRatio: 1, width: 37.03, borderRadius: 10.56 }, + userType: { + fontFamily: "Manrope_500Medium", + fontSize: 12, + color: "#858585", + }, + name: { + fontFamily: "Manrope_600SemiBold", + fontSize: 16, + }, }); export default MyGroup; From 7f79a1c8198cce49148bcdc2d0fec60b9450d1d4 Mon Sep 17 00:00:00 2001 From: ivic00 <102467664+ivic00@users.noreply.github.com> Date: Wed, 30 Oct 2024 00:02:25 +0100 Subject: [PATCH 43/66] added confirmation dialogs, fixed scroll wheels ui tweaks --- app/(auth)/_layout.tsx | 7 + assets/svgs/OutlookIcon.tsx | 4 +- .../pages/brain_dump/BrainDumpDialog.tsx | 82 ++ components/pages/brain_dump/MoveBrainDump.tsx | 23 +- .../pages/calendar/DeleteEventDialog.tsx | 81 ++ components/pages/calendar/EventCalendar.tsx | 11 +- .../pages/calendar/ManuallyAddEventModal.tsx | 1158 +++++++++-------- components/pages/calendar/atoms.ts | 1 + components/pages/grocery/AddGroceryItem.tsx | 2 +- components/pages/grocery/GroceryWrapper.tsx | 60 +- .../pages/settings/CalendarSettingsPage.tsx | 43 +- .../CalendarSettingsDialog.tsx | 86 ++ components/pages/todos/ToDoItem.tsx | 36 +- components/pages/todos/ToDosPage.tsx | 137 +- 14 files changed, 1077 insertions(+), 654 deletions(-) create mode 100644 components/pages/brain_dump/BrainDumpDialog.tsx create mode 100644 components/pages/calendar/DeleteEventDialog.tsx create mode 100644 components/pages/settings/calendar_components/CalendarSettingsDialog.tsx diff --git a/app/(auth)/_layout.tsx b/app/(auth)/_layout.tsx index 3f470fe..a735503 100644 --- a/app/(auth)/_layout.tsx +++ b/app/(auth)/_layout.tsx @@ -26,6 +26,7 @@ import NavSettingsIcon from "@/assets/svgs/NavSettingsIcon"; import { useAtom } from "jotai"; import { settingsPageIndex, + toDosPageIndex, userSettingsView, } from "@/components/pages/calendar/atoms"; @@ -33,6 +34,7 @@ export default function TabLayout() { const { mutateAsync: signOut } = useSignOut(); const [pageIndex, setPageIndex] = useAtom(settingsPageIndex); const [userView, setUserView] = useAtom(userSettingsView); + const [toDosIndex, setToDosIndex] = useAtom(toDosPageIndex); return ( { props.navigation.navigate("calendar"); setPageIndex(0); + setToDosIndex(0); setUserView(true); }} icon={} @@ -87,6 +90,7 @@ export default function TabLayout() { pressFunc={() => { props.navigation.navigate("grocery"); setPageIndex(0); + setToDosIndex(0); setUserView(true); }} icon={} @@ -113,6 +117,7 @@ export default function TabLayout() { pressFunc={() => { props.navigation.navigate("todos"); setPageIndex(0); + setToDosIndex(0); setUserView(true); }} icon={} @@ -124,6 +129,7 @@ export default function TabLayout() { pressFunc={() => { props.navigation.navigate("brain_dump"); setPageIndex(0); + setToDosIndex(0); setUserView(true); }} icon={} @@ -135,6 +141,7 @@ export default function TabLayout() { onPress={() => { props.navigation.navigate("settings"); setPageIndex(0); + setToDosIndex(0); setUserView(true); }} label={"Manage Settings"} diff --git a/assets/svgs/OutlookIcon.tsx b/assets/svgs/OutlookIcon.tsx index 719d0de..1e0626a 100644 --- a/assets/svgs/OutlookIcon.tsx +++ b/assets/svgs/OutlookIcon.tsx @@ -3,8 +3,8 @@ import Svg, { Path, LinearGradient, Stop, SvgProps } from "react-native-svg"; const OutlookIcon: React.FC = (props) => ( diff --git a/components/pages/brain_dump/BrainDumpDialog.tsx b/components/pages/brain_dump/BrainDumpDialog.tsx new file mode 100644 index 0000000..bffe876 --- /dev/null +++ b/components/pages/brain_dump/BrainDumpDialog.tsx @@ -0,0 +1,82 @@ +import React from "react"; +import { Dialog, Button, Text, View } from "react-native-ui-lib"; +import { StyleSheet } from "react-native"; + +interface BrainDumpDialogProps { + visible: boolean; + title: string; + onDismiss: () => void; + onConfirm: () => void; +} + +const BrainDumpDialog: React.FC = ({ + visible, + title, + onDismiss, + onConfirm, +}) => { + return ( + + + Delete Note + + + + Are you sure you want to delete the {"\n"} + + {title} + {" "} + Note? + + + + + + + + ); +}; + +// Empty stylesheet for future styles +const styles = StyleSheet.create({ + confirmBtn: { + backgroundColor: "#ea156d", + }, + cancelBtn: { + backgroundColor: "white", + }, + dialog: { + backgroundColor: "white", + paddingHorizontal: 25, + paddingTop: 35, + paddingBottom: 17, + borderRadius: 20, + }, + title: { + fontFamily: "Manrope_600SemiBold", + fontSize: 22, + marginBottom: 20, + }, + text: { + fontFamily: "PlusJakartaSans_400Regular", + fontSize: 16, + marginBottom: 25, + }, +}); + +export default BrainDumpDialog; diff --git a/components/pages/brain_dump/MoveBrainDump.tsx b/components/pages/brain_dump/MoveBrainDump.tsx index d576f41..7480767 100644 --- a/components/pages/brain_dump/MoveBrainDump.tsx +++ b/components/pages/brain_dump/MoveBrainDump.tsx @@ -18,6 +18,7 @@ import NavCalendarIcon from "@/assets/svgs/NavCalendarIcon"; import NavToDosIcon from "@/assets/svgs/NavToDosIcon"; import RemindersIcon from "@/assets/svgs/RemindersIcon"; import MenuIcon from "@/assets/svgs/MenuIcon"; +import BrainDumpDialog from "./BrainDumpDialog"; const MoveBrainDump = (props: { item: IBrainDump; @@ -28,12 +29,26 @@ const MoveBrainDump = (props: { const [description, setDescription] = useState( props.item.description ); + const [modalVisible, setModalVisible] = useState(false); + const { width } = Dimensions.get("screen"); useEffect(() => { updateBrainDumpItem(props.item.id, { description: description }); }, [description]); + const showConfirmationDialog = () => { + setModalVisible(true); + }; + + const handleDeleteNote = () =>{ + deleteBrainDump(props.item.id); + } + + const hideConfirmationDialog = () => { + setModalVisible(false); + } + return ( } onPress={() => { - deleteBrainDump(props.item.id); - props.setIsVisible(false); + showConfirmationDialog(); }} /> @@ -145,6 +159,7 @@ const MoveBrainDump = (props: { + ); }; @@ -191,10 +206,10 @@ const styles = StyleSheet.create({ fontSize: 22, fontFamily: "Manrope_500Medium", }, - description:{ + description: { fontFamily: "Manrope_400Regular", fontSize: 14, - } + }, }); export default MoveBrainDump; diff --git a/components/pages/calendar/DeleteEventDialog.tsx b/components/pages/calendar/DeleteEventDialog.tsx new file mode 100644 index 0000000..33bd2d9 --- /dev/null +++ b/components/pages/calendar/DeleteEventDialog.tsx @@ -0,0 +1,81 @@ +import React from "react"; +import { Dialog, Button, Text, View } from "react-native-ui-lib"; +import { StyleSheet } from "react-native"; + +interface DeleteEventDialogProps { + visible: boolean; + title: string; + onDismiss: () => void; + onConfirm: () => void; +} + +const DeleteEventDialog: React.FC = ({ + visible, + title, + onDismiss, + onConfirm, +}) => { + return ( + + + Delete Event + + + + Are you sure you want to delete the event:{" "} + + {title} + {" "} + + + + + ); +}; + +// Empty stylesheet for future styles +const styles = StyleSheet.create({ + confirmBtn: { + backgroundColor: "#ea156d", + }, + cancelBtn: { + backgroundColor: "white", + }, + dialog: { + backgroundColor: "white", + paddingHorizontal: 25, + paddingTop: 35, + paddingBottom: 17, + borderRadius: 20, + }, + title: { + fontFamily: "Manrope_600SemiBold", + fontSize: 22, + marginBottom: 20, + }, + text: { + fontFamily: "PlusJakartaSans_400Regular", + fontSize: 16, + marginBottom: 25, + }, +}); + +export default DeleteEventDialog; diff --git a/components/pages/calendar/EventCalendar.tsx b/components/pages/calendar/EventCalendar.tsx index 43fc1c3..da7500b 100644 --- a/components/pages/calendar/EventCalendar.tsx +++ b/components/pages/calendar/EventCalendar.tsx @@ -207,7 +207,7 @@ export const EventCalendar: React.FC = React.memo( scrollOffsetMinutes={offsetMinutes} theme={{ palette: { - nowIndicator: "#fd1575", + nowIndicator: profileData?.eventColor || "#fd1575", gray: { "100": "#e8eaed", "200": "#e8eaed", @@ -223,13 +223,15 @@ export const EventCalendar: React.FC = React.memo( fontSize: 16, }, moreLabel: {}, - xs:{fontSize: 10} + xs: { fontSize: 10 }, }, }} dayHeaderStyle={dateStyle} dayHeaderHighlightColor={"white"} renderCustomDateForMonth={renderCustomDateForMonth} showAdjacentMonths + hourStyle={styles.hourStyle} + ampm /> ); } @@ -273,4 +275,9 @@ const styles = StyleSheet.create({ alignItems: "center", justifyContent: "center", }, + hourStyle: { + color: "#5f6368", + fontSize: 12, + fontFamily: "Manrope_500Medium", + }, }); diff --git a/components/pages/calendar/ManuallyAddEventModal.tsx b/components/pages/calendar/ManuallyAddEventModal.tsx index 468d76f..888ec2f 100644 --- a/components/pages/calendar/ManuallyAddEventModal.tsx +++ b/components/pages/calendar/ManuallyAddEventModal.tsx @@ -1,569 +1,655 @@ import { - Button, - ButtonSize, - Colors, - DateTimePicker, - LoaderScreen, - Modal, - Picker, - PickerModes, - Switch, - Text, - TextField, - TextFieldRef, - TouchableOpacity, - View, + Button, + ButtonSize, + Colors, + DateTimePicker, + LoaderScreen, + Modal, + Picker, + PickerModes, + Switch, + Text, + TextField, + TextFieldRef, + TouchableOpacity, + View, } from "react-native-ui-lib"; -import {ScrollView} from "react-native-gesture-handler"; -import {useSafeAreaInsets} from "react-native-safe-area-context"; -import {useEffect, useRef, useState} from "react"; -import {AntDesign, Feather, Ionicons,} from "@expo/vector-icons"; -import {PickerMultiValue} from "react-native-ui-lib/src/components/picker/types"; -import {useCreateEvent} from "@/hooks/firebase/useCreateEvent"; -import {EventData} from "@/hooks/firebase/types/eventData"; -import {addHours} from "date-fns"; +import { ScrollView } from "react-native-gesture-handler"; +import { useSafeAreaInsets } from "react-native-safe-area-context"; +import { useEffect, useRef, useState } from "react"; +import { AntDesign, Feather, Ionicons } from "@expo/vector-icons"; +import { PickerMultiValue } from "react-native-ui-lib/src/components/picker/types"; +import { useCreateEvent } from "@/hooks/firebase/useCreateEvent"; +import { EventData } from "@/hooks/firebase/types/eventData"; +import { addHours } from "date-fns"; import DropModalIcon from "@/assets/svgs/DropModalIcon"; -import {StyleSheet} from "react-native"; +import { StyleSheet } from "react-native"; import ClockIcon from "@/assets/svgs/ClockIcon"; import LockIcon from "@/assets/svgs/LockIcon"; import MenuIcon from "@/assets/svgs/MenuIcon"; import CameraIcon from "@/assets/svgs/CameraIcon"; import AssigneesDisplay from "@/components/shared/AssigneesDisplay"; -import {useAtom} from "jotai"; -import {eventForEditAtom, selectedNewEventDateAtom} from "@/components/pages/calendar/atoms"; -import {useGetFamilyMembers} from "@/hooks/firebase/useGetFamilyMembers"; +import { useAtom } from "jotai"; +import { + eventForEditAtom, + selectedNewEventDateAtom, +} from "@/components/pages/calendar/atoms"; +import { useGetFamilyMembers } from "@/hooks/firebase/useGetFamilyMembers"; +import BinIcon from "@/assets/svgs/BinIcon"; +import CloseXIcon from "@/assets/svgs/CloseXIcon"; +import PenIcon from "@/assets/svgs/PenIcon"; +import DeleteEventDialog from "./DeleteEventDialog"; const daysOfWeek = [ - {label: "Monday", value: "monday"}, - {label: "Tuesday", value: "tuesday"}, - {label: "Wednesday", value: "wednesday"}, - {label: "Thursday", value: "thursday"}, - {label: "Friday", value: "friday"}, - {label: "Saturday", value: "saturday"}, - {label: "Sunday", value: "sunday"}, + { label: "Monday", value: "monday" }, + { label: "Tuesday", value: "tuesday" }, + { label: "Wednesday", value: "wednesday" }, + { label: "Thursday", value: "thursday" }, + { label: "Friday", value: "friday" }, + { label: "Saturday", value: "saturday" }, + { label: "Sunday", value: "sunday" }, ]; export const ManuallyAddEventModal = () => { - const insets = useSafeAreaInsets(); + const insets = useSafeAreaInsets(); - const [selectedNewEventDate, setSelectedNewEndDate] = useAtom(selectedNewEventDateAtom) - const [editEvent, setEditEvent] = useAtom(eventForEditAtom) + const [selectedNewEventDate, setSelectedNewEndDate] = useAtom( + selectedNewEventDateAtom + ); + const [editEvent, setEditEvent] = useAtom(eventForEditAtom); + const [deleteModalVisible, setDeleteModalVisible] = useState(false); - const {show, close, initialDate} = { - show: !!selectedNewEventDate || !!editEvent, - close: () => { - setSelectedNewEndDate(undefined) - setEditEvent(undefined) - }, - initialDate: selectedNewEventDate || editEvent?.start + const showDeleteEventModal = () => { + setDeleteModalVisible(true); + }; + + const handleDeleteEvent = () => {}; + + const hideDeleteEventModal = () => { + setDeleteModalVisible(false); + }; + + const { show, close, initialDate } = { + show: !!selectedNewEventDate || !!editEvent, + close: () => { + setSelectedNewEndDate(undefined); + setEditEvent(undefined); + }, + initialDate: selectedNewEventDate || editEvent?.start, + }; + + const detailsRef = useRef(null); + + const [title, setTitle] = useState(editEvent?.title || ""); + const [details, setDetails] = useState(editEvent?.notes || ""); + const [isAllDay, setIsAllDay] = useState(editEvent?.allDay || false); + const [isPrivate, setIsPrivate] = useState( + editEvent?.private || false + ); + const [startTime, setStartTime] = useState(() => { + const date = initialDate ?? new Date(); + date.setSeconds(0, 0); + return date; + }); + const [endTime, setEndTime] = useState(() => { + if (editEvent?.end) { + const date = new Date(editEvent.end); + date.setSeconds(0, 0); + return date; } + const date = + editEvent?.end ?? initialDate + ? addHours(editEvent?.end ?? initialDate!, 1) + : addHours(new Date(), 1); + date.setSeconds(0, 0); + return date; + }); + const [startDate, setStartDate] = useState(initialDate ?? new Date()); + const [endDate, setEndDate] = useState( + editEvent?.end ?? initialDate ?? new Date() + ); + const [selectedAttendees, setSelectedAttendees] = useState( + editEvent?.participants ?? [] + ); + const [repeatInterval, setRepeatInterval] = useState([]); - const detailsRef = useRef(null) + const { mutateAsync: createEvent, isLoading, isError } = useCreateEvent(); + const { data: members } = useGetFamilyMembers(true); - const [title, setTitle] = useState(editEvent?.title || ""); - const [details, setDetails] = useState(editEvent?.notes || ""); - const [isAllDay, setIsAllDay] = useState(editEvent?.allDay || false); - const [isPrivate, setIsPrivate] = useState(editEvent?.private || false); - const [startTime, setStartTime] = useState(() => { - const date = initialDate ?? new Date(); + useEffect(() => { + setTitle(editEvent?.title || ""); + setDetails(editEvent?.notes || ""); + setIsAllDay(editEvent?.allDay || false); + setIsPrivate(editEvent?.private || false); + setStartTime(() => { + const date = initialDate ?? new Date(); + date.setSeconds(0, 0); + return date; + }); + setEndTime(() => { + if (editEvent?.end) { + const date = new Date(editEvent.end); date.setSeconds(0, 0); return date; + } + const date = + editEvent?.end ?? initialDate + ? addHours(editEvent?.end ?? initialDate!, 1) + : addHours(new Date(), 1); + date.setSeconds(0, 0); + return date; }); - const [endTime, setEndTime] = useState(() => { - if (editEvent?.end) { - const date = new Date(editEvent.end); - date.setSeconds(0, 0); - return date; - } - const date = (editEvent?.end ?? initialDate) - ? addHours((editEvent?.end ?? initialDate!), 1) - : addHours(new Date(), 1); - date.setSeconds(0, 0); - return date; + setStartDate(initialDate ?? new Date()); + setEndDate(editEvent?.end ?? initialDate ?? new Date()); + setSelectedAttendees(editEvent?.participants ?? []); + setRepeatInterval([]); + }, [editEvent, selectedNewEventDate]); + + if (!show) return null; + + const formatDateTime = (date?: Date | string) => { + if (!date) return undefined; + return new Date(date).toLocaleDateString("en-US", { + weekday: "long", + month: "short", + day: "numeric", }); - const [startDate, setStartDate] = useState(initialDate ?? new Date()); - const [endDate, setEndDate] = useState(editEvent?.end ?? initialDate ?? new Date()); - const [selectedAttendees, setSelectedAttendees] = useState(editEvent?.participants ?? []); - const [repeatInterval, setRepeatInterval] = useState([]); + }; - const {mutateAsync: createEvent, isLoading, isError} = useCreateEvent(); - const {data: members} = useGetFamilyMembers(true); + const combineDateAndTime = (date: Date, time: Date): Date => { + const combined = new Date(date); + combined.setHours(time.getHours()); + combined.setMinutes(time.getMinutes()); + combined.setSeconds(0); + combined.setMilliseconds(0); + return combined; + }; - useEffect(() => { - setTitle(editEvent?.title || ""); - setDetails(editEvent?.notes || ""); - setIsAllDay(editEvent?.allDay || false); - setIsPrivate(editEvent?.private || false); - setStartTime(() => { - const date = initialDate ?? new Date(); - date.setSeconds(0, 0); - return date; - }); - setEndTime(() => { - if (editEvent?.end) { - const date = new Date(editEvent.end); - date.setSeconds(0, 0); - return date; - } - const date = (editEvent?.end ?? initialDate) - ? addHours((editEvent?.end ?? initialDate!), 1) - : addHours(new Date(), 1); - date.setSeconds(0, 0); - return date; - }); - setStartDate(initialDate ?? new Date()); - setEndDate(editEvent?.end ?? initialDate ?? new Date()); - setSelectedAttendees(editEvent?.participants ?? []); - setRepeatInterval([]); - }, [editEvent, selectedNewEventDate]); + const handleSave = async () => { + let finalStartDate: Date; + let finalEndDate: Date; - if (!show) return null; - - const formatDateTime = (date?: Date | string) => { - if (!date) return undefined; - return new Date(date).toLocaleDateString("en-US", { - weekday: "long", - month: "short", - day: "numeric", - }); - }; - - const combineDateAndTime = (date: Date, time: Date): Date => { - const combined = new Date(date); - combined.setHours(time.getHours()); - combined.setMinutes(time.getMinutes()); - combined.setSeconds(0); - combined.setMilliseconds(0); - return combined; - }; - - const handleSave = async () => { - let finalStartDate: Date; - let finalEndDate: Date; - - if (isAllDay) { - finalStartDate = new Date(startDate.setHours(0, 0, 0, 0)); - finalEndDate = new Date(startDate.setHours(0, 0, 0, 0)); - } else { - finalStartDate = combineDateAndTime(startDate, startTime); - finalEndDate = combineDateAndTime(endDate, endTime); - } - - const eventData: Partial = { - title: title, - startDate: finalStartDate, - endDate: finalEndDate, - allDay: isAllDay, - attendees: selectedAttendees, - notes: details - }; - - if (editEvent?.id) eventData.id = editEvent?.id - - await createEvent(eventData); - setEditEvent(undefined) - - close(); - }; - - const getRepeatLabel = () => { - const selectedDays = repeatInterval; - const allDays = [ - "sunday", - "monday", - "tuesday", - "wednesday", - "thursday", - "friday", - "saturday", - ]; - const workDays = ["monday", "tuesday", "wednesday", "thursday", "friday"]; - - const isEveryWorkDay = workDays.every((day) => selectedDays.includes(day)); - - const isEveryDay = allDays.every((day) => selectedDays.includes(day)); - - if (isEveryDay) { - return "Every day"; - } else if ( - isEveryWorkDay && - !selectedDays.includes("saturday") && - !selectedDays.includes("sunday") - ) { - return "Every work day"; - } else { - return selectedDays - .map((item) => daysOfWeek.find((day) => day.value === item)?.label) - .join(", "); - } - }; - - if (isLoading && !isError) { - return ( - - - - ); + if (isAllDay) { + finalStartDate = new Date(startDate.setHours(0, 0, 0, 0)); + finalEndDate = new Date(startDate.setHours(0, 0, 0, 0)); + } else { + finalStartDate = combineDateAndTime(startDate, startTime); + finalEndDate = combineDateAndTime(endDate, endTime); } + const eventData: Partial = { + title: title, + startDate: finalStartDate, + endDate: finalEndDate, + allDay: isAllDay, + attendees: selectedAttendees, + notes: details, + }; + + if (editEvent?.id) eventData.id = editEvent?.id; + + await createEvent(eventData); + setEditEvent(undefined); + + close(); + }; + + const getRepeatLabel = () => { + const selectedDays = repeatInterval; + const allDays = [ + "sunday", + "monday", + "tuesday", + "wednesday", + "thursday", + "friday", + "saturday", + ]; + const workDays = ["monday", "tuesday", "wednesday", "thursday", "friday"]; + + const isEveryWorkDay = workDays.every((day) => selectedDays.includes(day)); + + const isEveryDay = allDays.every((day) => selectedDays.includes(day)); + + if (isEveryDay) { + return "Every day"; + } else if ( + isEveryWorkDay && + !selectedDays.includes("saturday") && + !selectedDays.includes("sunday") + ) { + return "Every work day"; + } else { + return selectedDays + .map((item) => daysOfWeek.find((day) => day.value === item)?.label) + .join(", "); + } + }; + + if (isLoading && !isError) { return ( - - - - - - Cancel - - - - - - Save - - - - - { - setTitle(text); - }} - placeholderTextColor="#2d2d30" - style={{fontFamily: "Manrope_500Medium", fontSize: 22}} - paddingT-15 - paddingL-30 - returnKeyType="next" - /> - - - - - - - All day - - - - setIsAllDay(value)} - /> - - - - - - { - setStartDate(date); - }} - maximumDate={endDate} - style={{ - fontFamily: "PlusJakartaSans_500Medium", - fontSize: 16, - }} - marginL-8 - /> - - { - if (time <= endTime) { - setStartTime(time) - } else { - const currentTime = new Date(); - currentTime.setSeconds(0, 0); - setStartTime(currentTime); - } - }} - minuteInterval={5} - dateTimeFormatter={(date, mode) => - date.toLocaleTimeString("en-us", { - hour: "numeric", - minute: "numeric", - }) - } - mode="time" - style={{ - fontFamily: "PlusJakartaSans_500Medium", - fontSize: 16, - }} - marginR-30 - /> - - - {!isAllDay && ( - - - - { - setEndDate(date); - }} - style={{ - fontFamily: "PlusJakartaSans_500Medium", - fontSize: 16, - }} - /> - - { - if (time >= endTime) { - setEndTime(time); - } else { - const currentTime = new Date(); - currentTime.setSeconds(0, 0); - setEndTime(currentTime); - } - }} - minimumDate={startTime} - minuteInterval={5} - dateTimeFormatter={(date, mode) => - date.toLocaleTimeString("en-us", { - hour: "numeric", - minute: "numeric", - }) - } - mode="time" - style={{ - fontFamily: "PlusJakartaSans_500Medium", - fontSize: 16, - }} - marginR-30 - /> - - )} - - - - - - - - Attendees - - - setSelectedAttendees(value as string[] ?? [])} - style={{marginLeft: "auto"}} - mode={PickerModes.MULTI} - renderInput={() => - - } - /> - - )} - - - - + + View your full progress report here + + + } + /> + )} - {pageIndex == 1 && } - {pageIndex == 2 && } + + - - - ) - ; + )} + {pageIndex == 1 && ( + + )} + {pageIndex == 2 && } + + + + + ); }; const styles = StyleSheet.create({ - linkBtn: { - backgroundColor: "transparent", - padding: 0, - }, + linkBtn: { + backgroundColor: "transparent", + padding: 0, + }, }); export default ToDosPage; From 01338e7c708fd1fd3ad3e687900ce776a6ce0ae4 Mon Sep 17 00:00:00 2001 From: Milan Paunovic Date: Wed, 30 Oct 2024 02:41:00 +0100 Subject: [PATCH 44/66] Event filtering --- components/pages/calendar/EventCalendar.tsx | 14 ++++++++-- firebase/functions/index.js | 30 ++++++++++----------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/components/pages/calendar/EventCalendar.tsx b/components/pages/calendar/EventCalendar.tsx index da7500b..c9a1b01 100644 --- a/components/pages/calendar/EventCalendar.tsx +++ b/components/pages/calendar/EventCalendar.tsx @@ -13,6 +13,7 @@ import { import { useAuthContext } from "@/contexts/AuthContext"; import { CalendarEvent } from "@/components/pages/calendar/interfaces"; import { Text } from "react-native-ui-lib"; +import {addDays, isWithinInterval, subDays} from "date-fns"; interface EventCalendarProps { calendarHeight: number; @@ -46,7 +47,7 @@ export const EventCalendar: React.FC = React.memo( setIsRendering(true); const timeout = setTimeout(() => { setIsRendering(false); - }, 300); + }, 10 ); return () => clearTimeout(timeout); } }, [events, mode]); @@ -125,7 +126,16 @@ export const EventCalendar: React.FC = React.memo( } }, [mode]); - const memoizedEvents = useMemo(() => events ?? [], [events]); + const memoizedEvents = useMemo(() => { + const startOffset = mode === "month" ? 40 : mode === "week" ? 10 : 1; + const endOffset = mode === "month" ? 40 : mode === "week" ? 10 : 1; + + return events?.filter(event => + event.start && event.end && + isWithinInterval(event.start, { start: subDays(selectedDate, startOffset), end: addDays(selectedDate, endOffset) }) && + isWithinInterval(event.end, { start: subDays(selectedDate, startOffset), end: addDays(selectedDate, endOffset) }) + ) ?? []; + }, [events, selectedDate, mode]); const renderCustomDateForMonth = (date: Date) => { const circleStyle = useMemo( diff --git a/firebase/functions/index.js b/firebase/functions/index.js index 292b51c..9091619 100644 --- a/firebase/functions/index.js +++ b/firebase/functions/index.js @@ -18,7 +18,7 @@ exports.sendNotificationOnEventCreation = functions.firestore .document('Events/{eventId}') .onCreate(async (snapshot, context) => { const eventData = snapshot.data(); - const {familyId, creatorId, email} = eventData; + const { familyId, creatorId, email } = eventData; if (email) { console.log('Event has an email field. Skipping notification.'); @@ -30,12 +30,11 @@ exports.sendNotificationOnEventCreation = functions.firestore return; } + let pushTokens = await getPushTokensForFamilyExcludingCreator(familyId, creatorId); + if (!pushTokens.length) { - pushTokens = await getPushTokensForFamilyExcludingCreator(familyId, creatorId); - if (!pushTokens.length) { - console.log('No push tokens available for the event.'); - return; - } + console.log('No push tokens available for the event.'); + return; } eventCount++; @@ -49,21 +48,20 @@ exports.sendNotificationOnEventCreation = functions.firestore ? `An event "${eventData.title}" has been added. Check it out!` : `${eventCount} new events have been added.`; - let messages = []; - for (let pushToken of pushTokens) { + let messages = pushTokens.map(pushToken => { if (!Expo.isExpoPushToken(pushToken)) { console.error(`Push token ${pushToken} is not a valid Expo push token`); - continue; + return null; } - messages.push({ + return { to: pushToken, sound: 'default', title: 'New Events Added!', body: eventMessage, - data: {eventId: context.params.eventId}, - }); - } + data: { eventId: context.params.eventId }, + }; + }).filter(Boolean); let chunks = expo.chunkPushNotifications(messages); let tickets = []; @@ -78,7 +76,7 @@ exports.sendNotificationOnEventCreation = functions.firestore console.log('Notification successfully sent:', ticket.id); } else if (ticket.status === 'error') { console.error(`Notification error: ${ticket.message}`); - if (ticket.details && ticket.details.error === 'DeviceNotRegistered') { + if (ticket.details?.error === 'DeviceNotRegistered') { await removeInvalidPushToken(ticket.to); } } @@ -88,8 +86,8 @@ exports.sendNotificationOnEventCreation = functions.firestore } } - eventCount = 0; // Reset the event count after sending notification - pushTokens = []; // Reset push tokens for the next round + eventCount = 0; + pushTokens = []; }, 5000); }); From 06bd141b3c3aea129c009be0150303aeebba7050 Mon Sep 17 00:00:00 2001 From: Milan Paunovic Date: Wed, 30 Oct 2024 03:22:30 +0100 Subject: [PATCH 45/66] build nr updt --- app.json | 2 +- components/pages/calendar/EventCalendar.tsx | 18 +++++++++--------- ios/cally/Info.plist | 4 +++- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/app.json b/app.json index e85ec28..be7d2dc 100644 --- a/app.json +++ b/app.json @@ -16,7 +16,7 @@ "supportsTablet": true, "bundleIdentifier": "com.cally.app", "googleServicesFile": "./ios/GoogleService-Info.plist", - "buildNumber": "52", + "buildNumber": "53", "usesAppleSignIn": true }, "android": { diff --git a/components/pages/calendar/EventCalendar.tsx b/components/pages/calendar/EventCalendar.tsx index c9a1b01..f5590c5 100644 --- a/components/pages/calendar/EventCalendar.tsx +++ b/components/pages/calendar/EventCalendar.tsx @@ -137,11 +137,10 @@ export const EventCalendar: React.FC = React.memo( ) ?? []; }, [events, selectedDate, mode]); - const renderCustomDateForMonth = (date: Date) => { - const circleStyle = useMemo( - () => ({ - position: "absolute", - width: 30, + const renderCustomDateForMonth = (date: Date) => { + const circleStyle = useMemo( + () => ({ + width: 30, height: 30, justifyContent: "center", alignItems: "center", @@ -238,13 +237,14 @@ export const EventCalendar: React.FC = React.memo( }} dayHeaderStyle={dateStyle} dayHeaderHighlightColor={"white"} - renderCustomDateForMonth={renderCustomDateForMonth} + // renderCustomDateForMonth={renderCustomDateForMonth} showAdjacentMonths hourStyle={styles.hourStyle} ampm - /> - ); - } + + /> + ); + } ); const styles = StyleSheet.create({ diff --git a/ios/cally/Info.plist b/ios/cally/Info.plist index a32a87c..5ea67e0 100644 --- a/ios/cally/Info.plist +++ b/ios/cally/Info.plist @@ -47,7 +47,7 @@ CFBundleVersion - 52 + 53 LSRequiresIPhoneOS NSAppTransportSecurity @@ -131,6 +131,8 @@ $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route + $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route + $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route UILaunchStoryboardName SplashScreen From f7c121772ad4651313a38b739e4a1bdb09abf1e1 Mon Sep 17 00:00:00 2001 From: Dejan Date: Wed, 30 Oct 2024 23:37:43 +0100 Subject: [PATCH 46/66] - Reverted check if start time and end time overlap, caused an issue --- components/pages/calendar/ManuallyAddEventModal.tsx | 8 -------- 1 file changed, 8 deletions(-) diff --git a/components/pages/calendar/ManuallyAddEventModal.tsx b/components/pages/calendar/ManuallyAddEventModal.tsx index 888ec2f..326f4e2 100644 --- a/components/pages/calendar/ManuallyAddEventModal.tsx +++ b/components/pages/calendar/ManuallyAddEventModal.tsx @@ -383,10 +383,6 @@ export const ManuallyAddEventModal = () => { onChange={(time) => { if (time <= endTime) { setStartTime(time); - } else { - const currentTime = new Date(); - currentTime.setSeconds(0, 0); - setStartTime(currentTime); } }} minuteInterval={5} @@ -428,10 +424,6 @@ export const ManuallyAddEventModal = () => { onChange={(time) => { if (time >= endTime) { setEndTime(time); - } else { - const currentTime = new Date(); - currentTime.setSeconds(0, 0); - setEndTime(currentTime); } }} minimumDate={startTime} From 1417ec8f9bfadfeef5cb4b62d6aef5159000525c Mon Sep 17 00:00:00 2001 From: ivic00 <102467664+ivic00@users.noreply.github.com> Date: Wed, 30 Oct 2024 23:44:37 +0100 Subject: [PATCH 47/66] ui fixes --- assets/svgs/PlusIcon.tsx | 19 + components/pages/brain_dump/BrainDumpPage.tsx | 5 +- components/pages/calendar/AddEventDialog.tsx | 5 +- components/pages/grocery/AddGroceryItem.tsx | 10 +- components/pages/grocery/EditGroceryItem.tsx | 329 ++++++++++-------- components/pages/grocery/GroceryItem.tsx | 154 ++++---- components/pages/grocery/GroceryList.tsx | 5 +- components/pages/grocery/GroceryWrapper.tsx | 79 +++-- components/pages/todos/AddChore.tsx | 31 +- components/pages/todos/ToDoItem.tsx | 11 +- components/pages/todos/ToDosList.tsx | 287 ++++++++++----- components/pages/todos/ToDosPage.tsx | 1 - 12 files changed, 585 insertions(+), 351 deletions(-) create mode 100644 assets/svgs/PlusIcon.tsx diff --git a/assets/svgs/PlusIcon.tsx b/assets/svgs/PlusIcon.tsx new file mode 100644 index 0000000..5e9af64 --- /dev/null +++ b/assets/svgs/PlusIcon.tsx @@ -0,0 +1,19 @@ +import * as React from "react"; +import Svg, { SvgProps, Path } from "react-native-svg"; +const PlusIcon = (props: SvgProps) => ( + + + +); +export default PlusIcon; diff --git a/components/pages/brain_dump/BrainDumpPage.tsx b/components/pages/brain_dump/BrainDumpPage.tsx index 979e9c9..98782c5 100644 --- a/components/pages/brain_dump/BrainDumpPage.tsx +++ b/components/pages/brain_dump/BrainDumpPage.tsx @@ -6,6 +6,7 @@ import HeaderTemplate from "@/components/shared/HeaderTemplate"; import {Feather, MaterialIcons} from "@expo/vector-icons"; import AddBrainDump from "./AddBrainDump"; import LinearGradient from "react-native-linear-gradient"; +import PlusIcon from "@/assets/svgs/PlusIcon"; const BrainDumpPage = () => { const [searchText, setSearchText] = useState(""); @@ -85,10 +86,10 @@ const BrainDumpPage = () => { }} > - + New diff --git a/components/pages/calendar/AddEventDialog.tsx b/components/pages/calendar/AddEventDialog.tsx index def5322..1eab83d 100644 --- a/components/pages/calendar/AddEventDialog.tsx +++ b/components/pages/calendar/AddEventDialog.tsx @@ -10,6 +10,7 @@ import CalendarIcon from "@/assets/svgs/CalendarIcon"; import NavToDosIcon from "@/assets/svgs/NavToDosIcon"; import {useSetAtom} from "jotai"; import {selectedNewEventDateAtom} from "@/components/pages/calendar/atoms"; +import PlusIcon from "@/assets/svgs/PlusIcon"; export const AddEventDialog = () => { const [show, setShow] = useState(false); @@ -50,8 +51,8 @@ export const AddEventDialog = () => { onPress={() => setShow(true)} > - - + + New diff --git a/components/pages/grocery/AddGroceryItem.tsx b/components/pages/grocery/AddGroceryItem.tsx index 5304a7a..ec5c7f2 100644 --- a/components/pages/grocery/AddGroceryItem.tsx +++ b/components/pages/grocery/AddGroceryItem.tsx @@ -3,6 +3,7 @@ import React from "react"; import {Button, View,} from "react-native-ui-lib"; import {useGroceryContext} from "@/contexts/GroceryContext"; import {FontAwesome6} from "@expo/vector-icons"; +import PlusIcon from "@/assets/svgs/PlusIcon"; const AddGroceryItem = () => { const {setIsAddingGrocery} = useGroceryContext(); @@ -11,12 +12,12 @@ const AddGroceryItem = () => { @@ -25,7 +26,7 @@ const AddGroceryItem = () => { backgroundColor="#fd1775" label="Add item" text70L - iconSource={() => } + iconSource={() => } style={styles.finishShopBtn} labelStyle={styles.addBtnLbl} enableShadow @@ -69,6 +70,7 @@ const styles = StyleSheet.create({ }, finishShopBtn: { width: "100%", + height: 53.26, }, shoppingBtn: { flex: 1, diff --git a/components/pages/grocery/EditGroceryItem.tsx b/components/pages/grocery/EditGroceryItem.tsx index 0aecb91..812e98d 100644 --- a/components/pages/grocery/EditGroceryItem.tsx +++ b/components/pages/grocery/EditGroceryItem.tsx @@ -1,167 +1,204 @@ -import {Text, TextField, TextFieldRef, View} from "react-native-ui-lib"; -import React, {useEffect, useRef} from "react"; -import {GroceryCategory, useGroceryContext} from "@/contexts/GroceryContext"; -import {Dropdown} from "react-native-element-dropdown"; +import { Text, TextField, TextFieldRef, View } from "react-native-ui-lib"; +import React, { useEffect, useRef } from "react"; +import { GroceryCategory, useGroceryContext } from "@/contexts/GroceryContext"; +import { Dropdown } from "react-native-element-dropdown"; import CloseXIcon from "@/assets/svgs/CloseXIcon"; -import {StyleSheet} from "react-native"; +import { findNodeHandle, StyleSheet, UIManager } from "react-native"; import DropdownIcon from "@/assets/svgs/DropdownIcon"; -import {AntDesign} from "@expo/vector-icons"; +import { AntDesign } from "@expo/vector-icons"; interface IEditGrocery { - id?: string; - title: string; - category: GroceryCategory; - setTitle: (value: string) => void; - setCategory?: (category: GroceryCategory) => void; - setSubmit?: (value: boolean) => void; - closeEdit?: () => void; - handleEditSubmit?: Function; + id?: string; + title: string; + category: GroceryCategory; + setTitle: (value: string) => void; + setCategory?: (category: GroceryCategory) => void; + setSubmit?: (value: boolean) => void; + closeEdit?: () => void; + handleEditSubmit?: Function; } +const EditGroceryItem = ({ + editGrocery, + onInputFocus, +}: { + editGrocery: IEditGrocery; + onInputFocus: (y: number) => void; +}) => { + const { fuzzyMatchGroceryCategory } = useGroceryContext(); + const inputRef = useRef(null); + const containerRef = useRef(null); -const EditGroceryItem = ({editGrocery}: { editGrocery: IEditGrocery }) => { - const {fuzzyMatchGroceryCategory} = useGroceryContext(); - const inputRef = useRef(null); + const handleFocus = () => { + if (containerRef.current) { + const handle = findNodeHandle(containerRef.current); + if (handle) { + UIManager.measure( + handle, + ( + x: number, + y: number, + width: number, + height: number, + pageX: number, + pageY: number + ) => { + onInputFocus(pageY); + } + ); + } + } + }; - const groceryCategoryOptions = Object.values(GroceryCategory).map( - (category) => ({ - label: category, - value: category, - }) - ); + const groceryCategoryOptions = Object.values(GroceryCategory).map( + (category) => ({ + label: category, + value: category, + }) + ); - const handleSubmit = () => { - inputRef?.current?.blur() - console.log("CALLLLLL") - if (editGrocery.setSubmit) { - editGrocery.setSubmit(true); - } - if (editGrocery.handleEditSubmit) { - editGrocery.handleEditSubmit({ - id: editGrocery.id, - title: editGrocery.title, - category: editGrocery.category, - }); - } - if (editGrocery.closeEdit) { - editGrocery.closeEdit(); - } + const handleSubmit = () => { + inputRef?.current?.blur(); + console.log("CALLLLLL"); + if (editGrocery.setSubmit) { + editGrocery.setSubmit(true); + } + if (editGrocery.handleEditSubmit) { + editGrocery.handleEditSubmit({ + id: editGrocery.id, + title: editGrocery.title, + category: editGrocery.category, + }); + } + if (editGrocery.closeEdit) { + editGrocery.closeEdit(); + } + }; + + useEffect(() => { + if (inputRef.current) { + inputRef.current.focus(); } - useEffect(() => { - if (inputRef.current) { - inputRef.current.focus(); - } + console.log(editGrocery.category); + }, []); - console.log(editGrocery.category); - }, []); - - return ( - + + { + editGrocery.setTitle(value); + let groceryCategory = fuzzyMatchGroceryCategory(value); + if (editGrocery.setCategory) { + editGrocery.setCategory(groceryCategory); + } + }} + maxLength={25} + /> + + - - { - editGrocery.setTitle(value); - let groceryCategory = fuzzyMatchGroceryCategory(value); - if (editGrocery.setCategory) { - editGrocery.setCategory(groceryCategory); - } - }} - maxLength={25} - /> - - - { - if (editGrocery.closeEdit) { - editGrocery.closeEdit(); - } - }} - /> - - - ( - - )} - renderItem={(item) => { - return ( - - {item.label} - - ); - }} - onChange={(item) => { - if (editGrocery.handleEditSubmit) { - editGrocery.handleEditSubmit({ - id: editGrocery.id, - category: item.value, - }); - if (editGrocery.closeEdit) editGrocery.closeEdit(); - } else { - if (editGrocery.setCategory) { - editGrocery.setCategory(item.value); - } - } - }} - /> + onPress={handleSubmit} + /> + { + if (editGrocery.closeEdit) { + editGrocery.closeEdit(); + } + }} + /> - ); + + ( + + )} + renderItem={(item) => { + return ( + + {item.label} + + ); + }} + onChange={(item) => { + if (editGrocery.handleEditSubmit) { + editGrocery.handleEditSubmit({ + id: editGrocery.id, + category: item.value, + }); + if (editGrocery.closeEdit) editGrocery.closeEdit(); + } else { + if (editGrocery.setCategory) { + editGrocery.setCategory(item.value); + } + } + }} + /> + + ); }; const styles = StyleSheet.create({ - itemText: { - fontFamily: "Manrope_400Regular", - fontSize: 15.42, - paddingLeft: 15, - }, - selectedText: { - fontFamily: "Manrope_500Medium", - fontSize: 13.2, - color: "#fd1775", - }, - dropdownStyle: {borderRadius: 6.61, height: 115.34, width: 187}, - itemStyle: {padding: 0, margin: 0}, + itemText: { + fontFamily: "Manrope_400Regular", + fontSize: 15.42, + paddingLeft: 15, + }, + selectedText: { + fontFamily: "Manrope_500Medium", + fontSize: 13.2, + color: "#fd1775", + }, + dropdownStyle: { borderRadius: 6.61, height: 115.34, width: 187 }, + itemStyle: { padding: 0, margin: 0 }, }); export default EditGroceryItem; diff --git a/components/pages/grocery/GroceryItem.tsx b/components/pages/grocery/GroceryItem.tsx index e521e44..45427f6 100644 --- a/components/pages/grocery/GroceryItem.tsx +++ b/components/pages/grocery/GroceryItem.tsx @@ -1,21 +1,23 @@ -import {Checkbox, Text, TouchableOpacity, View} from "react-native-ui-lib"; -import React, {useEffect, useState} from "react"; -import {AntDesign} from "@expo/vector-icons"; -import {GroceryCategory, useGroceryContext} from "@/contexts/GroceryContext"; +import { Checkbox, Text, TouchableOpacity, View } from "react-native-ui-lib"; +import React, { useEffect, useState } from "react"; +import { AntDesign } from "@expo/vector-icons"; +import { GroceryCategory, useGroceryContext } from "@/contexts/GroceryContext"; import EditGroceryFrequency from "./EditGroceryFrequency"; import EditGroceryItem from "./EditGroceryItem"; -import {ImageBackground, StyleSheet} from "react-native"; -import {IGrocery} from "@/hooks/firebase/types/groceryData"; +import { ImageBackground, StyleSheet } from "react-native"; +import { IGrocery } from "@/hooks/firebase/types/groceryData"; import firestore from "@react-native-firebase/firestore"; -import {UserProfile} from "@/hooks/firebase/types/profileTypes"; -import {ProfileType, useAuthContext} from "@/contexts/AuthContext"; +import { UserProfile } from "@/hooks/firebase/types/profileTypes"; +import { ProfileType, useAuthContext } from "@/contexts/AuthContext"; const GroceryItem = ({ item, handleItemApproved, + onInputFocus, }: { item: IGrocery; handleItemApproved: (id: string, changes: Partial) => void; + onInputFocus: (y: number) => void; }) => { const { updateGroceryItem } = useGroceryContext(); const { profileData } = useAuthContext(); @@ -24,12 +26,14 @@ const GroceryItem = ({ const [openFreqEdit, setOpenFreqEdit] = useState(false); const [isEditingTitle, setIsEditingTitle] = useState(false); const [newTitle, setNewTitle] = useState(item.title ?? ""); - const [category, setCategory] = useState(item.category ?? GroceryCategory.None); + const [category, setCategory] = useState( + item.category ?? GroceryCategory.None + ); const [itemCreator, setItemCreator] = useState(null); const closeEdit = () => { setIsEditingTitle(false); - } + }; const handleTitleChange = (newTitle: string) => { updateGroceryItem({ id: item?.id, title: newTitle }); @@ -82,57 +86,70 @@ const GroceryItem = ({ setOpenFreqEdit(false); }} /> - {isEditingTitle ? - : - - {isParent ? - setIsEditingTitle(true)}> - - {item.title} - - : + {isEditingTitle ? ( + + ) : ( + + {isParent ? ( + setIsEditingTitle(true)}> {item.title} - } - - } + + ) : ( + + {item.title} + + )} + + )} {!item.approved ? ( - {isParent && - <> - handleItemApproved(item.id, { approved: true }) : null} - /> - handleItemApproved(item.id, { approved: false }) : null} - /> - } + {isParent && ( + <> + handleItemApproved(item.id, { approved: true }) + : null + } + /> + handleItemApproved(item.id, { approved: false }) + : null + } + /> + + )} ) : ( - !isEditingTitle && isParent && ( + !isEditingTitle && + isParent && ( - {profileData?.pfp ? : + /> + ) : ( - - - {itemCreator ? getInitials(itemCreator.firstName, itemCreator.lastName) : ""} - + + {itemCreator + ? getInitials(itemCreator.firstName, itemCreator.lastName) + : ""} + + - } + )} Requested by {itemCreator?.firstName} diff --git a/components/pages/grocery/GroceryList.tsx b/components/pages/grocery/GroceryList.tsx index 7c495b7..b6ec6da 100644 --- a/components/pages/grocery/GroceryList.tsx +++ b/components/pages/grocery/GroceryList.tsx @@ -10,7 +10,7 @@ import {ProfileType, useAuthContext} from "@/contexts/AuthContext"; import {IGrocery} from "@/hooks/firebase/types/groceryData"; import AddPersonIcon from "@/assets/svgs/AddPersonIcon"; -const GroceryList = () => { +const GroceryList = ({onInputFocus}: {onInputFocus: (y: number) => void}) => { const { groceries, updateGroceryItem, @@ -169,6 +169,7 @@ const GroceryList = () => { handleItemApproved={(id, changes) => updateGroceryItem({...changes, id: id}) } + onInputFocus={onInputFocus} /> )} keyExtractor={(item) => item.id.toString()} @@ -230,6 +231,7 @@ const GroceryList = () => { setSubmit: setSubmitted, closeEdit: () => setIsAddingGrocery(false) }} + onInputFocus={onInputFocus} /> )} @@ -254,6 +256,7 @@ const GroceryList = () => { handleItemApproved={(id, changes) => updateGroceryItem({...changes, id: id}) } + onInputFocus={onInputFocus} /> ) )} diff --git a/components/pages/grocery/GroceryWrapper.tsx b/components/pages/grocery/GroceryWrapper.tsx index fd91bd3..b93db37 100644 --- a/components/pages/grocery/GroceryWrapper.tsx +++ b/components/pages/grocery/GroceryWrapper.tsx @@ -1,42 +1,79 @@ -import { Dimensions, ScrollView } from "react-native"; +import { Dimensions, ScrollView, Keyboard, Platform } from "react-native"; import { View } from "react-native-ui-lib"; -import React, { useEffect, useRef } from "react"; +import React, { useEffect, useRef, useState } from "react"; import AddGroceryItem from "./AddGroceryItem"; import GroceryList from "./GroceryList"; import { useGroceryContext } from "@/contexts/GroceryContext"; const GroceryWrapper = () => { const { isAddingGrocery } = useGroceryContext(); - const scrollViewRef = useRef(null); // Reference to the ScrollView + const scrollViewRef = useRef(null); + const [keyboardHeight, setKeyboardHeight] = useState(0); + + useEffect(() => { + const keyboardWillShowListener = Keyboard.addListener( + Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow', + (e) => { + setKeyboardHeight(e.endCoordinates.height); + } + ); + + const keyboardWillHideListener = Keyboard.addListener( + Platform.OS === 'ios' ? 'keyboardWillHide' : 'keyboardDidHide', + () => { + setKeyboardHeight(0); + } + ); + + return () => { + keyboardWillShowListener.remove(); + keyboardWillHideListener.remove(); + }; + }, []); useEffect(() => { if (isAddingGrocery && scrollViewRef.current) { scrollViewRef.current.scrollTo({ - y: 400, // Adjust this value to scroll a bit down (100 is an example) + y: 400, animated: true, }); } }, [isAddingGrocery]); + const handleInputFocus = (y: number) => { + if (scrollViewRef.current) { + // Get the window height + const windowHeight = Dimensions.get('window').height; + // Calculate the space we want to leave at the top + const topSpacing = 20; + + // Calculate the target scroll position: + // y (position of input) - topSpacing (space we want at top) + // if keyboard is shown, we need to account for its height + const scrollPosition = Math.max(0, y - topSpacing); + + scrollViewRef.current.scrollTo({ + y: scrollPosition, + animated: true, + }); + } + }; + return ( - - - - - - - - - - + <> + + + + + {!isAddingGrocery && } - + ); }; -export default GroceryWrapper; +export default GroceryWrapper; \ No newline at end of file diff --git a/components/pages/todos/AddChore.tsx b/components/pages/todos/AddChore.tsx index 4ba3fc8..0c66e8e 100644 --- a/components/pages/todos/AddChore.tsx +++ b/components/pages/todos/AddChore.tsx @@ -1,38 +1,46 @@ -import { StyleSheet } from "react-native"; +import { Dimensions, StyleSheet } from "react-native"; import React, { useState } from "react"; import { Button, ButtonSize, Text, View } from "react-native-ui-lib"; import { AntDesign } from "@expo/vector-icons"; import LinearGradient from "react-native-linear-gradient"; import AddChoreDialog from "./AddChoreDialog"; +import PlusIcon from "@/assets/svgs/PlusIcon"; const AddChore = () => { const [isVisible, setIsVisible] = useState(false); return ( - - {isVisible && } - + {isVisible && ( + + )} + ); }; @@ -53,8 +61,7 @@ const styles = StyleSheet.create({ }, button: { backgroundColor: "rgb(253, 23, 117)", - paddingVertical: 15, - paddingHorizontal: 30, + height: 53.26, borderRadius: 30, width: 335, }, diff --git a/components/pages/todos/ToDoItem.tsx b/components/pages/todos/ToDoItem.tsx index 7bc1446..55bb8c3 100644 --- a/components/pages/todos/ToDoItem.tsx +++ b/components/pages/todos/ToDoItem.tsx @@ -17,8 +17,13 @@ import AddChoreDialog from "@/components/pages/todos/AddChoreDialog"; import { useGetFamilyMembers } from "@/hooks/firebase/useGetFamilyMembers"; import RepeatIcon from "@/assets/svgs/RepeatIcon"; import { ProfileType, useAuthContext } from "@/contexts/AuthContext"; +import { format } from "date-fns"; -const ToDoItem = (props: { item: IToDo; isSettings?: boolean }) => { +const ToDoItem = (props: { + item: IToDo; + isSettings?: boolean; + is7Days?: boolean; +}) => { const { updateToDo } = useToDosContext(); const { data: members } = useGetFamilyMembers(); const { profileData } = useAuthContext(); @@ -55,6 +60,7 @@ const ToDoItem = (props: { item: IToDo; isSettings?: boolean }) => { return ( { return props.item.repeatType; } })()} + {props.item.date && + props.is7Days && + " / " + format(props.item.date, "EEEE")} )} diff --git a/components/pages/todos/ToDosList.tsx b/components/pages/todos/ToDosList.tsx index 6589427..431c293 100644 --- a/components/pages/todos/ToDosList.tsx +++ b/components/pages/todos/ToDosList.tsx @@ -14,40 +14,64 @@ import { IToDo } from "@/hooks/firebase/types/todoData"; const groupToDosByDate = (toDos: IToDo[]) => { let sortedTodos = toDos.sort((a, b) => a.date - b.date); - return sortedTodos.reduce((groups, toDo) => { - let dateKey; + return sortedTodos.reduce( + (groups, toDo) => { + let dateKey; + let subDateKey; - const isNext7Days = (date: Date) => { - const today = new Date(); - return isWithinInterval(date, { start: today, end: addDays(today, 7) }); - }; + const isNext7Days = (date: Date) => { + const today = new Date(); + return isWithinInterval(date, { start: today, end: addDays(today, 7) }); + }; - const isNext30Days = (date: Date) => { - const today = new Date(); - return isWithinInterval(date, { start: today, end: addDays(today, 30) }); - }; + const isNext30Days = (date: Date) => { + const today = new Date(); + return isWithinInterval(date, { + start: today, + end: addDays(today, 30), + }); + }; - if (toDo.date === null) { - dateKey = "No Date"; - } else if (isToday(toDo.date)) { - dateKey = "Today"; - } else if (isTomorrow(toDo.date)) { - dateKey = "Tomorrow"; - } else if (isNext7Days(toDo.date)) { - dateKey = "Next 7 Days"; - } else if (isNext30Days(toDo.date)) { - dateKey = "Next 30 Days"; - } else { - dateKey = format(toDo.date, "EEE MMM dd"); + if (toDo.date === null) { + dateKey = "No Date"; + } else if (isToday(toDo.date)) { + dateKey = "Today"; + } else if (isTomorrow(toDo.date)) { + dateKey = "Tomorrow"; + } else if (isNext7Days(toDo.date)) { + dateKey = "Next 7 Days"; + } else if (isNext30Days(toDo.date)) { + dateKey = "Next 30 Days"; + subDateKey = format(toDo.date, "MMM d"); + } else { + return groups; + } + + if (!groups[dateKey]) { + groups[dateKey] = { + items: [], + subgroups: {}, + }; + } + + if (dateKey === "Next 30 Days" && subDateKey) { + if (!groups[dateKey].subgroups[subDateKey]) { + groups[dateKey].subgroups[subDateKey] = []; + } + groups[dateKey].subgroups[subDateKey].push(toDo); + } else { + groups[dateKey].items.push(toDo); + } + + return groups; + }, + {} as { + [key: string]: { + items: IToDo[]; + subgroups: { [key: string]: IToDo[] }; + }; } - - if (!groups[dateKey]) { - groups[dateKey] = []; - } - - groups[dateKey].push(toDo); - return groups; - }, {} as { [key: string]: IToDo[] }); + ); }; const ToDosList = ({ isSettings }: { isSettings?: boolean }) => { @@ -67,11 +91,139 @@ const ToDosList = ({ isSettings }: { isSettings?: boolean }) => { })); }; - const noDateToDos = groupedToDos["No Date"] || []; + const noDateToDos = groupedToDos["No Date"]?.items || []; const datedToDos = Object.keys(groupedToDos).filter( (key) => key !== "No Date" ); + const renderTodoGroup = (dateKey: string) => { + const isExpanded = expandedGroups[dateKey] || false; + + if (dateKey === "Next 30 Days") { + const subgroups = Object.entries(groupedToDos[dateKey].subgroups).sort( + ([dateA], [dateB]) => { + const dateAObj = new Date(dateA); + const dateBObj = new Date(dateB); + return dateAObj.getTime() - dateBObj.getTime(); + } + ); + + return ( + + toggleExpand(dateKey)} + style={{ + flexDirection: "row", + justifyContent: "space-between", + alignItems: "center", + paddingHorizontal: 0, + marginBottom: 4, + marginTop: 15, + }} + > + + {dateKey} + + + + + {isExpanded && + subgroups.map(([subDate, items]) => { + const sortedItems = [ + ...items.filter((toDo) => !toDo.done), + ...items.filter((toDo) => toDo.done), + ]; + + return ( + + + + {subDate} + + + + {sortedItems.map((item) => ( + + ))} + + ); + })} + + ); + } + + const sortedToDos = [ + ...groupedToDos[dateKey].items.filter((toDo) => !toDo.done), + ...groupedToDos[dateKey].items.filter((toDo) => toDo.done), + ]; + + return ( + + toggleExpand(dateKey)} + style={{ + flexDirection: "row", + justifyContent: "space-between", + alignItems: "center", + paddingHorizontal: 0, + marginBottom: 4, + marginTop: 15, + }} + > + + {dateKey} + + + + + {isExpanded && + sortedToDos.map((item) => ( + + ))} + + ); + }; + return ( {noDateToDos.length > 0 && ( @@ -85,26 +237,14 @@ const ToDosList = ({ isSettings }: { isSettings?: boolean }) => { > Unscheduled - {!expandNoDate && ( - { - setExpandNoDate(!expandNoDate); - }} - /> - )} - {expandNoDate && ( - { - setExpandNoDate(!expandNoDate); - }} - /> - )} + { + setExpandNoDate(!expandNoDate); + }} + /> {expandNoDate && noDateToDos @@ -115,50 +255,7 @@ const ToDosList = ({ isSettings }: { isSettings?: boolean }) => { )} - {datedToDos.map((dateKey) => { - const isExpanded = expandedGroups[dateKey] || false; - const sortedToDos = [ - ...groupedToDos[dateKey].filter((toDo) => !toDo.done), - ...groupedToDos[dateKey].filter((toDo) => toDo.done), - ]; - - return ( - - toggleExpand(dateKey)} - style={{ - flexDirection: "row", - justifyContent: "space-between", - alignItems: "center", - paddingHorizontal: 0, - marginBottom: 4, - marginTop: 15, - }} - > - - {dateKey} - - {!isExpanded && ( - - )} - {isExpanded && ( - - )} - - - {isExpanded && - sortedToDos.map((item) => ( - - ))} - - ); - })} + {datedToDos.map(renderTodoGroup)} ); }; diff --git a/components/pages/todos/ToDosPage.tsx b/components/pages/todos/ToDosPage.tsx index b8ab4c6..590a901 100644 --- a/components/pages/todos/ToDosPage.tsx +++ b/components/pages/todos/ToDosPage.tsx @@ -32,7 +32,6 @@ const ToDosPage = () => { > From 632ec6cf154f46135e9c4417bd9c1d55e38a0dc6 Mon Sep 17 00:00:00 2001 From: Milan Paunovic Date: Thu, 31 Oct 2024 00:13:52 +0100 Subject: [PATCH 48/66] add event invalidation --- hooks/useFetchAndSaveAppleEvents.ts | 6 +++++- hooks/useFetchAndSaveGoogleEvents.ts | 6 +++++- hooks/useFetchAndSaveOutlookEvents.ts | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/hooks/useFetchAndSaveAppleEvents.ts b/hooks/useFetchAndSaveAppleEvents.ts index b0f1783..85f1cf7 100644 --- a/hooks/useFetchAndSaveAppleEvents.ts +++ b/hooks/useFetchAndSaveAppleEvents.ts @@ -1,9 +1,10 @@ -import {useMutation} from "react-query"; +import {useMutation, useQueryClient} from "react-query"; import {useAuthContext} from "@/contexts/AuthContext"; import {useCreateEventsFromProvider} from "@/hooks/firebase/useCreateEvent"; import {fetchiPhoneCalendarEvents} from "@/calendar-integration/apple-calendar-utils"; export const useFetchAndSaveAppleEvents = () => { + const queryClient = useQueryClient() const {profileData} = useAuthContext(); const {mutateAsync: createEventsFromProvider} = useCreateEventsFromProvider(); @@ -29,5 +30,8 @@ export const useFetchAndSaveAppleEvents = () => { throw error; } }, + onSuccess: () => { + queryClient.invalidateQueries(["events"]) + }, }); }; \ No newline at end of file diff --git a/hooks/useFetchAndSaveGoogleEvents.ts b/hooks/useFetchAndSaveGoogleEvents.ts index 7f823a0..d2bd62b 100644 --- a/hooks/useFetchAndSaveGoogleEvents.ts +++ b/hooks/useFetchAndSaveGoogleEvents.ts @@ -1,9 +1,10 @@ -import {useMutation} from "react-query"; +import {useMutation, useQueryClient} from "react-query"; import {fetchGoogleCalendarEvents} from "@/calendar-integration/google-calendar-utils"; import {useAuthContext} from "@/contexts/AuthContext"; import {useCreateEventsFromProvider} from "@/hooks/firebase/useCreateEvent"; export const useFetchAndSaveGoogleEvents = () => { + const queryClient = useQueryClient() const {profileData} = useAuthContext(); const {mutateAsync: createEventsFromProvider} = useCreateEventsFromProvider(); @@ -41,5 +42,8 @@ export const useFetchAndSaveGoogleEvents = () => { throw error; // Ensure errors are propagated to the mutation } }, + onSuccess: () => { + queryClient.invalidateQueries(["events"]) + }, }); }; \ No newline at end of file diff --git a/hooks/useFetchAndSaveOutlookEvents.ts b/hooks/useFetchAndSaveOutlookEvents.ts index 36540bb..5d5f6a3 100644 --- a/hooks/useFetchAndSaveOutlookEvents.ts +++ b/hooks/useFetchAndSaveOutlookEvents.ts @@ -1,9 +1,10 @@ -import {useMutation} from "react-query"; +import {useMutation, useQueryClient} from "react-query"; import {useAuthContext} from "@/contexts/AuthContext"; import {useCreateEventsFromProvider} from "@/hooks/firebase/useCreateEvent"; import {fetchMicrosoftCalendarEvents} from "@/calendar-integration/microsoft-calendar-utils"; export const useFetchAndSaveOutlookEvents = () => { + const queryClient = useQueryClient() const {profileData} = useAuthContext(); const {mutateAsync: createEventsFromProvider} = useCreateEventsFromProvider(); @@ -32,5 +33,8 @@ export const useFetchAndSaveOutlookEvents = () => { throw error; } }, + onSuccess: () => { + queryClient.invalidateQueries(["events"]) + }, }); }; \ No newline at end of file From 37f3d279993030abb32d64d2499f2b68189e8094 Mon Sep 17 00:00:00 2001 From: Milan Paunovic Date: Thu, 31 Oct 2024 02:35:50 +0100 Subject: [PATCH 49/66] Added react native big calendar patch --- app/(auth)/_layout.tsx | 11 +- components/pages/brain_dump/AddBrainDump.tsx | 16 +- components/pages/calendar/EventCalendar.tsx | 526 ++-- components/pages/calendar/interfaces.ts | 4 +- .../settings/user_settings_views/MyGroup.tsx | 7 +- firebase/functions/yarn.lock | 2353 +++++++++++++++++ ios/cally.xcodeproj/project.pbxproj | 4 +- ios/cally/Info.plist | 1 + package.json | 7 +- .../react-native-big-calendar+4.15.1.patch | 186 ++ yarn.lock | 88 +- 11 files changed, 2934 insertions(+), 269 deletions(-) create mode 100644 firebase/functions/yarn.lock create mode 100644 patches/react-native-big-calendar+4.15.1.patch diff --git a/app/(auth)/_layout.tsx b/app/(auth)/_layout.tsx index a735503..662daa9 100644 --- a/app/(auth)/_layout.tsx +++ b/app/(auth)/_layout.tsx @@ -23,7 +23,7 @@ import NavToDosIcon from "@/assets/svgs/NavToDosIcon"; import NavBrainDumpIcon from "@/assets/svgs/NavBrainDumpIcon"; import NavCalendarIcon from "@/assets/svgs/NavCalendarIcon"; import NavSettingsIcon from "@/assets/svgs/NavSettingsIcon"; -import { useAtom } from "jotai"; +import {useAtom, useSetAtom} from "jotai"; import { settingsPageIndex, toDosPageIndex, @@ -32,9 +32,9 @@ import { export default function TabLayout() { const { mutateAsync: signOut } = useSignOut(); - const [pageIndex, setPageIndex] = useAtom(settingsPageIndex); - const [userView, setUserView] = useAtom(userSettingsView); - const [toDosIndex, setToDosIndex] = useAtom(toDosPageIndex); + const setPageIndex = useSetAtom(settingsPageIndex); + const setUserView = useSetAtom(userSettingsView); + const setToDosIndex = useSetAtom(toDosPageIndex); return ( , }} drawerContent={(props) => { return ( @@ -234,7 +233,7 @@ export default function TabLayout() { name="todos" options={{ drawerLabel: "To-Do", - title: "To-Do's", + title: "To-Dos", }} /> diff --git a/components/pages/brain_dump/AddBrainDump.tsx b/components/pages/brain_dump/AddBrainDump.tsx index a134f5d..33fd602 100644 --- a/components/pages/brain_dump/AddBrainDump.tsx +++ b/components/pages/brain_dump/AddBrainDump.tsx @@ -13,6 +13,8 @@ import { Dimensions, Keyboard, StyleSheet } from "react-native"; import DropModalIcon from "@/assets/svgs/DropModalIcon"; import { useBrainDumpContext } from "@/contexts/DumpContext"; +import KeyboardManager from "react-native-keyboard-manager"; + interface IAddBrainDumpProps { isVisible: boolean; @@ -29,14 +31,26 @@ const AddBrainDump = ({ const [dumpDesc, setDumpDesc] = useState(""); const { width } = Dimensions.get("screen"); + // Refs for the two TextFields const descriptionRef = useRef(null); + const titleRef = useRef(null); useEffect(() => { setDumpDesc(""); setDumpTitle(""); }, [addBrainDumpProps.isVisible]); + useEffect(() => { + setTimeout(() => { + titleRef?.current?.focus() + }, 500) + }, []); + + useEffect(() => { + KeyboardManager.setEnableAutoToolbar(false); + },[]) + return ( { diff --git a/components/pages/calendar/EventCalendar.tsx b/components/pages/calendar/EventCalendar.tsx index f5590c5..e5bac28 100644 --- a/components/pages/calendar/EventCalendar.tsx +++ b/components/pages/calendar/EventCalendar.tsx @@ -1,293 +1,325 @@ -import React, { useCallback, useEffect, useMemo, useState } from "react"; -import { Calendar } from "react-native-big-calendar"; -import { ActivityIndicator, StyleSheet, View, ViewStyle } from "react-native"; -import { useGetEvents } from "@/hooks/firebase/useGetEvents"; -import { useAtom, useSetAtom } from "jotai"; +import React, {useCallback, useEffect, useMemo, useState} from "react"; +import {Calendar} from "react-native-big-calendar"; +import {ActivityIndicator, StyleSheet, View, ViewStyle} from "react-native"; +import {useGetEvents} from "@/hooks/firebase/useGetEvents"; +import {useAtom, useSetAtom} from "jotai"; import { - editVisibleAtom, - eventForEditAtom, - modeAtom, - selectedDateAtom, - selectedNewEventDateAtom, + editVisibleAtom, + eventForEditAtom, + modeAtom, + selectedDateAtom, + selectedNewEventDateAtom, } from "@/components/pages/calendar/atoms"; -import { useAuthContext } from "@/contexts/AuthContext"; -import { CalendarEvent } from "@/components/pages/calendar/interfaces"; -import { Text } from "react-native-ui-lib"; -import {addDays, isWithinInterval, subDays} from "date-fns"; +import {useAuthContext} from "@/contexts/AuthContext"; +import {CalendarEvent} from "@/components/pages/calendar/interfaces"; +import {Text} from "react-native-ui-lib"; +import { isWithinInterval, subDays, addDays, compareAsc } from "date-fns"; interface EventCalendarProps { - calendarHeight: number; - // WAS USED FOR SCROLLABLE CALENDARS, PERFORMANCE WAS NOT OPTIMAL - calendarWidth: number; + calendarHeight: number; + // WAS USED FOR SCROLLABLE CALENDARS, PERFORMANCE WAS NOT OPTIMAL + calendarWidth: number; } const getTotalMinutes = () => { - const date = new Date(); - return Math.abs(date.getUTCHours() * 60 + date.getUTCMinutes() - 200); + const date = new Date(); + return Math.abs(date.getUTCHours() * 60 + date.getUTCMinutes() - 200); }; export const EventCalendar: React.FC = React.memo( - ({ calendarHeight }) => { - const { data: events, isLoading } = useGetEvents(); - const { profileData } = useAuthContext(); - const [selectedDate, setSelectedDate] = useAtom(selectedDateAtom); - const [mode, setMode] = useAtom(modeAtom); + ({calendarHeight}) => { + const {data: events, isLoading} = useGetEvents(); + const {profileData} = useAuthContext(); + const [selectedDate, setSelectedDate] = useAtom(selectedDateAtom); + const [mode, setMode] = useAtom(modeAtom); - const setEditVisible = useSetAtom(editVisibleAtom); - const setEventForEdit = useSetAtom(eventForEditAtom); - const setSelectedNewEndDate = useSetAtom(selectedNewEventDateAtom); + const setEditVisible = useSetAtom(editVisibleAtom); + const setEventForEdit = useSetAtom(eventForEditAtom); + const setSelectedNewEndDate = useSetAtom(selectedNewEventDateAtom); - const [isRendering, setIsRendering] = useState(true); - const [offsetMinutes, setOffsetMinutes] = useState(getTotalMinutes()); + const [isRendering, setIsRendering] = useState(true); + const [offsetMinutes, setOffsetMinutes] = useState(getTotalMinutes()); - const todaysDate = new Date(); + const todaysDate = new Date(); - useEffect(() => { - if (events && mode) { - setIsRendering(true); - const timeout = setTimeout(() => { - setIsRendering(false); - }, 10 ); - return () => clearTimeout(timeout); - } - }, [events, mode]); + useEffect(() => { + if (events && mode) { + setIsRendering(true); + const timeout = setTimeout(() => { + setIsRendering(false); + }, 10); + return () => clearTimeout(timeout); + } + }, [events, mode]); - const handlePressEvent = useCallback( - (event: CalendarEvent) => { - if (mode === "day" || mode === "week") { - setEditVisible(true); - console.log({ event }); - setEventForEdit(event); - } else { - setMode("day"); - setSelectedDate(event.start); - } - }, - [setEditVisible, setEventForEdit, mode] - ); + const handlePressEvent = useCallback( + (event: CalendarEvent) => { + if (mode === "day" || mode === "week") { + setEditVisible(true); + console.log({event}); + setEventForEdit(event); + } else { + setMode("day"); + setSelectedDate(event.start); + } + }, + [setEditVisible, setEventForEdit, mode] + ); - const handlePressCell = useCallback( - (date: Date) => { - if (mode === "day" || mode === "week") { - setSelectedNewEndDate(date); - } else { - setMode("day"); - setSelectedDate(date); - } - }, - [mode, setSelectedNewEndDate, setSelectedDate] - ); + const handlePressCell = useCallback( + (date: Date) => { + if (mode === "day" || mode === "week") { + setSelectedNewEndDate(date); + } else { + setMode("day"); + setSelectedDate(date); + } + }, + [mode, setSelectedNewEndDate, setSelectedDate] + ); - const handleSwipeEnd = useCallback( - (date: Date) => { - setSelectedDate(date); - }, - [setSelectedDate] - ); + const handleSwipeEnd = useCallback( + (date: Date) => { + setSelectedDate(date); + }, + [setSelectedDate] + ); - const memoizedEventCellStyle = useCallback( - (event: CalendarEvent) => ({ backgroundColor: event.eventColor }), - [] - ); + const memoizedEventCellStyle = useCallback( + (event: CalendarEvent) => ({backgroundColor: event.eventColor}), + [] + ); - const memoizedWeekStartsOn = useMemo( - () => (profileData?.firstDayOfWeek === "Mondays" ? 1 : 0), - [profileData] - ); + const memoizedWeekStartsOn = useMemo( + () => (profileData?.firstDayOfWeek === "Mondays" ? 1 : 0), + [profileData] + ); - const isSameDate = useCallback((date1: Date, date2: Date) => { - return ( - date1.getDate() === date2.getDate() && - date1.getMonth() === date2.getMonth() && - date1.getFullYear() === date2.getFullYear() - ); - }, []); + const isSameDate = useCallback((date1: Date, date2: Date) => { + return ( + date1.getDate() === date2.getDate() && + date1.getMonth() === date2.getMonth() && + date1.getFullYear() === date2.getFullYear() + ); + }, []); - const dayHeaderColor = useMemo(() => { - return isSameDate(todaysDate, selectedDate) ? "white" : "#4d4d4d"; - }, [selectedDate, mode]); + const dayHeaderColor = useMemo(() => { + return isSameDate(todaysDate, selectedDate) ? "white" : "#4d4d4d"; + }, [selectedDate, mode]); - const dateStyle = useMemo(() => { - if (mode === "week") return undefined; - return isSameDate(todaysDate, selectedDate) && mode === "day" - ? styles.dayHeader - : styles.otherDayHeader; - }, [selectedDate, mode]); + const dateStyle = useMemo(() => { + if (mode === "week") return undefined; + return isSameDate(todaysDate, selectedDate) && mode === "day" + ? styles.dayHeader + : styles.otherDayHeader; + }, [selectedDate, mode]); - const memoizedHeaderContentStyle = useMemo(() => { - if (mode === "day") { - return styles.dayModeHeader; - } else if (mode === "week") { - return styles.weekModeHeader; - } else if (mode === "month") { - return styles.monthModeHeader; - } else { - return {}; - } - }, [mode]); + const memoizedHeaderContentStyle = useMemo(() => { + if (mode === "day") { + return styles.dayModeHeader; + } else if (mode === "week") { + return styles.weekModeHeader; + } else if (mode === "month") { + return styles.monthModeHeader; + } else { + return {}; + } + }, [mode]); - const memoizedEvents = useMemo(() => { - const startOffset = mode === "month" ? 40 : mode === "week" ? 10 : 1; - const endOffset = mode === "month" ? 40 : mode === "week" ? 10 : 1; - return events?.filter(event => - event.start && event.end && - isWithinInterval(event.start, { start: subDays(selectedDate, startOffset), end: addDays(selectedDate, endOffset) }) && - isWithinInterval(event.end, { start: subDays(selectedDate, startOffset), end: addDays(selectedDate, endOffset) }) - ) ?? []; - }, [events, selectedDate, mode]); + const { enrichedEvents, filteredEvents } = useMemo(() => { + const startTime = Date.now(); // Start timer + + const startOffset = mode === "month" ? 40 : mode === "week" ? 10 : 1; + const endOffset = mode === "month" ? 40 : mode === "week" ? 10 : 1; + + const filteredEvents = events?.filter(event => + event.start && event.end && + isWithinInterval(event.start, { + start: subDays(selectedDate, startOffset), + end: addDays(selectedDate, endOffset) + }) && + isWithinInterval(event.end, { + start: subDays(selectedDate, startOffset), + end: addDays(selectedDate, endOffset) + }) + ) ?? []; + + const enrichedEvents = filteredEvents.reduce((acc, event) => { + const dateKey = event.start.toISOString().split('T')[0]; + acc[dateKey] = acc[dateKey] || []; + acc[dateKey].push({ + ...event, + overlapPosition: false, + overlapCount: 0 + }); + + // Sort events for this dateKey from oldest to newest by event.start + acc[dateKey].sort((a, b) => compareAsc(a.start, b.start)); + + return acc; + }, {} as Record); + + const endTime = Date.now(); // End timer + console.log("memoizedEvents computation time:", endTime - startTime, "ms"); + + return { enrichedEvents, filteredEvents }; + }, [events, selectedDate, mode]); const renderCustomDateForMonth = (date: Date) => { const circleStyle = useMemo( () => ({ width: 30, - height: 30, - justifyContent: "center", - alignItems: "center", - borderRadius: 15, - }), - [] - ); + height: 30, + justifyContent: "center", + alignItems: "center", + borderRadius: 15, + }), + [] + ); - const defaultStyle = useMemo( - () => ({ - ...circleStyle, - }), - [circleStyle] - ); + const defaultStyle = useMemo( + () => ({ + ...circleStyle, + }), + [circleStyle] + ); - const currentDateStyle = useMemo( - () => ({ - ...circleStyle, - backgroundColor: "#4184f2", - }), - [circleStyle] - ); + const currentDateStyle = useMemo( + () => ({ + ...circleStyle, + backgroundColor: "#4184f2", + }), + [circleStyle] + ); - const renderDate = useCallback( - (date: Date) => { - const isCurrentDate = isSameDate(todaysDate, date); - const appliedStyle = isCurrentDate ? currentDateStyle : defaultStyle; + const renderDate = useCallback( + (date: Date) => { + const isCurrentDate = isSameDate(todaysDate, date); + const appliedStyle = isCurrentDate ? currentDateStyle : defaultStyle; - return ( - - - - {date.getDate()} - - - - ); - }, - [todaysDate, currentDateStyle, defaultStyle] // dependencies - ); + return ( + + + + {date.getDate()} + + + + ); + }, + [todaysDate, currentDateStyle, defaultStyle] // dependencies + ); - return renderDate(date); - }; + return renderDate(date); + }; - useEffect(() => { - setOffsetMinutes(getTotalMinutes()); - }, [events, mode]); + useEffect(() => { + setOffsetMinutes(getTotalMinutes()); + }, [events, mode]); - if (isLoading || isRendering) { - return ( - - - - ); - } + if (isLoading || isRendering) { + return ( + + + + ); + } - return ( - ); } ); const styles = StyleSheet.create({ - segmentslblStyle: { - fontSize: 12, - fontFamily: "Manrope_600SemiBold", - }, - calHeader: { - borderWidth: 0, - }, - dayModeHeader: { - alignSelf: "flex-start", - justifyContent: "space-between", - alignContent: "center", - width: 38, - right: 42, - height: 13, - }, - weekModeHeader: {}, - monthModeHeader: {}, - loadingContainer: { - flex: 1, - justifyContent: "center", - alignItems: "center", - }, - dayHeader: { - backgroundColor: "#4184f2", - aspectRatio: 1, - borderRadius: 100, - alignItems: "center", - justifyContent: "center", - }, - otherDayHeader: { - backgroundColor: "transparent", - color: "#919191", - aspectRatio: 1, - borderRadius: 100, - alignItems: "center", - justifyContent: "center", - }, - hourStyle: { - color: "#5f6368", - fontSize: 12, - fontFamily: "Manrope_500Medium", - }, + segmentslblStyle: { + fontSize: 12, + fontFamily: "Manrope_600SemiBold", + }, + calHeader: { + borderWidth: 0, + }, + dayModeHeader: { + alignSelf: "flex-start", + justifyContent: "space-between", + alignContent: "center", + width: 38, + right: 42, + height: 13, + }, + weekModeHeader: {}, + monthModeHeader: {}, + loadingContainer: { + flex: 1, + justifyContent: "center", + alignItems: "center", + }, + dayHeader: { + backgroundColor: "#4184f2", + aspectRatio: 1, + borderRadius: 100, + alignItems: "center", + justifyContent: "center", + }, + otherDayHeader: { + backgroundColor: "transparent", + color: "#919191", + aspectRatio: 1, + borderRadius: 100, + alignItems: "center", + justifyContent: "center", + }, + hourStyle: { + color: "#5f6368", + fontSize: 12, + fontFamily: "Manrope_500Medium", + }, }); diff --git a/components/pages/calendar/interfaces.ts b/components/pages/calendar/interfaces.ts index 9c2648e..4e19e7e 100644 --- a/components/pages/calendar/interfaces.ts +++ b/components/pages/calendar/interfaces.ts @@ -10,5 +10,7 @@ export interface CalendarEvent { eventColor?: string; // Optional color to represent the event participants?: string[]; // Optional list of participants or attendees private?: boolean; - notes?: string + notes?: string, + overlapPosition?: number + overlapCount?: number } \ No newline at end of file diff --git a/components/pages/settings/user_settings_views/MyGroup.tsx b/components/pages/settings/user_settings_views/MyGroup.tsx index c0e9055..b03494a 100644 --- a/components/pages/settings/user_settings_views/MyGroup.tsx +++ b/components/pages/settings/user_settings_views/MyGroup.tsx @@ -28,7 +28,7 @@ import CircledXIcon from "@/assets/svgs/CircledXIcon"; import ProfileIcon from "@/assets/svgs/ProfileIcon"; import NavToDosIcon from "@/assets/svgs/NavToDosIcon"; import Ionicons from "@expo/vector-icons/Ionicons"; -import { PreviousNextView } from "react-native-keyboard-manager"; +import KeyboardManager, { PreviousNextView } from "react-native-keyboard-manager"; const MyGroup = () => { const [showAddUserDialog, setShowAddUserDialog] = useState(false); @@ -100,12 +100,17 @@ const MyGroup = () => { } }; + useEffect(() => { + KeyboardManager.setEnableAutoToolbar(true); + },[]) + useEffect(() => { setFirstName(""); setLastName(""); setEmail(""); }, []); + // @ts-ignore return ( diff --git a/firebase/functions/yarn.lock b/firebase/functions/yarn.lock new file mode 100644 index 0000000..c102e08 --- /dev/null +++ b/firebase/functions/yarn.lock @@ -0,0 +1,2353 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.6.1": + version "4.11.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.1.tgz#a547badfc719eb3e5f4b556325e542fbe9d7a18f" + integrity sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q== + +"@eslint/eslintrc@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" + integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.6.0" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@eslint/js@8.57.1": + version "8.57.1" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.1.tgz#de633db3ec2ef6a3c89e2f19038063e8a122e2c2" + integrity sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q== + +"@fastify/busboy@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-3.0.0.tgz#328a4639cdd9282c1d1f56aa84943f153df8839d" + integrity sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w== + +"@firebase/app-check-interop-types@0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.2.tgz#455b6562c7a3de3ef75ea51f72dfec5829ad6997" + integrity sha512-LMs47Vinv2HBMZi49C09dJxp0QT5LwDzFaVGf/+ITHe3BlIhUiLNttkATSXplc89A2lAaeTqjgqVkiRfUGyQiQ== + +"@firebase/app-types@0.9.2": + version "0.9.2" + resolved "https://registry.yarnpkg.com/@firebase/app-types/-/app-types-0.9.2.tgz#8cbcceba784753a7c0066a4809bc22f93adee080" + integrity sha512-oMEZ1TDlBz479lmABwWsWjzHwheQKiAgnuKxE0pz0IXCVx7/rtlkx1fQ6GfgK24WCrxDKMplZrT50Kh04iMbXQ== + +"@firebase/auth-interop-types@0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@firebase/auth-interop-types/-/auth-interop-types-0.2.3.tgz#927f1f2139a680b55fef0bddbff2c982b08587e8" + integrity sha512-Fc9wuJGgxoxQeavybiuwgyi+0rssr76b+nHpj+eGhXFYAdudMWyfBHvFL/I5fEHniUM/UQdFzi9VXJK2iZF7FQ== + +"@firebase/component@0.6.9": + version "0.6.9" + resolved "https://registry.yarnpkg.com/@firebase/component/-/component-0.6.9.tgz#4248cfeab222245ada0d7f78ece95a87574532b4" + integrity sha512-gm8EUEJE/fEac86AvHn8Z/QW8BvR56TBw3hMW0O838J/1mThYQXAIQBgUv75EqlCZfdawpWLrKt1uXvp9ciK3Q== + dependencies: + "@firebase/util" "1.10.0" + tslib "^2.1.0" + +"@firebase/database-compat@^1.0.2": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@firebase/database-compat/-/database-compat-1.0.8.tgz#69ab03d00e27a89f65486896ea219094aa38c27f" + integrity sha512-OpeWZoPE3sGIRPBKYnW9wLad25RaWbGyk7fFQe4xnJQKRzlynWeFBSRRAoLE2Old01WXwskUiucNqUUVlFsceg== + dependencies: + "@firebase/component" "0.6.9" + "@firebase/database" "1.0.8" + "@firebase/database-types" "1.0.5" + "@firebase/logger" "0.4.2" + "@firebase/util" "1.10.0" + tslib "^2.1.0" + +"@firebase/database-types@1.0.5", "@firebase/database-types@^1.0.0": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@firebase/database-types/-/database-types-1.0.5.tgz#2d923f42e3d9911b9eec537ed8b5ecaa0ce95c37" + integrity sha512-fTlqCNwFYyq/C6W7AJ5OCuq5CeZuBEsEwptnVxlNPkWCo5cTTyukzAHRSO/jaQcItz33FfYrrFk1SJofcu2AaQ== + dependencies: + "@firebase/app-types" "0.9.2" + "@firebase/util" "1.10.0" + +"@firebase/database@1.0.8": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@firebase/database/-/database-1.0.8.tgz#01bb0d0cb5653ae6a6641523f6f085b4c1be9c2f" + integrity sha512-dzXALZeBI1U5TXt6619cv0+tgEhJiwlUtQ55WNZY7vGAjv7Q1QioV969iYwt1AQQ0ovHnEW0YW9TiBfefLvErg== + dependencies: + "@firebase/app-check-interop-types" "0.3.2" + "@firebase/auth-interop-types" "0.2.3" + "@firebase/component" "0.6.9" + "@firebase/logger" "0.4.2" + "@firebase/util" "1.10.0" + faye-websocket "0.11.4" + tslib "^2.1.0" + +"@firebase/logger@0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@firebase/logger/-/logger-0.4.2.tgz#74dfcfeedee810deb8a7080d5b7eba56aa16ffa2" + integrity sha512-Q1VuA5M1Gjqrwom6I6NUU4lQXdo9IAQieXlujeHZWvRt1b7qQ0KwBaNAjgxG27jgF9/mUwsNmO8ptBCGVYhB0A== + dependencies: + tslib "^2.1.0" + +"@firebase/util@1.10.0": + version "1.10.0" + resolved "https://registry.yarnpkg.com/@firebase/util/-/util-1.10.0.tgz#9ec8ab54da82bfc31baff0c43cb281998cbeddab" + integrity sha512-xKtx4A668icQqoANRxyDLBLz51TAbDP9KRfpbKGxiCAW346d0BeJe5vN6/hKxxmWwnZ0mautyv39JxviwwQMOQ== + dependencies: + tslib "^2.1.0" + +"@google-cloud/firestore@^7.7.0": + version "7.10.0" + resolved "https://registry.yarnpkg.com/@google-cloud/firestore/-/firestore-7.10.0.tgz#fc434f6da583aba48d5532ce322e8c03af1978f8" + integrity sha512-VFNhdHvfnmqcHHs6YhmSNHHxQqaaD64GwiL0c+e1qz85S8SWZPC2XFRf8p9yHRTF40Kow424s1KBU9f0fdQa+Q== + dependencies: + "@opentelemetry/api" "^1.3.0" + fast-deep-equal "^3.1.1" + functional-red-black-tree "^1.0.1" + google-gax "^4.3.3" + protobufjs "^7.2.6" + +"@google-cloud/paginator@^5.0.0": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@google-cloud/paginator/-/paginator-5.0.2.tgz#86ad773266ce9f3b82955a8f75e22cd012ccc889" + integrity sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg== + dependencies: + arrify "^2.0.0" + extend "^3.0.2" + +"@google-cloud/projectify@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@google-cloud/projectify/-/projectify-4.0.0.tgz#d600e0433daf51b88c1fa95ac7f02e38e80a07be" + integrity sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA== + +"@google-cloud/promisify@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@google-cloud/promisify/-/promisify-4.0.0.tgz#a906e533ebdd0f754dca2509933334ce58b8c8b1" + integrity sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g== + +"@google-cloud/storage@^7.7.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@google-cloud/storage/-/storage-7.13.0.tgz#b59a495861fe7c48f78c1b482b9404f07aa60e66" + integrity sha512-Y0rYdwM5ZPW3jw/T26sMxxfPrVQTKm9vGrZG8PRyGuUmUJ8a2xNuQ9W/NNA1prxqv2i54DSydV8SJqxF2oCVgA== + dependencies: + "@google-cloud/paginator" "^5.0.0" + "@google-cloud/projectify" "^4.0.0" + "@google-cloud/promisify" "^4.0.0" + abort-controller "^3.0.0" + async-retry "^1.3.3" + duplexify "^4.1.3" + fast-xml-parser "^4.4.1" + gaxios "^6.0.2" + google-auth-library "^9.6.3" + html-entities "^2.5.2" + mime "^3.0.0" + p-limit "^3.0.1" + retry-request "^7.0.0" + teeny-request "^9.0.0" + uuid "^8.0.0" + +"@grpc/grpc-js@^1.10.9": + version "1.12.2" + resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.12.2.tgz#97eda82dd49bb9c24eaf6434ea8d7de446e95aac" + integrity sha512-bgxdZmgTrJZX50OjyVwz3+mNEnCTNkh3cIqGPWVNeW9jX6bn1ZkU80uPd+67/ZpIJIjRQ9qaHCjhavyoWYxumg== + dependencies: + "@grpc/proto-loader" "^0.7.13" + "@js-sdsl/ordered-map" "^4.4.2" + +"@grpc/proto-loader@^0.7.13": + version "0.7.13" + resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.7.13.tgz#f6a44b2b7c9f7b609f5748c6eac2d420e37670cf" + integrity sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw== + dependencies: + lodash.camelcase "^4.3.0" + long "^5.0.0" + protobufjs "^7.2.5" + yargs "^17.7.2" + +"@humanwhocodes/config-array@^0.13.0": + version "0.13.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz#fb907624df3256d04b9aa2df50d7aa97ec648748" + integrity sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw== + dependencies: + "@humanwhocodes/object-schema" "^2.0.3" + debug "^4.3.1" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" + integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== + +"@js-sdsl/ordered-map@^4.4.2": + version "4.4.2" + resolved "https://registry.yarnpkg.com/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz#9299f82874bab9e4c7f9c48d865becbfe8d6907c" + integrity sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@opentelemetry/api@^1.3.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.9.0.tgz#d03eba68273dc0f7509e2a3d5cba21eae10379fe" + integrity sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg== + +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== + +"@tootallnate/once@2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" + integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== + +"@types/body-parser@*": + version "1.19.5" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" + integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/caseless@*": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.5.tgz#db9468cb1b1b5a925b8f34822f1669df0c5472f5" + integrity sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg== + +"@types/connect@*": + version "3.4.38" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" + integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== + dependencies: + "@types/node" "*" + +"@types/cors@^2.8.5": + version "2.8.17" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.17.tgz#5d718a5e494a8166f569d986794e49c48b216b2b" + integrity sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA== + dependencies: + "@types/node" "*" + +"@types/express-serve-static-core@*": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-5.0.0.tgz#91f06cda1049e8f17eeab364798ed79c97488a1c" + integrity sha512-AbXMTZGt40T+KON9/Fdxx0B2WK5hsgxcfXJLr5bFpZ7b4JCex2WyQPTEKdXqfHiY5nKKBScZ7yCoO6Pvgxfvnw== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/send" "*" + +"@types/express-serve-static-core@^4.17.33": + version "4.19.6" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz#e01324c2a024ff367d92c66f48553ced0ab50267" + integrity sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/send" "*" + +"@types/express@4.17.3": + version "4.17.3" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.3.tgz#38e4458ce2067873b09a73908df488870c303bd9" + integrity sha512-I8cGRJj3pyOLs/HndoP+25vOqhqWkAZsWMEmq1qXy/b/M3ppufecUwaK2/TVDVxcV61/iSdhykUjQQ2DLSrTdg== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "*" + "@types/serve-static" "*" + +"@types/express@^4.17.17": + version "4.17.21" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" + integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.33" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/http-errors@*": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" + integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== + +"@types/jsonwebtoken@^9.0.2": + version "9.0.7" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.7.tgz#e49b96c2b29356ed462e9708fc73b833014727d2" + integrity sha512-ugo316mmTYBl2g81zDFnZ7cfxlut3o+/EQdaP7J8QN2kY6lJ22hmQYCK5EHcJHbrW+dkCGSCPgbG8JtYj6qSrg== + dependencies: + "@types/node" "*" + +"@types/lodash@^4.14.104": + version "4.17.10" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.10.tgz#64f3edf656af2fe59e7278b73d3e62404144a6e6" + integrity sha512-YpS0zzoduEhuOWjAotS6A5AVCva7X4lVlYLF0FYHAY9sdraBfnatttHItlWeZdGhuEkf+OzMNg2ZYAx8t+52uQ== + +"@types/long@^4.0.0": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" + integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== + +"@types/mime@^1": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" + integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== + +"@types/node@*", "@types/node@>=13.7.0", "@types/node@^22.0.1": + version "22.7.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.5.tgz#cfde981727a7ab3611a481510b473ae54442b92b" + integrity sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ== + dependencies: + undici-types "~6.19.2" + +"@types/qs@*": + version "6.9.16" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.16.tgz#52bba125a07c0482d26747d5d4947a64daf8f794" + integrity sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A== + +"@types/range-parser@*": + version "1.2.7" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" + integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== + +"@types/request@^2.48.8": + version "2.48.12" + resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.12.tgz#0f590f615a10f87da18e9790ac94c29ec4c5ef30" + integrity sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw== + dependencies: + "@types/caseless" "*" + "@types/node" "*" + "@types/tough-cookie" "*" + form-data "^2.5.0" + +"@types/send@*": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" + integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/serve-static@*": + version "1.15.7" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.7.tgz#22174bbd74fb97fe303109738e9b5c2f3064f714" + integrity sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw== + dependencies: + "@types/http-errors" "*" + "@types/node" "*" + "@types/send" "*" + +"@types/tough-cookie@*": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.5.tgz#cb6e2a691b70cb177c6e3ae9c1d2e8b2ea8cd304" + integrity sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA== + +"@typescript-eslint/eslint-plugin@^8.7.0": + version "8.8.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.8.1.tgz#9364b756d4d78bcbdf6fd3e9345e6924c68ad371" + integrity sha512-xfvdgA8AP/vxHgtgU310+WBnLB4uJQ9XdyP17RebG26rLtDrQJV3ZYrcopX91GrHmMoH8bdSwMRh2a//TiJ1jQ== + dependencies: + "@eslint-community/regexpp" "^4.10.0" + "@typescript-eslint/scope-manager" "8.8.1" + "@typescript-eslint/type-utils" "8.8.1" + "@typescript-eslint/utils" "8.8.1" + "@typescript-eslint/visitor-keys" "8.8.1" + graphemer "^1.4.0" + ignore "^5.3.1" + natural-compare "^1.4.0" + ts-api-utils "^1.3.0" + +"@typescript-eslint/scope-manager@8.8.1": + version "8.8.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.8.1.tgz#b4bea1c0785aaebfe3c4ab059edaea1c4977e7ff" + integrity sha512-X4JdU+66Mazev/J0gfXlcC/dV6JI37h+93W9BRYXrSn0hrE64IoWgVkO9MSJgEzoWkxONgaQpICWg8vAN74wlA== + dependencies: + "@typescript-eslint/types" "8.8.1" + "@typescript-eslint/visitor-keys" "8.8.1" + +"@typescript-eslint/type-utils@8.8.1": + version "8.8.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.8.1.tgz#31f59ec46e93a02b409fb4d406a368a59fad306e" + integrity sha512-qSVnpcbLP8CALORf0za+vjLYj1Wp8HSoiI8zYU5tHxRVj30702Z1Yw4cLwfNKhTPWp5+P+k1pjmD5Zd1nhxiZA== + dependencies: + "@typescript-eslint/typescript-estree" "8.8.1" + "@typescript-eslint/utils" "8.8.1" + debug "^4.3.4" + ts-api-utils "^1.3.0" + +"@typescript-eslint/types@8.8.1": + version "8.8.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.8.1.tgz#ebe85e0fa4a8e32a24a56adadf060103bef13bd1" + integrity sha512-WCcTP4SDXzMd23N27u66zTKMuEevH4uzU8C9jf0RO4E04yVHgQgW+r+TeVTNnO1KIfrL8ebgVVYYMMO3+jC55Q== + +"@typescript-eslint/typescript-estree@8.8.1": + version "8.8.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.8.1.tgz#34649f4e28d32ee49152193bc7dedc0e78e5d1ec" + integrity sha512-A5d1R9p+X+1js4JogdNilDuuq+EHZdsH9MjTVxXOdVFfTJXunKJR/v+fNNyO4TnoOn5HqobzfRlc70NC6HTcdg== + dependencies: + "@typescript-eslint/types" "8.8.1" + "@typescript-eslint/visitor-keys" "8.8.1" + debug "^4.3.4" + fast-glob "^3.3.2" + is-glob "^4.0.3" + minimatch "^9.0.4" + semver "^7.6.0" + ts-api-utils "^1.3.0" + +"@typescript-eslint/utils@8.8.1": + version "8.8.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.8.1.tgz#9e29480fbfa264c26946253daa72181f9f053c9d" + integrity sha512-/QkNJDbV0bdL7H7d0/y0qBbV2HTtf0TIyjSDTvvmQEzeVx8jEImEbLuOA4EsvE8gIgqMitns0ifb5uQhMj8d9w== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@typescript-eslint/scope-manager" "8.8.1" + "@typescript-eslint/types" "8.8.1" + "@typescript-eslint/typescript-estree" "8.8.1" + +"@typescript-eslint/visitor-keys@8.8.1": + version "8.8.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.8.1.tgz#0fb1280f381149fc345dfde29f7542ff4e587fc5" + integrity sha512-0/TdC3aeRAsW7MDvYRwEc1Uwm0TIBfzjPFgg60UU2Haj5qsCs9cc3zNgY71edqE3LbWfF/WoZQd3lJoDXFQpag== + dependencies: + "@typescript-eslint/types" "8.8.1" + eslint-visitor-keys "^3.4.3" + +"@ungap/structured-clone@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" + integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== + +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn@^8.9.0: + version "8.12.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" + integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +agent-base@^7.0.2: + version "7.1.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.1.tgz#bdbded7dfb096b751a2a087eeeb9664725b2e317" + integrity sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA== + dependencies: + debug "^4.3.4" + +ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +arrify@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" + integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== + +async-retry@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.3.3.tgz#0e7f36c04d8478e7a58bdbed80cedf977785f280" + integrity sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw== + dependencies: + retry "0.13.1" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-js@^1.3.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +bignumber.js@^9.0.0: + version "9.1.2" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" + integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug== + +body-parser@1.20.3: + version "1.20.3" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" + integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g== + dependencies: + bytes "3.1.2" + content-type "~1.0.5" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.13.0" + raw-body "2.5.2" + type-is "~1.6.18" + unpipe "1.0.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +combined-stream@^1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4, content-type@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.1.tgz#2f73c42142d5d5cf71310a74fc4ae61670e5dbc9" + integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w== + +cors@^2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: + version "4.3.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" + integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== + dependencies: + ms "^2.1.3" + +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +duplexify@^4.0.0, duplexify@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-4.1.3.tgz#a07e1c0d0a2c001158563d32592ba58bddb0236f" + integrity sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA== + dependencies: + end-of-stream "^1.4.1" + inherits "^2.0.3" + readable-stream "^3.1.1" + stream-shift "^1.0.2" + +ecdsa-sig-formatter@1.0.11, ecdsa-sig-formatter@^1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== + dependencies: + safe-buffer "^5.0.1" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +encodeurl@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" + integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== + +end-of-stream@^1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +err-code@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" + integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== + +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +escalade@^3.1.1: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-config-google@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/eslint-config-google/-/eslint-config-google-0.14.0.tgz#4f5f8759ba6e11b424294a219dbfa18c508bcc1a" + integrity sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw== + +eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + +eslint@^8.57.1: + version "8.57.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.1.tgz#7df109654aba7e3bbe5c8eae533c5e461d3c6ca9" + integrity sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.4" + "@eslint/js" "8.57.1" + "@humanwhocodes/config-array" "^0.13.0" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + "@ungap/structured-clone" "^1.2.0" + ajv "^6.12.4" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + strip-ansi "^6.0.1" + text-table "^0.2.0" + +espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== + dependencies: + acorn "^8.9.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + +esquery@^1.4.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" + integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + +expo-server-sdk@^3.11.0: + version "3.11.0" + resolved "https://registry.yarnpkg.com/expo-server-sdk/-/expo-server-sdk-3.11.0.tgz#80bc16e2ec103a1235e856adf0d2ae358f7f5ddc" + integrity sha512-EGH82ZcdAFjKq+6daDE8Xj7BjaSeP1VDvZ3Hmtn/KzEQ3ffqHkauMsgXL2wLEPlvatLq3EsYNcejXRBV54WnFQ== + dependencies: + node-fetch "^2.6.0" + promise-limit "^2.7.0" + promise-retry "^2.0.1" + +express@^4.17.1: + version "4.21.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.21.1.tgz#9dae5dda832f16b4eec941a4e44aa89ec481b281" + integrity sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.3" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.7.1" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~2.0.0" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.3.1" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.3" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.10" + proxy-addr "~2.0.7" + qs "6.13.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.19.0" + serve-static "1.16.2" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +extend@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +farmhash-modern@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/farmhash-modern/-/farmhash-modern-1.1.0.tgz#c36b34ad196290d57b0b482dc89e637d0b59835f" + integrity sha512-6ypT4XfgqJk/F3Yuv4SX26I3doUjt0GTG4a+JgWxXQpxXzTBq8fPUeGHfcYMMDPHJHm3yPOSjaeBwBGAHWXCdA== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +fast-xml-parser@^4.4.1: + version "4.5.0" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz#2882b7d01a6825dfdf909638f2de0256351def37" + integrity sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg== + dependencies: + strnum "^1.0.5" + +fastq@^1.6.0: + version "1.17.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" + integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== + dependencies: + reusify "^1.0.4" + +faye-websocket@0.11.4: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.1.tgz#0c575f1d1d324ddd1da35ad7ece3df7d19088019" + integrity sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ== + dependencies: + debug "2.6.9" + encodeurl "~2.0.0" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +firebase-admin@^12.1.0: + version "12.6.0" + resolved "https://registry.yarnpkg.com/firebase-admin/-/firebase-admin-12.6.0.tgz#495bfa30a4484d1af6390bb3481fdf911bca530e" + integrity sha512-gc0pDiUmxscxBhcjMcttmjvExJmnQdVRb+IIth95CvMm7F9rLdabrQZThW2mK02HR696P+rzd6NqkdUA3URu4w== + dependencies: + "@fastify/busboy" "^3.0.0" + "@firebase/database-compat" "^1.0.2" + "@firebase/database-types" "^1.0.0" + "@types/node" "^22.0.1" + farmhash-modern "^1.1.0" + jsonwebtoken "^9.0.0" + jwks-rsa "^3.1.0" + node-forge "^1.3.1" + uuid "^10.0.0" + optionalDependencies: + "@google-cloud/firestore" "^7.7.0" + "@google-cloud/storage" "^7.7.0" + +firebase-functions-test@^3.1.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/firebase-functions-test/-/firebase-functions-test-3.3.0.tgz#63566f0ea71d9fd0651c756b29a8b50ec5f408d8" + integrity sha512-X+OOA34MGrsTimFXTDnWT0psAqnmBkJ85bGCoLMwjgei5Prfkqh3bv5QASnXC/cmIVBSF2Qw9uW1+mF/t3kFlw== + dependencies: + "@types/lodash" "^4.14.104" + lodash "^4.17.5" + ts-deepmerge "^2.0.1" + +firebase-functions@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/firebase-functions/-/firebase-functions-5.1.1.tgz#15c668d072d4000d6a348aabb7ab4acdbd2442f8" + integrity sha512-KkyKZE98Leg/C73oRyuUYox04PQeeBThdygMfeX+7t1cmKWYKa/ZieYa89U8GHgED+0mF7m7wfNZOfbURYxIKg== + dependencies: + "@types/cors" "^2.8.5" + "@types/express" "4.17.3" + cors "^2.8.5" + express "^4.17.1" + protobufjs "^7.2.2" + +flat-cache@^3.0.4: + version "3.2.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" + integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== + dependencies: + flatted "^3.2.9" + keyv "^4.5.3" + rimraf "^3.0.2" + +flatted@^3.2.9: + version "3.3.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" + integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== + +form-data@^2.5.0: + version "2.5.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.2.tgz#dc653743d1de2fcc340ceea38079daf6e9069fd2" + integrity sha512-GgwY0PS7DbXqajuGf4OYlsrIu3zgxD6Vvql43IBhm6MahqA5SK/7mwhtNj2AdH2z35YR34ujJ7BN+3fFC3jP5Q== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + safe-buffer "^5.2.1" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== + +gaxios@^6.0.0, gaxios@^6.0.2, gaxios@^6.1.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/gaxios/-/gaxios-6.7.1.tgz#ebd9f7093ede3ba502685e73390248bb5b7f71fb" + integrity sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ== + dependencies: + extend "^3.0.2" + https-proxy-agent "^7.0.1" + is-stream "^2.0.0" + node-fetch "^2.6.9" + uuid "^9.0.1" + +gcp-metadata@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/gcp-metadata/-/gcp-metadata-6.1.0.tgz#9b0dd2b2445258e7597f2024332d20611cbd6b8c" + integrity sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg== + dependencies: + gaxios "^6.0.0" + json-bigint "^1.0.0" + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + +glob-parent@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob@^7.1.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^13.19.0: + version "13.24.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" + integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== + dependencies: + type-fest "^0.20.2" + +google-auth-library@^9.3.0, google-auth-library@^9.6.3: + version "9.14.2" + resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-9.14.2.tgz#92a53ba32b3a9ff9ced8ed34129edb5a7fa7fb52" + integrity sha512-R+FRIfk1GBo3RdlRYWPdwk8nmtVUOn6+BkDomAC46KoU8kzXzE1HLmOasSCbWUByMMAGkknVF0G5kQ69Vj7dlA== + dependencies: + base64-js "^1.3.0" + ecdsa-sig-formatter "^1.0.11" + gaxios "^6.1.1" + gcp-metadata "^6.1.0" + gtoken "^7.0.0" + jws "^4.0.0" + +google-gax@^4.3.3: + version "4.4.1" + resolved "https://registry.yarnpkg.com/google-gax/-/google-gax-4.4.1.tgz#95a9cf7ee7777ac22d1926a45b5f886dd8beecae" + integrity sha512-Phyp9fMfA00J3sZbJxbbB4jC55b7DBjE3F6poyL3wKMEBVKA79q6BGuHcTiM28yOzVql0NDbRL8MLLh8Iwk9Dg== + dependencies: + "@grpc/grpc-js" "^1.10.9" + "@grpc/proto-loader" "^0.7.13" + "@types/long" "^4.0.0" + abort-controller "^3.0.0" + duplexify "^4.0.0" + google-auth-library "^9.3.0" + node-fetch "^2.7.0" + object-hash "^3.0.0" + proto3-json-serializer "^2.0.2" + protobufjs "^7.3.2" + retry-request "^7.0.0" + uuid "^9.0.1" + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + +gtoken@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-7.1.0.tgz#d61b4ebd10132222817f7222b1e6064bd463fc26" + integrity sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw== + dependencies: + gaxios "^6.0.0" + jws "^4.0.0" + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + +has-proto@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +hasown@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + +html-entities@^2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.5.2.tgz#201a3cf95d3a15be7099521620d19dfb4f65359f" + integrity sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-parser-js@>=0.5.1: + version "0.5.8" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" + integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== + +http-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== + dependencies: + "@tootallnate/once" "2" + agent-base "6" + debug "4" + +https-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + +https-proxy-agent@^7.0.1: + version "7.0.5" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz#9e8b5013873299e11fab6fd548405da2d6c602b2" + integrity sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw== + dependencies: + agent-base "^7.0.2" + debug "4" + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ignore@^5.2.0, ignore@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" + integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== + +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +jose@^4.14.6: + version "4.15.9" + resolved "https://registry.yarnpkg.com/jose/-/jose-4.15.9.tgz#9b68eda29e9a0614c042fa29387196c7dd800100" + integrity sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA== + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +json-bigint@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-1.0.0.tgz#ae547823ac0cad8398667f8cd9ef4730f5b01ff1" + integrity sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ== + dependencies: + bignumber.js "^9.0.0" + +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +jsonwebtoken@^9.0.0: + version "9.0.2" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3" + integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== + dependencies: + jws "^3.2.2" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + semver "^7.5.4" + +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jwa@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-2.0.0.tgz#a7e9c3f29dae94027ebcaf49975c9345593410fc" + integrity sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jwks-rsa@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/jwks-rsa/-/jwks-rsa-3.1.0.tgz#50406f23e38c9b2682cd437f824d7d61aa983171" + integrity sha512-v7nqlfezb9YfHHzYII3ef2a2j1XnGeSE/bK3WfumaYCqONAIstJbrEGapz4kadScZzEt7zYCN7bucj8C0Mv/Rg== + dependencies: + "@types/express" "^4.17.17" + "@types/jsonwebtoken" "^9.0.2" + debug "^4.3.4" + jose "^4.14.6" + limiter "^1.1.5" + lru-memoizer "^2.2.0" + +jws@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== + dependencies: + jwa "^1.4.1" + safe-buffer "^5.0.1" + +jws@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jws/-/jws-4.0.0.tgz#2d4e8cf6a318ffaa12615e9dec7e86e6c97310f4" + integrity sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg== + dependencies: + jwa "^2.0.0" + safe-buffer "^5.0.1" + +keyv@^4.5.3: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +limiter@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/limiter/-/limiter-1.1.5.tgz#8f92a25b3b16c6131293a0cc834b4a838a2aa7c2" + integrity sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA== + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== + +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== + +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== + +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== + +lodash@^4.17.5: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +long@^5.0.0: + version "5.2.3" + resolved "https://registry.yarnpkg.com/long/-/long-5.2.3.tgz#a3ba97f3877cf1d778eccbcb048525ebb77499e1" + integrity sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q== + +lru-cache@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +lru-memoizer@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lru-memoizer/-/lru-memoizer-2.3.0.tgz#ef0fbc021bceb666794b145eefac6be49dc47f31" + integrity sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug== + dependencies: + lodash.clonedeep "^4.5.0" + lru-cache "6.0.0" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +merge-descriptors@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5" + integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ== + +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micromatch@^4.0.4: + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== + dependencies: + braces "^3.0.3" + picomatch "^2.3.1" + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7" + integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== + +minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.3, ms@^2.1.1, ms@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +node-fetch@^2.6.0, node-fetch@^2.6.9, node-fetch@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== + dependencies: + whatwg-url "^5.0.0" + +node-forge@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + +object-assign@^4: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-hash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" + integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== + +object-inspect@^1.13.1: + version "1.13.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff" + integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +once@^1.3.0, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +optionator@^0.9.3: + version "0.9.4" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734" + integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.5" + +p-limit@^3.0.1, p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-to-regexp@0.1.10: + version "0.1.10" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.10.tgz#67e9108c5c0551b9e5326064387de4763c4d5f8b" + integrity sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w== + +picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +promise-limit@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/promise-limit/-/promise-limit-2.7.0.tgz#eb5737c33342a030eaeaecea9b3d3a93cb592b26" + integrity sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw== + +promise-retry@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" + integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== + dependencies: + err-code "^2.0.2" + retry "^0.12.0" + +proto3-json-serializer@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/proto3-json-serializer/-/proto3-json-serializer-2.0.2.tgz#5b705203b4d58f3880596c95fad64902617529dd" + integrity sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ== + dependencies: + protobufjs "^7.2.5" + +protobufjs@^7.2.2, protobufjs@^7.2.5, protobufjs@^7.2.6, protobufjs@^7.3.2: + version "7.4.0" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.4.0.tgz#7efe324ce9b3b61c82aae5de810d287bc08a248a" + integrity sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/node" ">=13.7.0" + long "^5.0.0" + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +punycode@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + +qs@6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" + integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== + dependencies: + side-channel "^1.0.6" + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +readable-stream@^3.1.1: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +retry-request@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/retry-request/-/retry-request-7.0.2.tgz#60bf48cfb424ec01b03fca6665dee91d06dd95f3" + integrity sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w== + dependencies: + "@types/request" "^2.48.8" + extend "^3.0.2" + teeny-request "^9.0.0" + +retry@0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.2.1, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +semver@^7.5.4, semver@^7.6.0: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + +send@0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8" + integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serve-static@1.16.2: + version "1.16.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.2.tgz#b6a5343da47f6bdd2673848bf45754941e803296" + integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw== + dependencies: + encodeurl "~2.0.0" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.19.0" + +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +stream-events@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/stream-events/-/stream-events-1.0.5.tgz#bbc898ec4df33a4902d892333d47da9bf1c406d5" + integrity sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg== + dependencies: + stubs "^3.0.0" + +stream-shift@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.3.tgz#85b8fab4d71010fc3ba8772e8046cc49b8a3864b" + integrity sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ== + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +strnum@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db" + integrity sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA== + +stubs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/stubs/-/stubs-3.0.0.tgz#e8d2ba1fa9c90570303c030b6900f7d5f89abe5b" + integrity sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw== + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +teeny-request@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/teeny-request/-/teeny-request-9.0.0.tgz#18140de2eb6595771b1b02203312dfad79a4716d" + integrity sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g== + dependencies: + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" + node-fetch "^2.6.9" + stream-events "^1.0.5" + uuid "^9.0.0" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +ts-api-utils@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" + integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== + +ts-deepmerge@^2.0.1: + version "2.0.7" + resolved "https://registry.yarnpkg.com/ts-deepmerge/-/ts-deepmerge-2.0.7.tgz#36786a9a10b5f3a6f5154007cf17bfba7251e0a7" + integrity sha512-3phiGcxPSSR47RBubQxPoZ+pqXsEsozLo4G4AlSrsMKTFg9TA3l+3he5BqpUi9wiuDbaHWXH/amlzQ49uEdXtg== + +tslib@^2.1.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" + integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +undici-types@~6.19.2: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +util-deprecate@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +uuid@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-10.0.0.tgz#5a95aa454e6e002725c79055fd42aaba30ca6294" + integrity sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ== + +uuid@^8.0.0: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +uuid@^9.0.0, uuid@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== + +vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +websocket-driver@>=0.5.1: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +word-wrap@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@^17.7.2: + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/ios/cally.xcodeproj/project.pbxproj b/ios/cally.xcodeproj/project.pbxproj index ef5c283..ca73519 100644 --- a/ios/cally.xcodeproj/project.pbxproj +++ b/ios/cally.xcodeproj/project.pbxproj @@ -450,7 +450,7 @@ ); OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG"; PRODUCT_BUNDLE_IDENTIFIER = com.cally.app; - PRODUCT_NAME = "Cally"; + PRODUCT_NAME = Cally; SWIFT_OBJC_BRIDGING_HEADER = "cally/cally-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -484,7 +484,7 @@ ); OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE"; PRODUCT_BUNDLE_IDENTIFIER = com.cally.app; - PRODUCT_NAME = "Cally"; + PRODUCT_NAME = Cally; SWIFT_OBJC_BRIDGING_HEADER = "cally/cally-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/ios/cally/Info.plist b/ios/cally/Info.plist index 5ea67e0..b5ae381 100644 --- a/ios/cally/Info.plist +++ b/ios/cally/Info.plist @@ -133,6 +133,7 @@ $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route + $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route UILaunchStoryboardName SplashScreen diff --git a/package.json b/package.json index c6e9a7b..c968392 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ "prebuild": "npx expo prebuild -p ios", "prebuild-build-submit-ios": "yarn run prebuild && yarn run build-ios && yarn run submit", "prebuild-build-submit-ios-cicd": "yarn build-ios-cicd", - "prebuild-build-submit-cicd": "yarn build-cicd" + "prebuild-build-submit-cicd": "yarn build-cicd", + "postinstall": "patch-package" }, "jest": { "preset": "jest-expo" @@ -69,11 +70,12 @@ "firebase-functions": "^5.1.0", "fuzzysort": "^3.0.2", "jotai": "^2.9.1", + "patch-package": "^8.0.0", "react": "18.2.0", "react-dom": "18.2.0", "react-native": "0.74.3", "react-native-app-auth": "^8.0.0", - "react-native-big-calendar": "^4.14.0", + "react-native-big-calendar": "^4.15.1", "react-native-calendars": "^1.1306.0", "react-native-element-dropdown": "^2.12.2", "react-native-gesture-handler": "~2.16.1", @@ -102,6 +104,7 @@ "@types/react-test-renderer": "^18.0.7", "jest": "^29.2.1", "jest-expo": "~51.0.3", + "postinstall-postinstall": "^2.1.0", "react-test-renderer": "18.2.0", "typescript": "~5.3.3" }, diff --git a/patches/react-native-big-calendar+4.15.1.patch b/patches/react-native-big-calendar+4.15.1.patch new file mode 100644 index 0000000..9173bde --- /dev/null +++ b/patches/react-native-big-calendar+4.15.1.patch @@ -0,0 +1,186 @@ +diff --git a/node_modules/react-native-big-calendar/build/index.js b/node_modules/react-native-big-calendar/build/index.js +index 848ceba..57fbaed 100644 +--- a/node_modules/react-native-big-calendar/build/index.js ++++ b/node_modules/react-native-big-calendar/build/index.js +@@ -9,6 +9,17 @@ var isoWeek = require('dayjs/plugin/isoWeek'); + var React = require('react'); + var reactNative = require('react-native'); + var calendarize = require('calendarize'); ++var { ++ startOfDay, ++ endOfDay, ++ startOfWeek, ++ isAfter, ++ isBefore, ++ isSameDay, ++ differenceInDays, ++ add, ++ getTime ++} = require('date-fns'); + + function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } + +@@ -1000,87 +1011,91 @@ function _CalendarBodyForMonthView(_a) { + var start = _a.start, end = _a.end; + return day.isBetween(dayjs__default["default"](start).startOf('day'), dayjs__default["default"](end).endOf('day'), null, '[)'); + }); +- } +- else { +- /** +- * Better way to sort overlapping events that spans accross multiple days +- * For example, if you want following events +- * Event 1, start = 01/01 12:00, end = 02/01 12:00 +- * Event 2, start = 02/01 12:00, end = 03/01 12:00 +- * Event 3, start = 03/01 12:00, end = 04/01 12:00 +- * +- * When drawing calendar in month view, event 3 should be placed at 3rd index for 03/01, because Event 2 are placed at 2nd index for 02/01 and 03/01 +- * +- */ +- var min_1 = day.startOf('day'), max_1 = day.endOf('day'); +- //filter all events that starts from the current week until the current day, and sort them by reverse starting time +- var filteredEvents_1 = events +- .filter(function (_a) { +- var start = _a.start, end = _a.end; +- return dayjs__default["default"](end).isAfter(day.startOf('week')) && dayjs__default["default"](start).isBefore(max_1); +- }) +- .sort(function (a, b) { +- if (dayjs__default["default"](a.start).isSame(b.start, 'day')) { +- var aDuration = dayjs__default["default"].duration(dayjs__default["default"](a.end).diff(dayjs__default["default"](a.start))).days(); +- var bDuration = dayjs__default["default"].duration(dayjs__default["default"](b.end).diff(dayjs__default["default"](b.start))).days(); +- return aDuration - bDuration; +- } +- return b.start.getTime() - a.start.getTime(); ++ } else { ++ // Convert day once and cache all the commonly used dates/times ++ const jsDay = day?.toDate?.() || day; ++ const weekStart = startOfWeek(jsDay); ++ var min_1 = startOfDay(jsDay); ++ var max_1 = endOfDay(jsDay); ++ const max1Time = getTime(max_1); ++ const min1Time = getTime(min_1); ++ ++ // Pre-process events with dates and cache timestamps ++ const processedEvents = events.map(event => { ++ const startDay = event.start?.toDate?.() || new Date(event.start); ++ const endDay = event.end?.toDate?.() || new Date(event.end); ++ return { ++ ...event, ++ startDay, ++ endDay, ++ startTime: getTime(startDay), ++ endTime: getTime(endDay), ++ startDayStart: startOfDay(startDay) ++ }; + }); +- /** +- * find the most relevant min date to filter the events +- * in the example: +- * 1. when rendering for 01/01, min date will be 01/01 (start of day for event 1) +- * 2. when rendering for 02/01, min date will be 01/01 (start of day for event 1) +- * 3. when rendering for 03/01, min date will be 01/01 (start of day for event 1) +- * 4. when rendering for 04/01, min date will be 01/01 (start of day for event 1) +- * 5. when rendering for 05/01, min date will be 05/01 (no event overlaps with 05/01) +- */ +- filteredEvents_1.forEach(function (_a) { +- var start = _a.start, end = _a.end; +- if (dayjs__default["default"](end).isAfter(min_1) && dayjs__default["default"](start).isBefore(min_1)) { +- min_1 = dayjs__default["default"](start).startOf('day'); ++ ++ // Filter events within the weekly range and sort by reverse start time ++ let filteredEvents_1 = processedEvents ++ .filter(({ startTime, endTime }) => ++ endTime > getTime(weekStart) && startTime < max1Time ++ ) ++ .sort((a, b) => { ++ if (isSameDay(a.startDay, b.startDay)) { ++ // Pre-calculate durations since they're used in sorting ++ const aDuration = differenceInDays(a.endDay, a.startDay); ++ const bDuration = differenceInDays(b.endDay, b.startDay); ++ return bDuration - aDuration; ++ } ++ return b.startTime - a.startTime; ++ }); ++ ++ // Update min_1 to the earliest startDay for overlapping events ++ for (const event of filteredEvents_1) { ++ if (event.endTime > min1Time && event.startTime < min1Time) { ++ min_1 = event.startDayStart; ++ break; // We only need the first one due to the sort order + } +- }); ++ } ++ ++ // Filter to keep only events that overlap the min to max range, then reverse ++ const min1TimeUpdated = getTime(min_1); + filteredEvents_1 = filteredEvents_1 +- .filter(function (_a) { +- var start = _a.start, end = _a.end; +- return dayjs__default["default"](end).endOf('day').isAfter(min_1) && dayjs__default["default"](start).isBefore(max_1); +- }) ++ .filter(({ startTime, endDay }) => ++ getTime(endOfDay(endDay)) > min1TimeUpdated && startTime < max1Time ++ ) + .reverse(); +- /** +- * We move eligible event to the top +- * For example, when rendering for 03/01, Event 3 should be moved to the top, since there is a gap left by Event 1 +- */ +- var finalEvents_1 = []; +- var tmpDay_1 = day.startOf('week'); +- //re-sort events from the start of week until the calendar cell date +- //optimize sorting of event nodes and make sure that no empty gaps are left on top of calendar cell +- while (!tmpDay_1.isAfter(day)) { +- filteredEvents_1.forEach(function (event) { +- if (dayjs__default["default"](event.end).isBefore(tmpDay_1.startOf('day'))) { +- var eventToMoveUp = filteredEvents_1.find(function (e) { +- return dayjs__default["default"](e.start).startOf('day').isSame(tmpDay_1.startOf('day')); +- }); +- if (eventToMoveUp != undefined) { +- //remove eventToMoveUp from finalEvents first +- if (finalEvents_1.indexOf(eventToMoveUp) > -1) { +- finalEvents_1.splice(finalEvents_1.indexOf(eventToMoveUp), 1); +- } +- if (finalEvents_1.indexOf(event) > -1) { +- finalEvents_1.splice(finalEvents_1.indexOf(event), 1, eventToMoveUp); +- } +- else { ++ ++ // Move eligible events to the top, preventing duplicate entries ++ const finalEvents_1 = []; ++ const seenEvents = new Set(); // Use Set for faster lookups ++ let tmpDay_1 = weekStart; ++ ++ while (!isAfter(tmpDay_1, jsDay)) { ++ const tmpDayTime = getTime(tmpDay_1); ++ ++ for (const event of filteredEvents_1) { ++ const eventEndDayTime = getTime(startOfDay(event.endDay)); ++ ++ if (!seenEvents.has(event)) { ++ if (eventEndDayTime < tmpDayTime) { ++ // Find event starting on tmpDay ++ const eventToMoveUp = filteredEvents_1.find(e => ++ isSameDay(e.startDayStart, tmpDay_1) ++ ); ++ if (eventToMoveUp && !seenEvents.has(eventToMoveUp)) { + finalEvents_1.push(eventToMoveUp); ++ seenEvents.add(eventToMoveUp); + } ++ } else { ++ finalEvents_1.push(event); ++ seenEvents.add(event); + } + } +- else if (finalEvents_1.indexOf(event) == -1) { +- finalEvents_1.push(event); +- } +- }); +- tmpDay_1 = tmpDay_1.add(1, 'day'); ++ } ++ tmpDay_1 = add(tmpDay_1, { days: 1 }); + } ++ ++ console.log(finalEvents_1); + return finalEvents_1; + } + }, [events, sortedMonthView]); diff --git a/yarn.lock b/yarn.lock index 0746292..7b6e5e2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3183,6 +3183,11 @@ resolved "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.13.tgz" integrity sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g== +"@yarnpkg/lockfile@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" + integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== + "@zxing/text-encoding@0.9.0": version "0.9.0" resolved "https://registry.npmjs.org/@zxing/text-encoding/-/text-encoding-0.9.0.tgz" @@ -3982,7 +3987,7 @@ ci-info@^2.0.0: resolved "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== -ci-info@^3.2.0, ci-info@^3.3.0: +ci-info@^3.2.0, ci-info@^3.3.0, ci-info@^3.7.0: version "3.9.0" resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz" integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== @@ -4456,7 +4461,7 @@ date-fns@^3.6.0: resolved "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz" integrity sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww== -dayjs@^1.11.10, dayjs@^1.8.15: +dayjs@^1.11.13, dayjs@^1.8.15: version "1.11.13" resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz" integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg== @@ -5543,7 +5548,7 @@ find-up@^5.0.0, find-up@~5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" -find-yarn-workspace-root@~2.0.0: +find-yarn-workspace-root@^2.0.0, find-yarn-workspace-root@~2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz" integrity sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ== @@ -7215,6 +7220,16 @@ json-schema-traverse@^1.0.0: resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== +json-stable-stringify@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.1.1.tgz#52d4361b47d49168bcc4e564189a42e5a7439454" + integrity sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg== + dependencies: + call-bind "^1.0.5" + isarray "^2.0.5" + jsonify "^0.0.1" + object-keys "^1.1.1" + json5@^1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz" @@ -7243,6 +7258,11 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" +jsonify@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.1.tgz#2aa3111dae3d34a0f151c63f3a45d995d9420978" + integrity sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg== + jsonwebtoken@^9.0.0: version "9.0.2" resolved "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz" @@ -7315,6 +7335,13 @@ kind-of@^6.0.0, kind-of@^6.0.1, kind-of@^6.0.2: resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== +klaw-sync@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/klaw-sync/-/klaw-sync-6.0.0.tgz#1fd2cfd56ebb6250181114f0a581167099c2b28c" + integrity sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ== + dependencies: + graceful-fs "^4.1.11" + kleur@^3.0.3: version "3.0.3" resolved "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz" @@ -8260,7 +8287,7 @@ open@^6.2.0: dependencies: is-wsl "^1.1.0" -open@^7.0.3: +open@^7.0.3, open@^7.4.2: version "7.4.2" resolved "https://registry.npmjs.org/open/-/open-7.4.2.tgz" integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== @@ -8434,6 +8461,27 @@ password-prompt@^1.0.4: ansi-escapes "^4.3.2" cross-spawn "^7.0.3" +patch-package@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-8.0.0.tgz#d191e2f1b6e06a4624a0116bcb88edd6714ede61" + integrity sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA== + dependencies: + "@yarnpkg/lockfile" "^1.1.0" + chalk "^4.1.2" + ci-info "^3.7.0" + cross-spawn "^7.0.3" + find-yarn-workspace-root "^2.0.0" + fs-extra "^9.0.0" + json-stable-stringify "^1.0.2" + klaw-sync "^6.0.0" + minimist "^1.2.6" + open "^7.4.2" + rimraf "^2.6.3" + semver "^7.5.3" + slash "^2.0.0" + tmp "^0.0.33" + yaml "^2.2.2" + path-exists@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" @@ -8559,6 +8607,11 @@ postcss@~8.4.32: picocolors "^1.0.1" source-map-js "^1.2.0" +postinstall-postinstall@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz#4f7f77441ef539d1512c40bd04c71b06a4704ca3" + integrity sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ== + pretty-bytes@5.6.0: version "5.6.0" resolved "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz" @@ -8827,13 +8880,13 @@ react-native-base64@0.0.2: resolved "https://registry.npmjs.org/react-native-base64/-/react-native-base64-0.0.2.tgz" integrity sha512-Fu/J1a2y0X22EJDWqJR2oEa1fpP4gTFjYxk8ElJdt1Yak3HOXmFJ7EohLVHU2DaQkgmKfw8qb7u/48gpzveRbg== -react-native-big-calendar@^4.14.0: - version "4.14.0" - resolved "https://registry.npmjs.org/react-native-big-calendar/-/react-native-big-calendar-4.14.0.tgz" - integrity sha512-EYCxqXnRAg8QWsW3Npq3JI/9+lXlo9o6Gri7WttQQSqE/cGkVrVeKXObpvN6Cc4qrIUvnc4cgLAeM/j4+bOb6g== +react-native-big-calendar@^4.15.1: + version "4.15.1" + resolved "https://registry.yarnpkg.com/react-native-big-calendar/-/react-native-big-calendar-4.15.1.tgz#9cfef290e40a51cbc59b1be4d065804b21f2f74f" + integrity sha512-hNrzkM+9Kb2T0J/1fW9AMaeN+AuhakCfNtQPaQL29l3JXgOO14ikJ3iPqQkmNVbuiWYiMrpI25hrmXffiOVIgQ== dependencies: calendarize "^1.1.1" - dayjs "^1.11.10" + dayjs "^1.11.13" react-native-calendars@^1.1306.0: version "1.1306.0" @@ -9303,6 +9356,13 @@ rimraf@3.0.2, rimraf@^3.0.2: dependencies: glob "^7.1.3" +rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + rimraf@~2.6.2: version "2.6.3" resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz" @@ -9606,6 +9666,11 @@ sisteransi@^1.0.5: resolved "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz" integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + slash@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" @@ -10931,6 +10996,11 @@ yaml@^2.2.1: resolved "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz" integrity sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw== +yaml@^2.2.2: + version "2.6.0" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.6.0.tgz#14059ad9d0b1680d0f04d3a60fe00f3a857303c3" + integrity sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ== + yargs-parser@^18.1.2: version "18.1.3" resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz" From fff113de655a5378327b16dc4d415d0a7163debf Mon Sep 17 00:00:00 2001 From: Milan Paunovic Date: Thu, 31 Oct 2024 02:44:47 +0100 Subject: [PATCH 50/66] Build nr updt --- app.json | 2 +- ios/cally.xcodeproj/project.pbxproj | 4 ++-- ios/cally/Info.plist | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app.json b/app.json index be7d2dc..82d789f 100644 --- a/app.json +++ b/app.json @@ -16,7 +16,7 @@ "supportsTablet": true, "bundleIdentifier": "com.cally.app", "googleServicesFile": "./ios/GoogleService-Info.plist", - "buildNumber": "53", + "buildNumber": "55", "usesAppleSignIn": true }, "android": { diff --git a/ios/cally.xcodeproj/project.pbxproj b/ios/cally.xcodeproj/project.pbxproj index ca73519..ef5c283 100644 --- a/ios/cally.xcodeproj/project.pbxproj +++ b/ios/cally.xcodeproj/project.pbxproj @@ -450,7 +450,7 @@ ); OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG"; PRODUCT_BUNDLE_IDENTIFIER = com.cally.app; - PRODUCT_NAME = Cally; + PRODUCT_NAME = "Cally"; SWIFT_OBJC_BRIDGING_HEADER = "cally/cally-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -484,7 +484,7 @@ ); OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE"; PRODUCT_BUNDLE_IDENTIFIER = com.cally.app; - PRODUCT_NAME = Cally; + PRODUCT_NAME = "Cally"; SWIFT_OBJC_BRIDGING_HEADER = "cally/cally-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/ios/cally/Info.plist b/ios/cally/Info.plist index b5ae381..baf1726 100644 --- a/ios/cally/Info.plist +++ b/ios/cally/Info.plist @@ -47,7 +47,7 @@ CFBundleVersion - 53 + 55 LSRequiresIPhoneOS NSAppTransportSecurity @@ -134,6 +134,7 @@ $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route + $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route UILaunchStoryboardName SplashScreen From 1b6a241bbe8955d1dbe775f62558a5779cb3fa5d Mon Sep 17 00:00:00 2001 From: Milan Paunovic Date: Thu, 31 Oct 2024 12:01:01 +0100 Subject: [PATCH 51/66] Add event deletion --- .../pages/calendar/ManuallyAddEventModal.tsx | 1246 +++++++++-------- hooks/firebase/useDeleteEvent.ts | 39 + 2 files changed, 670 insertions(+), 615 deletions(-) create mode 100644 hooks/firebase/useDeleteEvent.ts diff --git a/components/pages/calendar/ManuallyAddEventModal.tsx b/components/pages/calendar/ManuallyAddEventModal.tsx index 326f4e2..70795ed 100644 --- a/components/pages/calendar/ManuallyAddEventModal.tsx +++ b/components/pages/calendar/ManuallyAddEventModal.tsx @@ -1,647 +1,663 @@ import { - Button, - ButtonSize, - Colors, - DateTimePicker, - LoaderScreen, - Modal, - Picker, - PickerModes, - Switch, - Text, - TextField, - TextFieldRef, - TouchableOpacity, - View, + Button, + ButtonSize, + Colors, + DateTimePicker, + LoaderScreen, + Modal, + Picker, + PickerModes, + Switch, + Text, + TextField, + TextFieldRef, + TouchableOpacity, + View, } from "react-native-ui-lib"; -import { ScrollView } from "react-native-gesture-handler"; -import { useSafeAreaInsets } from "react-native-safe-area-context"; -import { useEffect, useRef, useState } from "react"; -import { AntDesign, Feather, Ionicons } from "@expo/vector-icons"; -import { PickerMultiValue } from "react-native-ui-lib/src/components/picker/types"; -import { useCreateEvent } from "@/hooks/firebase/useCreateEvent"; -import { EventData } from "@/hooks/firebase/types/eventData"; -import { addHours } from "date-fns"; +import {ScrollView} from "react-native-gesture-handler"; +import {useSafeAreaInsets} from "react-native-safe-area-context"; +import {useEffect, useRef, useState} from "react"; +import {AntDesign, Feather, Ionicons} from "@expo/vector-icons"; +import {PickerMultiValue} from "react-native-ui-lib/src/components/picker/types"; +import {useCreateEvent} from "@/hooks/firebase/useCreateEvent"; +import {EventData} from "@/hooks/firebase/types/eventData"; +import {addHours} from "date-fns"; import DropModalIcon from "@/assets/svgs/DropModalIcon"; -import { StyleSheet } from "react-native"; +import {StyleSheet} from "react-native"; import ClockIcon from "@/assets/svgs/ClockIcon"; import LockIcon from "@/assets/svgs/LockIcon"; import MenuIcon from "@/assets/svgs/MenuIcon"; import CameraIcon from "@/assets/svgs/CameraIcon"; import AssigneesDisplay from "@/components/shared/AssigneesDisplay"; -import { useAtom } from "jotai"; -import { - eventForEditAtom, - selectedNewEventDateAtom, -} from "@/components/pages/calendar/atoms"; -import { useGetFamilyMembers } from "@/hooks/firebase/useGetFamilyMembers"; +import {useAtom} from "jotai"; +import {eventForEditAtom, selectedNewEventDateAtom,} from "@/components/pages/calendar/atoms"; +import {useGetFamilyMembers} from "@/hooks/firebase/useGetFamilyMembers"; import BinIcon from "@/assets/svgs/BinIcon"; -import CloseXIcon from "@/assets/svgs/CloseXIcon"; -import PenIcon from "@/assets/svgs/PenIcon"; import DeleteEventDialog from "./DeleteEventDialog"; +import {useDeleteEvent} from "@/hooks/firebase/useDeleteEvent"; const daysOfWeek = [ - { label: "Monday", value: "monday" }, - { label: "Tuesday", value: "tuesday" }, - { label: "Wednesday", value: "wednesday" }, - { label: "Thursday", value: "thursday" }, - { label: "Friday", value: "friday" }, - { label: "Saturday", value: "saturday" }, - { label: "Sunday", value: "sunday" }, + {label: "Monday", value: "monday"}, + {label: "Tuesday", value: "tuesday"}, + {label: "Wednesday", value: "wednesday"}, + {label: "Thursday", value: "thursday"}, + {label: "Friday", value: "friday"}, + {label: "Saturday", value: "saturday"}, + {label: "Sunday", value: "sunday"}, ]; export const ManuallyAddEventModal = () => { - const insets = useSafeAreaInsets(); + const insets = useSafeAreaInsets(); - const [selectedNewEventDate, setSelectedNewEndDate] = useAtom( - selectedNewEventDateAtom - ); - const [editEvent, setEditEvent] = useAtom(eventForEditAtom); - const [deleteModalVisible, setDeleteModalVisible] = useState(false); + const [selectedNewEventDate, setSelectedNewEndDate] = useAtom( + selectedNewEventDateAtom + ); + const [editEvent, setEditEvent] = useAtom(eventForEditAtom); + const [deleteModalVisible, setDeleteModalVisible] = useState(false); + const {mutateAsync: deleteEvent, isLoading: isDeleting} = useDeleteEvent() - const showDeleteEventModal = () => { - setDeleteModalVisible(true); - }; - - const handleDeleteEvent = () => {}; - - const hideDeleteEventModal = () => { - setDeleteModalVisible(false); - }; - - const { show, close, initialDate } = { - show: !!selectedNewEventDate || !!editEvent, - close: () => { - setSelectedNewEndDate(undefined); - setEditEvent(undefined); - }, - initialDate: selectedNewEventDate || editEvent?.start, - }; - - const detailsRef = useRef(null); - - const [title, setTitle] = useState(editEvent?.title || ""); - const [details, setDetails] = useState(editEvent?.notes || ""); - const [isAllDay, setIsAllDay] = useState(editEvent?.allDay || false); - const [isPrivate, setIsPrivate] = useState( - editEvent?.private || false - ); - const [startTime, setStartTime] = useState(() => { - const date = initialDate ?? new Date(); - date.setSeconds(0, 0); - return date; - }); - const [endTime, setEndTime] = useState(() => { - if (editEvent?.end) { - const date = new Date(editEvent.end); - date.setSeconds(0, 0); - return date; - } - const date = - editEvent?.end ?? initialDate - ? addHours(editEvent?.end ?? initialDate!, 1) - : addHours(new Date(), 1); - date.setSeconds(0, 0); - return date; - }); - const [startDate, setStartDate] = useState(initialDate ?? new Date()); - const [endDate, setEndDate] = useState( - editEvent?.end ?? initialDate ?? new Date() - ); - const [selectedAttendees, setSelectedAttendees] = useState( - editEvent?.participants ?? [] - ); - const [repeatInterval, setRepeatInterval] = useState([]); - - const { mutateAsync: createEvent, isLoading, isError } = useCreateEvent(); - const { data: members } = useGetFamilyMembers(true); - - useEffect(() => { - setTitle(editEvent?.title || ""); - setDetails(editEvent?.notes || ""); - setIsAllDay(editEvent?.allDay || false); - setIsPrivate(editEvent?.private || false); - setStartTime(() => { - const date = initialDate ?? new Date(); - date.setSeconds(0, 0); - return date; - }); - setEndTime(() => { - if (editEvent?.end) { - const date = new Date(editEvent.end); - date.setSeconds(0, 0); - return date; - } - const date = - editEvent?.end ?? initialDate - ? addHours(editEvent?.end ?? initialDate!, 1) - : addHours(new Date(), 1); - date.setSeconds(0, 0); - return date; - }); - setStartDate(initialDate ?? new Date()); - setEndDate(editEvent?.end ?? initialDate ?? new Date()); - setSelectedAttendees(editEvent?.participants ?? []); - setRepeatInterval([]); - }, [editEvent, selectedNewEventDate]); - - if (!show) return null; - - const formatDateTime = (date?: Date | string) => { - if (!date) return undefined; - return new Date(date).toLocaleDateString("en-US", { - weekday: "long", - month: "short", - day: "numeric", - }); - }; - - const combineDateAndTime = (date: Date, time: Date): Date => { - const combined = new Date(date); - combined.setHours(time.getHours()); - combined.setMinutes(time.getMinutes()); - combined.setSeconds(0); - combined.setMilliseconds(0); - return combined; - }; - - const handleSave = async () => { - let finalStartDate: Date; - let finalEndDate: Date; - - if (isAllDay) { - finalStartDate = new Date(startDate.setHours(0, 0, 0, 0)); - finalEndDate = new Date(startDate.setHours(0, 0, 0, 0)); - } else { - finalStartDate = combineDateAndTime(startDate, startTime); - finalEndDate = combineDateAndTime(endDate, endTime); - } - - const eventData: Partial = { - title: title, - startDate: finalStartDate, - endDate: finalEndDate, - allDay: isAllDay, - attendees: selectedAttendees, - notes: details, + const {show, close, initialDate} = { + show: !!selectedNewEventDate || !!editEvent, + close: () => { + setDeleteModalVisible(false); + setSelectedNewEndDate(undefined); + setEditEvent(undefined); + }, + initialDate: selectedNewEventDate || editEvent?.start, }; - if (editEvent?.id) eventData.id = editEvent?.id; + const detailsRef = useRef(null); - await createEvent(eventData); - setEditEvent(undefined); - - close(); - }; - - const getRepeatLabel = () => { - const selectedDays = repeatInterval; - const allDays = [ - "sunday", - "monday", - "tuesday", - "wednesday", - "thursday", - "friday", - "saturday", - ]; - const workDays = ["monday", "tuesday", "wednesday", "thursday", "friday"]; - - const isEveryWorkDay = workDays.every((day) => selectedDays.includes(day)); - - const isEveryDay = allDays.every((day) => selectedDays.includes(day)); - - if (isEveryDay) { - return "Every day"; - } else if ( - isEveryWorkDay && - !selectedDays.includes("saturday") && - !selectedDays.includes("sunday") - ) { - return "Every work day"; - } else { - return selectedDays - .map((item) => daysOfWeek.find((day) => day.value === item)?.label) - .join(", "); - } - }; - - if (isLoading && !isError) { - return ( - - - + const [title, setTitle] = useState(editEvent?.title || ""); + const [details, setDetails] = useState(editEvent?.notes || ""); + const [isAllDay, setIsAllDay] = useState(editEvent?.allDay || false); + const [isPrivate, setIsPrivate] = useState( + editEvent?.private || false ); - } + const [startTime, setStartTime] = useState(() => { + const date = initialDate ?? new Date(); + date.setSeconds(0, 0); + return date; + }); + const [endTime, setEndTime] = useState(() => { + if (editEvent?.end) { + const date = new Date(editEvent.end); + date.setSeconds(0, 0); + return date; + } + const date = + editEvent?.end ?? initialDate + ? addHours(editEvent?.end ?? initialDate!, 1) + : addHours(new Date(), 1); + date.setSeconds(0, 0); + return date; + }); + const [startDate, setStartDate] = useState(initialDate ?? new Date()); + const [endDate, setEndDate] = useState( + editEvent?.end ?? initialDate ?? new Date() + ); + const [selectedAttendees, setSelectedAttendees] = useState( + editEvent?.participants ?? [] + ); + const [repeatInterval, setRepeatInterval] = useState([]); - return ( - - - {editEvent ? ( - <> - - - - - - - - - ); + {/* Camera Dialog */} + setShowCameraDialog(false)} + bottom + width="100%" + height="70%" + containerStyle={{padding: 15, backgroundColor: "white"}} + > + {hasPermission === null ? ( + Requesting camera permissions... + ) : !hasPermission ? ( + No access to camera + ) : ( + + )} + + + ); }; const styles = StyleSheet.create({ - textfield: { - backgroundColor: "white", - marginVertical: 10, - padding: 30, - height: 45, - borderRadius: 50, - fontFamily: "PlusJakartaSans_300Light", - }, - jakartaLight: { - fontFamily: "PlusJakartaSans_300Light", - fontSize: 16, - color: "#484848", - }, - jakartaMedium: { - fontFamily: "PlusJakartaSans_500Medium", - fontSize: 16, - color: "#919191", - textDecorationLine: "underline", - }, + textfield: { + backgroundColor: "white", + marginVertical: 10, + padding: 30, + height: 45, + borderRadius: 50, + fontFamily: "PlusJakartaSans_300Light", + }, + jakartaLight: { + fontFamily: "PlusJakartaSans_300Light", + fontSize: 16, + color: "#484848", + }, + jakartaMedium: { + fontFamily: "PlusJakartaSans_500Medium", + fontSize: 16, + color: "#919191", + textDecorationLine: "underline", + }, }); export default SignInPage; diff --git a/components/pages/settings/CalendarSettingsPage.tsx b/components/pages/settings/CalendarSettingsPage.tsx index 809d877..8b12d7f 100644 --- a/components/pages/settings/CalendarSettingsPage.tsx +++ b/components/pages/settings/CalendarSettingsPage.tsx @@ -1,10 +1,10 @@ -import { AntDesign, Ionicons } from "@expo/vector-icons"; -import React, { useCallback, useEffect, useState } from "react"; -import { Button, Checkbox, Text, View } from "react-native-ui-lib"; -import { ActivityIndicator, Alert, ScrollView, StyleSheet } from "react-native"; -import { TouchableOpacity } from "react-native-gesture-handler"; -import { useAuthContext } from "@/contexts/AuthContext"; -import { useUpdateUserData } from "@/hooks/firebase/useUpdateUserData"; +import {AntDesign, Ionicons} from "@expo/vector-icons"; +import React, {useCallback, useEffect, useState} from "react"; +import {Button, Checkbox, Text, View} from "react-native-ui-lib"; +import {ActivityIndicator, ScrollView, StyleSheet} from "react-native"; +import {TouchableOpacity} from "react-native-gesture-handler"; +import {useAuthContext} from "@/contexts/AuthContext"; +import {useUpdateUserData} from "@/hooks/firebase/useUpdateUserData"; import debounce from "debounce"; import AppleIcon from "@/assets/svgs/AppleIcon"; import GoogleIcon from "@/assets/svgs/GoogleIcon"; @@ -12,840 +12,830 @@ import OutlookIcon from "@/assets/svgs/OutlookIcon"; import * as AuthSession from "expo-auth-session"; import * as Google from "expo-auth-session/providers/google"; import * as WebBrowser from "expo-web-browser"; -import { UserProfile } from "@firebase/auth"; -import { useFetchAndSaveGoogleEvents } from "@/hooks/useFetchAndSaveGoogleEvents"; -import { useFetchAndSaveOutlookEvents } from "@/hooks/useFetchAndSaveOutlookEvents"; -import { useFetchAndSaveAppleEvents } from "@/hooks/useFetchAndSaveAppleEvents"; +import {useFetchAndSaveGoogleEvents} from "@/hooks/useFetchAndSaveGoogleEvents"; +import {useFetchAndSaveOutlookEvents} from "@/hooks/useFetchAndSaveOutlookEvents"; +import {useFetchAndSaveAppleEvents} from "@/hooks/useFetchAndSaveAppleEvents"; import * as AppleAuthentication from "expo-apple-authentication"; import ExpoLocalization from "expo-localization/src/ExpoLocalization"; -import { colorMap } from "@/constants/colorMap"; -import { useAtom } from "jotai"; -import { settingsPageIndex } from "../calendar/atoms"; +import {colorMap} from "@/constants/colorMap"; +import {useAtom} from "jotai"; +import {settingsPageIndex} from "../calendar/atoms"; import CalendarSettingsDialog from "./calendar_components/CalendarSettingsDialog"; +import {useClearTokens} from "@/hooks/firebase/useClearTokens"; const googleConfig = { - androidClientId: - "406146460310-2u67ab2nbhu23trp8auho1fq4om29fc0.apps.googleusercontent.com", - iosClientId: - "406146460310-2u67ab2nbhu23trp8auho1fq4om29fc0.apps.googleusercontent.com", - webClientId: - "406146460310-2u67ab2nbhu23trp8auho1fq4om29fc0.apps.googleusercontent.com", - scopes: [ - "email", - "profile", - "https://www.googleapis.com/auth/calendar.events.owned", - ], + androidClientId: + "406146460310-2u67ab2nbhu23trp8auho1fq4om29fc0.apps.googleusercontent.com", + iosClientId: + "406146460310-2u67ab2nbhu23trp8auho1fq4om29fc0.apps.googleusercontent.com", + webClientId: + "406146460310-2u67ab2nbhu23trp8auho1fq4om29fc0.apps.googleusercontent.com", + scopes: [ + "email", + "profile", + "https://www.googleapis.com/auth/calendar.events.owned", + ], + extraParams: { + access_type: "offline", + }, }; const microsoftConfig = { - clientId: "13c79071-1066-40a9-9f71-b8c4b138b4af", - redirectUri: AuthSession.makeRedirectUri({ path: "settings" }), - scopes: [ - "openid", - "profile", - "email", - "offline_access", - "Calendars.ReadWrite", - "User.Read", - ], - authorizationEndpoint: - "https://login.microsoftonline.com/common/oauth2/v2.0/authorize", - tokenEndpoint: "https://login.microsoftonline.com/common/oauth2/v2.0/token", + clientId: "13c79071-1066-40a9-9f71-b8c4b138b4af", + redirectUri: AuthSession.makeRedirectUri({path: "settings"}), + scopes: [ + "openid", + "profile", + "email", + "offline_access", + "Calendars.ReadWrite", + "User.Read", + ], + authorizationEndpoint: + "https://login.microsoftonline.com/common/oauth2/v2.0/authorize", + tokenEndpoint: "https://login.microsoftonline.com/common/oauth2/v2.0/token", }; const CalendarSettingsPage = () => { - const { profileData } = useAuthContext(); - const [pageIndex, setPageIndex] = useAtom(settingsPageIndex); - const [firstDayOfWeek, setFirstDayOfWeek] = useState( - profileData?.firstDayOfWeek ?? - ExpoLocalization.getCalendars()[0].firstWeekday === 1 - ? "Mondays" - : "Sundays" - ); - const [isModalVisible, setModalVisible] = useState(false); - const [selectedService, setSelectedService] = useState< - "google" | "outlook" | "apple" - >("google"); - const [selectedEmail, setSelectedEmail] = useState(""); + const {profileData} = useAuthContext(); + const [pageIndex, setPageIndex] = useAtom(settingsPageIndex); + const [firstDayOfWeek, setFirstDayOfWeek] = useState( + profileData?.firstDayOfWeek ?? + ExpoLocalization.getCalendars()[0].firstWeekday === 1 + ? "Mondays" + : "Sundays" + ); + const [isModalVisible, setModalVisible] = useState(false); + const [selectedService, setSelectedService] = useState< + "google" | "outlook" | "apple" + >("google"); + const [selectedEmail, setSelectedEmail] = useState(""); - const showConfirmationDialog = ( - serviceName: "google" | "outlook" | "apple", - email: string - ) => { - setSelectedService(serviceName); - setSelectedEmail(email); - setModalVisible(true); - }; + const showConfirmationDialog = ( + serviceName: "google" | "outlook" | "apple", + email: string + ) => { + setSelectedService(serviceName); + setSelectedEmail(email); + setModalVisible(true); + }; - const handleConfirm = () => { - clearToken(selectedService, selectedEmail); - setModalVisible(false); - }; + const handleConfirm = () => { + clearToken(selectedService, selectedEmail); + setModalVisible(false); + }; - const handleCancel = () => { - setModalVisible(false); - }; + const handleCancel = () => { + setModalVisible(false); + }; - const [selectedColor, setSelectedColor] = useState( - profileData?.eventColor ?? colorMap.pink - ); - const [previousSelectedColor, setPreviousSelectedColor] = useState( - profileData?.eventColor ?? colorMap.pink - ); + const [selectedColor, setSelectedColor] = useState( + profileData?.eventColor ?? colorMap.pink + ); + const [previousSelectedColor, setPreviousSelectedColor] = useState( + profileData?.eventColor ?? colorMap.pink + ); - const { mutateAsync: updateUserData } = useUpdateUserData(); - const { mutateAsync: fetchAndSaveGoogleEvents, isLoading: isSyncingGoogle } = - useFetchAndSaveGoogleEvents(); - const { - mutateAsync: fetchAndSaveOutlookEvents, - isLoading: isSyncingOutlook, - } = useFetchAndSaveOutlookEvents(); - const { mutateAsync: fetchAndSaveAppleEvents, isLoading: isSyncingApple } = - useFetchAndSaveAppleEvents(); + const {mutateAsync: updateUserData} = useUpdateUserData(); + const {mutateAsync: clearToken} = useClearTokens(); + const {mutateAsync: fetchAndSaveGoogleEvents, isLoading: isSyncingGoogle} = + useFetchAndSaveGoogleEvents(); + const { + mutateAsync: fetchAndSaveOutlookEvents, + isLoading: isSyncingOutlook, + } = useFetchAndSaveOutlookEvents(); + const {mutateAsync: fetchAndSaveAppleEvents, isLoading: isSyncingApple} = + useFetchAndSaveAppleEvents(); - WebBrowser.maybeCompleteAuthSession(); - const [_, response, promptAsync] = Google.useAuthRequest(googleConfig); + WebBrowser.maybeCompleteAuthSession(); + const [_, response, promptAsync] = Google.useAuthRequest(googleConfig); - useEffect(() => { - signInWithGoogle(); - }, [response]); + useEffect(() => { + signInWithGoogle(); + }, [response]); - const signInWithGoogle = async () => { - try { - if (response?.type === "success") { - const accessToken = response.authentication?.accessToken; + const signInWithGoogle = async () => { + try { + if (response?.type === "success") { + const { accessToken, refreshToken } = response?.authentication!; - const userInfoResponse = await fetch( - "https://www.googleapis.com/oauth2/v3/userinfo", - { - headers: { Authorization: `Bearer ${accessToken}` }, - } - ); + const userInfoResponse = await fetch( + "https://www.googleapis.com/oauth2/v3/userinfo", + { + headers: { Authorization: `Bearer ${accessToken}` }, + } + ); - const userInfo = await userInfoResponse.json(); - const googleMail = userInfo.email; + const userInfo = await userInfoResponse.json(); + const googleMail = userInfo.email; - let googleAccounts = profileData?.googleAccounts; - const updatedGoogleAccounts = googleAccounts - ? { ...googleAccounts, [googleMail]: accessToken } - : { [googleMail]: accessToken }; + let googleAccounts = profileData?.googleAccounts || {}; + const updatedGoogleAccounts = { + ...googleAccounts, + [googleMail]: { accessToken, refreshToken }, + }; - await updateUserData({ - newUserData: { googleAccounts: updatedGoogleAccounts }, - }); + await updateUserData({ + newUserData: { googleAccounts: updatedGoogleAccounts }, + }); - await fetchAndSaveGoogleEvents({ - token: accessToken, - email: googleMail, - }); - } - } catch (error) { - console.error("Error during Google sign-in:", error); - } - }; - - const handleMicrosoftSignIn = async () => { - try { - console.log("Starting Microsoft sign-in..."); - - const authRequest = new AuthSession.AuthRequest({ - clientId: microsoftConfig.clientId, - scopes: microsoftConfig.scopes, - redirectUri: microsoftConfig.redirectUri, - responseType: AuthSession.ResponseType.Code, - usePKCE: true, // Enable PKCE - }); - - console.log("Auth request created:", authRequest); - - const authResult = await authRequest.promptAsync({ - authorizationEndpoint: microsoftConfig.authorizationEndpoint, - }); - - console.log("Auth result:", authResult); - - if (authResult.type === "success" && authResult.params?.code) { - const code = authResult.params.code; - console.log("Authorization code received:", code); - - // Exchange authorization code for tokens - const tokenResponse = await fetch(microsoftConfig.tokenEndpoint, { - method: "POST", - headers: { - "Content-Type": "application/x-www-form-urlencoded", - }, - body: `client_id=${ - microsoftConfig.clientId - }&redirect_uri=${encodeURIComponent( - microsoftConfig.redirectUri - )}&grant_type=authorization_code&code=${code}&code_verifier=${ - authRequest.codeVerifier - }&scope=${encodeURIComponent( - "https://graph.microsoft.com/Calendars.ReadWrite offline_access User.Read" - )}`, - }); - - console.log("Token response status:", tokenResponse.status); - - if (!tokenResponse.ok) { - const errorText = await tokenResponse.text(); - console.error("Token exchange failed:", errorText); - return; - } - - const tokenData = await tokenResponse.json(); - console.log("Token data received:", tokenData); - - if (tokenData?.access_token) { - console.log("Access token received, fetching user info..."); - - // Fetch user info from Microsoft Graph API to get the email - const userInfoResponse = await fetch( - "https://graph.microsoft.com/v1.0/me", - { - headers: { - Authorization: `Bearer ${tokenData.access_token}`, - }, + await fetchAndSaveGoogleEvents({ + token: accessToken, + email: googleMail, + }); } - ); + } catch (error) { + console.error("Error during Google sign-in:", error); + } + }; - const userInfo = await userInfoResponse.json(); - console.log("User info received:", userInfo); + const handleMicrosoftSignIn = async () => { + try { + console.log("Starting Microsoft sign-in..."); - if (userInfo.error) { - console.error("Error fetching user info:", userInfo.error); - } else { - const outlookMail = userInfo.mail || userInfo.userPrincipalName; - - let microsoftAccounts = profileData?.microsoftAccounts; - const updatedMicrosoftAccounts = microsoftAccounts - ? { ...microsoftAccounts, [outlookMail]: tokenData.access_token } - : { [outlookMail]: tokenData.access_token }; - - // Update user data with Microsoft token and email - await updateUserData({ - newUserData: { microsoftAccounts: updatedMicrosoftAccounts }, + const authRequest = new AuthSession.AuthRequest({ + clientId: microsoftConfig.clientId, + scopes: microsoftConfig.scopes, + redirectUri: microsoftConfig.redirectUri, + responseType: AuthSession.ResponseType.Code, + usePKCE: true, // Enable PKCE }); - await fetchAndSaveOutlookEvents( - tokenData.access_token, - outlookMail - ); - console.log("User data updated successfully."); - } - } - } else { - console.warn("Authentication was not successful:", authResult); - } - } catch (error) { - console.error("Error during Microsoft sign-in:", error); - } - }; + console.log("Auth request created:", authRequest); - const handleAppleSignIn = async () => { - try { - console.log("Starting Apple Sign-in..."); + const authResult = await authRequest.promptAsync({ + authorizationEndpoint: microsoftConfig.authorizationEndpoint, + }); - const credential = await AppleAuthentication.signInAsync({ - requestedScopes: [ - AppleAuthentication.AppleAuthenticationScope.EMAIL, - AppleAuthentication.AppleAuthenticationScope.FULL_NAME, - ], - }); + console.log("Auth result:", authResult); - console.log("Apple sign-in result:", credential); + if (authResult.type === "success" && authResult.params?.code) { + const code = authResult.params.code; + console.log("Authorization code received:", code); - const appleToken = credential.identityToken; - const appleMail = credential.email; + // Exchange authorization code for tokens + const tokenResponse = await fetch(microsoftConfig.tokenEndpoint, { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + body: `client_id=${ + microsoftConfig.clientId + }&redirect_uri=${encodeURIComponent( + microsoftConfig.redirectUri + )}&grant_type=authorization_code&code=${code}&code_verifier=${ + authRequest.codeVerifier + }&scope=${encodeURIComponent( + "https://graph.microsoft.com/Calendars.ReadWrite offline_access User.Read" + )}`, + }); - if (appleToken) { - console.log("Apple ID token received. Fetch user info if needed..."); + console.log("Token response status:", tokenResponse.status); - await updateUserData({ - newUserData: { appleToken, appleMail }, - }); + if (!tokenResponse.ok) { + const errorText = await tokenResponse.text(); + console.error("Token exchange failed:", errorText); + return; + } - console.log("User data updated with Apple ID token."); - await fetchAndSaveAppleEvents({ token: appleToken, email: appleMail! }); - } else { - console.warn( - "Apple authentication was not successful or email was hidden." - ); - } - } catch (error) { - console.error("Error during Apple Sign-in:", error); - } - }; + const tokenData = await tokenResponse.json(); + console.log("Token data received:", tokenData); - const debouncedUpdateUserData = useCallback( - debounce(async (color: string) => { - try { - await updateUserData({ - newUserData: { - eventColor: color, - }, - }); - } catch (error) { - console.error("Failed to update color:", error); - setSelectedColor(previousSelectedColor); - } - }, 500), - [] - ); + if (tokenData?.access_token) { + console.log("Access token received, fetching user info..."); - const debouncedUpdateFirstDayOfWeek = useCallback( - debounce(async (firstDayOfWeek: string) => { - try { - await updateUserData({ - newUserData: { - firstDayOfWeek, - }, - }); - } catch (error) { - console.error("Failed to update first day of week:", error); - } - }, 500), - [] - ); - - const handleChangeFirstDayOfWeek = (firstDayOfWeek: string) => { - setFirstDayOfWeek(firstDayOfWeek === "Sundays" ? "Mondays" : "Sundays"); - debouncedUpdateFirstDayOfWeek( - firstDayOfWeek === "Sundays" ? "Mondays" : "Sundays" - ); - }; - - const handleChangeColor = (color: string) => { - setPreviousSelectedColor(selectedColor); - setSelectedColor(color); - debouncedUpdateUserData(color); - }; - - const clearToken = async ( - provider: "google" | "outlook" | "apple", - email: string - ) => { - const newUserData: Partial = {}; - if (provider === "google") { - let googleAccounts = profileData?.googleAccounts; - if (googleAccounts) { - googleAccounts[email] = null; - newUserData.googleAccounts = googleAccounts; - } - } else if (provider === "outlook") { - let microsoftAccounts = profileData?.microsoftAccounts; - if (microsoftAccounts) { - microsoftAccounts[email] = null; - newUserData.microsoftAccounts = microsoftAccounts; - } - } else if (provider === "apple") { - let appleAccounts = profileData?.appleAccounts; - if (appleAccounts) { - appleAccounts[email] = null; - newUserData.appleAccounts = appleAccounts; - } - } - await updateUserData({ newUserData }); - }; - - let isConnectedToGoogle = false; - if (profileData?.googleAccounts) { - Object.values(profileData?.googleAccounts).forEach((item) => { - if (item !== null) { - isConnectedToGoogle = true; - return; - } - }); - } - - let isConnectedToMicrosoft = false; - const microsoftAccounts = profileData?.microsoftAccounts; - if (microsoftAccounts) { - Object.values(profileData?.microsoftAccounts).forEach((item) => { - if (item !== null) { - isConnectedToMicrosoft = true; - return; - } - }); - } - - let isConnectedToApple = false; - if (profileData?.appleAccounts) { - Object.values(profileData?.appleAccounts).forEach((item) => { - if (item !== null) { - isConnectedToApple = true; - return; - } - }); - } - - return ( - - setPageIndex(0)}> - - - - Return to main settings - - - - - Calendar settings - - - Event Color Preference - - - handleChangeColor(colorMap.pink)}> - - {selectedColor == colorMap.pink && ( - - )} - - - handleChangeColor(colorMap.orange)} - > - - {selectedColor == colorMap.orange && ( - - )} - - - handleChangeColor(colorMap.green)}> - - {selectedColor == colorMap.green && ( - - )} - - - handleChangeColor(colorMap.teal)}> - - {selectedColor == colorMap.teal && ( - - )} - - - handleChangeColor(colorMap.purple)} - > - - {selectedColor == colorMap.purple && ( - - )} - - - - - - Weekly Start Date - - handleChangeFirstDayOfWeek("Sundays")} - /> - - Sundays - - {" "} - (default) - - - - - handleChangeFirstDayOfWeek("Mondays")} - /> - - Mondays - - - - - Add Calendar - - - + - - {selectedStatus === ProfileType.FAMILY_DEVICE - ? "Device Name" - : "First Name"} - - { - lNameRef.current?.focus(); - }} - blurOnSubmit={false} - returnKeyType="next" - /> + setShowAddUserDialog(false)} + center + marginT-30 + > + Return to user settings + + + - {selectedStatus !== ProfileType.FAMILY_DEVICE && ( - <> - Last Name - { - emailRef.current?.focus(); - }} - blurOnSubmit={false} - returnKeyType="next" - /> - - )} + setOnNewUserClick(false)} + > + + + + + + New User Information + + { + setOnNewUserClick(false); + }} + > + + + + - {selectedStatus !== ProfileType.FAMILY_DEVICE && ( - <> - Email Address (Optional) - - - )} + + {pfpUri ? ( + + ) : ( + + } + backgroundColor={Colors.grey60} + style={{borderRadius: 25}} + center + /> + )} - - - ); + {pfpUri ? ( + + + Clear user photo + + + ) : ( + + + Upload User Profile Photo + + + )} + + + + Member Status + + setSelectedStatus(item)} + showSearch + floatingPlaceholder + style={styles.inViewPicker} + trailingAccessory={ + + + + } + > + + + + + + + + + {selectedStatus === ProfileType.FAMILY_DEVICE + ? "Device Name" + : "First Name"} + + { + lNameRef.current?.focus(); + }} + blurOnSubmit={false} + returnKeyType="next" + /> + + {selectedStatus !== ProfileType.FAMILY_DEVICE && ( + <> + Last Name + { + emailRef.current?.focus(); + }} + blurOnSubmit={false} + returnKeyType="next" + /> + + )} + + {selectedStatus !== ProfileType.FAMILY_DEVICE && ( + <> + Email Address (Optional) + + + )} + + + + + + ); +}; + +const styles = StyleSheet.create({ + searchField: { + borderWidth: 0.7, + borderColor: "#9b9b9b", + borderRadius: 15, + height: 42, + paddingLeft: 10, + marginVertical: 20, + }, +}); + +export default FeedbackPage; diff --git a/components/pages/main/SignInPage.tsx b/components/pages/main/SignInPage.tsx index b3b0718..8f926b2 100644 --- a/components/pages/main/SignInPage.tsx +++ b/components/pages/main/SignInPage.tsx @@ -1,183 +1,193 @@ import { - Button, - ButtonSize, - Colors, - KeyboardAwareScrollView, - LoaderScreen, - Text, - TextField, - TextFieldRef, - View, + Button, + ButtonSize, + Colors, + KeyboardAwareScrollView, + LoaderScreen, + Text, + TextField, + TextFieldRef, + View, } from "react-native-ui-lib"; -import React, {useRef, useState} from "react"; -import {useSignIn} from "@/hooks/firebase/useSignIn"; -import {KeyboardAvoidingView, Platform, StyleSheet} from "react-native"; +import React, { useRef, useState } from "react"; +import { useSignIn } from "@/hooks/firebase/useSignIn"; +import { KeyboardAvoidingView, Platform, StyleSheet } from "react-native"; import Toast from "react-native-toast-message"; import KeyboardManager from "react-native-keyboard-manager"; -import {SafeAreaView} from "react-native-safe-area-context"; -import {useRouter} from "expo-router"; +import { SafeAreaView } from "react-native-safe-area-context"; +import { useRouter } from "expo-router"; -KeyboardManager.setEnableAutoToolbar(true); +if (Platform.OS === "ios") KeyboardManager.setEnableAutoToolbar(true); const SignInPage = () => { - const [email, setEmail] = useState(""); - const [password, setPassword] = useState(""); - const passwordRef = useRef(null); + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const passwordRef = useRef(null); - const {mutateAsync: signIn, error, isError, isLoading} = useSignIn(); + const { mutateAsync: signIn, error, isError, isLoading } = useSignIn(); - const router = useRouter() + const router = useRouter(); - const handleSignIn = async () => { - await signIn({email, password}); - if (!isError) { - Toast.show({ - type: "success", - text1: "Login successful!", - }); - } else { - Toast.show({ - type: "error", - text1: "Error logging in", - text2: `${error}`, - }); - } - }; + const handleSignIn = async () => { + await signIn({ email, password }); + if (!isError) { + Toast.show({ + type: "success", + text1: "Login successful!", + }); + } else { + Toast.show({ + type: "error", + text1: "Error logging in", + text2: `${error}`, + }); + } + }; - return ( - - - - - - Jump back into Cally - - - Please enter your details. - - + return ( + + + + + + Jump back into Cally + + + Please enter your details. + + - - { - // Move focus to the description field - passwordRef.current?.focus(); - }} - /> - - + + { + // Move focus to the description field + passwordRef.current?.focus(); + }} + /> + + - + -