diff --git a/package.json b/package.json index 1654f953..df98ea8c 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,6 @@ "formik-wizard-form": "^2.1.0", "framer-motion": "^10.16.4", "js-cookie": "^3.0.5", - "jsonwebtoken": "^9.0.2", "jwt-decode": "^4.0.0", "lucide-react": "^0.302.0", "material-icons": "^1.13.12", diff --git a/public/images/iiti_bg.JPG b/public/images/iiti_bg.JPG new file mode 100644 index 00000000..d0084443 Binary files /dev/null and b/public/images/iiti_bg.JPG differ diff --git a/src/app/(authroutes)/layout.tsx b/src/app/(authroutes)/layout.tsx new file mode 100644 index 00000000..0d783a05 --- /dev/null +++ b/src/app/(authroutes)/layout.tsx @@ -0,0 +1,29 @@ +import "../globals.css"; +import { Providers } from "@/store/provider"; +import { Suspense } from "react"; + +interface Props { + children: React.ReactNode; +} + +const AuthLayout = async ({ children }: Props) => { + return ( +
+ +
+ {/* sidebar and main content share this space */} + Loading...}> + +
+
+ {children} +
+
+
+
+
+
+ ); +}; + +export default AuthLayout; diff --git a/src/app/(authroutes)/recruiter/signup/page.tsx b/src/app/(authroutes)/recruiter/signup/page.tsx new file mode 100644 index 00000000..a0dc8e1a --- /dev/null +++ b/src/app/(authroutes)/recruiter/signup/page.tsx @@ -0,0 +1,8 @@ +import RecruiterSignup from "@/components/loginForms/recruiterSignup"; +import React from "react"; + +const Signup = () => { + return ; +}; + +export default Signup; diff --git a/src/app/events/page.tsx b/src/app/(routes)/events/page.tsx similarity index 100% rename from src/app/events/page.tsx rename to src/app/(routes)/events/page.tsx diff --git a/src/app/(routes)/layout.tsx b/src/app/(routes)/layout.tsx new file mode 100644 index 00000000..11fe1626 --- /dev/null +++ b/src/app/(routes)/layout.tsx @@ -0,0 +1,25 @@ +import "../globals.css"; +import Sidebar from "@/components/Sidebar"; +import MainContent from "@/components/MainContent"; +import { Providers } from "@/store/provider"; +import { Suspense } from "react"; + +interface Props { + children: React.ReactNode; +} + +const RouteLayout = async ({ children }: Props) => { + return ( +
+ {/* sidebar and main content share this space */} + Loading...}> + + + + {children} + +
+ ); +}; + +export default RouteLayout; diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 05f2ee82..6ef43a28 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,16 +1,9 @@ -import MenuButton from "@/components/MenuButton"; import "./globals.css"; import type { Metadata } from "next"; import { Inter } from "next/font/google"; -import Link from "next/link"; import { ToggleProvider } from "@/contextProviders/ToggleProvider"; -import Sidebar from "@/components/Sidebar"; -import MainContent from "@/components/MainContent"; -import NavButtonGroup from "@/components/NavButtonGroup"; import NextAuthProvider from "@/contextProviders/sessionProvider"; import { Toaster } from "react-hot-toast"; -import { Providers } from "@/store/provider"; -import { Suspense } from "react"; const inter = Inter({ subsets: ["latin"] }); @@ -21,10 +14,9 @@ export const metadata: Metadata = { interface Props { children: React.ReactNode; - auth: React.ReactNode; } -const RootLayout = async ({ children, auth }: Props) => { +const RootLayout = async ({ children }: Props) => { const className = inter.className; return ( @@ -32,31 +24,10 @@ const RootLayout = async ({ children, auth }: Props) => {
- {/* */} {/* Page Content */} - -
- {/* sidebar and main content share this space */} - Loading...}> - - - - {children} - -
- {auth} -
+ {children}
diff --git a/src/components/Calendar/context/ContextWrapper.tsx b/src/components/Calendar/context/ContextWrapper.tsx index 338ecdb8..f1b3d4b4 100644 --- a/src/components/Calendar/context/ContextWrapper.tsx +++ b/src/components/Calendar/context/ContextWrapper.tsx @@ -5,7 +5,7 @@ import { selectedDayEvent } from "./GlobalContext"; import { fetchEvents } from "@/helpers/api"; import toast from "react-hot-toast"; import Cookies from "js-cookie"; -import jwt from "jsonwebtoken"; +import { jwtDecode } from "jwt-decode"; import { fetchStudentEvents } from "@/helpers/student/api"; export const labelsClasses = new Map([ @@ -65,7 +65,7 @@ export default function ContextWrapper(props: any) { if (accessToken) { try { - const decoded = jwt.decode(accessToken); + const decoded: any = jwtDecode(accessToken); user = decoded ? { role: decoded.role } : null; } catch (error) { console.error("JWT decoding error:", error); diff --git a/src/components/loginForms/recruiterSignup.tsx b/src/components/loginForms/recruiterSignup.tsx new file mode 100644 index 00000000..6b6c8d9d --- /dev/null +++ b/src/components/loginForms/recruiterSignup.tsx @@ -0,0 +1,468 @@ +"use client"; +import { + Card, + CardHeader, + CardTitle, + CardDescription, + CardContent, + CardFooter, +} from "@/components/ui/card"; +import { Label } from "@/components/ui/label"; +import { Input } from "@/components/ui/input"; +import { + Select, + SelectTrigger, + SelectValue, + SelectContent, + SelectItem, + SelectGroup, +} from "@/components/ui/select"; +import { Button } from "@/components/ui/button"; +import { + getCompanies, + postCompany, + signupRecruiter, +} from "@/helpers/recruiter/signup"; +import { getJafDetails } from "@/helpers/recruiter/api"; +import toast from "react-hot-toast"; + +import { useEffect, useState } from "react"; +import { CompanyPostFC, JAFdetailsFC } from "@/helpers/recruiter/types"; +import { MultiSelect } from "../ui/multiselect"; +import Link from "next/link"; +import dynamic from "next/dynamic"; + +const Collapsible = dynamic(() => import("@/components/ui/collapsible"), { + ssr: false, +}); +const Loader = dynamic(() => import("../Loader/loader"), { + ssr: false, +}); + +export const RecruiterForm = ({ + formData, + setFormData, +}: { + formData: CompanyPostFC; + setFormData: (data: any) => void; +}) => { + const [jaf, setjaf] = useState(null); + const [loading, setLoading] = useState(true); + + const handleChange = ( + e: React.ChangeEvent, + ) => { + const { id, value } = e.currentTarget; + setFormData((prevState) => ({ + ...prevState, + [id]: value, + })); + }; + + const handleAdressChange = ( + e: React.ChangeEvent, + ) => { + const { id, value } = e.currentTarget; + setFormData((prevState) => ({ + ...prevState, + address: { + ...prevState.address, + [id]: value, + }, + })); + }; + + useEffect(() => { + getJafDetails().then((data) => { + setjaf(data); + setLoading(false); + }); + }, []); + + return ( + <> + {loading && } + {jaf && ( +
+
+
+ + +
+
+ + +
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + { + setFormData((prev) => ({ ...prev, domains: e })); + }} + /> +
+
+
+
+
+ + +
+
+ + +
+
+
+ + +
+
+ + +
+
+
+ + +
+
+
+ )} + + ); +}; + +export default function RecruiterSignup() { + const [companies, setCompanies] = useState([]); + const [createCompany, setCreateCompany] = useState(false); + + const [companyFormData, setCompanyFormData] = useState({ + name: "", + category: "", + yearOfEstablishment: "", + website: "", + size: 0, + annualTurnover: "", + socialMediaLink: "", + domains: [], + address: { + line1: "", + line2: "", + city: "", + state: "", + country: "", + }, + }); + + const [formData, setFormData] = useState({ + user: { name: "", email: "", contact: "" }, + companyId: "", + designation: "", + landline: "", + }); + + useEffect(() => { + getCompanies().then((data) => { + setCompanies(data); + }); + }, []); + + const handleInputChange = (e: React.ChangeEvent) => { + const { name, value } = e.target; + setFormData((prevFormData) => ({ + ...prevFormData, + [name]: value, + })); + }; + + const handleUserInputChange = (e: React.ChangeEvent) => { + const { name, value } = e.target; + setFormData((prevFormData) => ({ + ...prevFormData, + user: { ...prevFormData.user, [name]: value }, + })); + }; + + const handleSubmit = async () => { + if (createCompany) { + try { + const data = await postCompany(companyFormData); + + const updatedFormData = { ...formData, companyId: data[0] }; + setFormData(updatedFormData); + + const signupRes = await signupRecruiter(updatedFormData); + if (signupRes) { + toast.success("Successful! Please check your mail"); + } else { + toast.error("Some error occured"); + } + } catch (error) { + toast.error("Error creating company or signing up"); + } + return; + } + + try { + const signupRes = await signupRecruiter(formData); + if (signupRes) { + toast.success("Please check your mail"); + } else { + toast.error("Some error occured"); + } + } catch (error) { + toast.error("Error creating company or signing up"); + } + }; + + return ( + + + + Recruiter Registration + + Fill in the details to register. + + +
+
+
+ + +
+ {createCompany || ( +
+ + + +
+ )} + +
+ + +
+
+
+ + +
+
+ + +
+
+
+ + +
+
+ + {createCompany && ( + + + + )} +
+
+ +
+ + + + +
+
+
+ ); +} diff --git a/src/components/ui/collapsible.tsx b/src/components/ui/collapsible.tsx new file mode 100644 index 00000000..cd85ccf0 --- /dev/null +++ b/src/components/ui/collapsible.tsx @@ -0,0 +1,50 @@ +import React, { useState } from "react"; +import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; +import { motion } from "framer-motion"; + +const Collapsible = ({ + title, + children, + defaultexpanded = false, +}: { + title: String | React.ReactNode; + children: React.ReactNode; + defaultexpanded?: boolean; +}) => { + const [isExpanded, setIsExpanded] = useState(defaultexpanded); + + const handleToggle = () => { + setIsExpanded(!isExpanded); + }; + + return ( +
+
+
{title}
+ + + +
+ + + {children} + +
+ ); +}; + +export default Collapsible; diff --git a/src/components/ui/multiselect.tsx b/src/components/ui/multiselect.tsx index ab988b12..17eed330 100644 --- a/src/components/ui/multiselect.tsx +++ b/src/components/ui/multiselect.tsx @@ -5,15 +5,11 @@ export const MultiSelect = ({ givenOptions, formData, setFormData }) => { setFormData(selectedOptions.map((option) => option.value)); }; - console.log(formData); - const values = []; formData.forEach((element) => { values.push({ value: element, label: element }); }); - console.log(values); - const options = givenOptions.map((option) => ({ value: option, label: option, diff --git a/src/helpers/api.ts b/src/helpers/api.ts index 639bbfbc..73ea58a0 100644 --- a/src/helpers/api.ts +++ b/src/helpers/api.ts @@ -1,11 +1,10 @@ import qs from "qs"; import Cookies from "js-cookie"; import { jwtDecode } from "jwt-decode"; -import toast, { Toaster } from "react-hot-toast"; +import toast from "react-hot-toast"; import { ResumePatchData } from "./types"; const baseUrl = process.env.NEXT_PUBLIC_BACKEND_URL; -process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; interface ApiCallOptions { method?: string; @@ -506,7 +505,12 @@ export const fetchRegistrations = async ( ], }); }; -export const postRegistration = async (studentID: string, seasonID: string, registered: boolean) => { + +export const postRegistration = async ( + studentID: string, + seasonID: string, + registered: boolean, +) => { return apiCall("/registrations", { method: "POST", body: [ diff --git a/src/helpers/recruiter/api.ts b/src/helpers/recruiter/api.ts index 689955de..24bb3460 100644 --- a/src/helpers/recruiter/api.ts +++ b/src/helpers/recruiter/api.ts @@ -1,14 +1,6 @@ -import axios from "axios"; import { JobDetailFC, updateProfileFC, SalaryFC } from "./types"; import { OpenFile, apiCall } from "../api"; -const baseUrl = process.env.NEXT_PUBLIC_BACKEND_URL; -process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; - -const url = (NextUrl: string) => { - return `${baseUrl}/api/v1${NextUrl}`; -}; - export const fetchProfile = async () => { return apiCall(`/recruiter-view/recruiter`); }; diff --git a/src/helpers/recruiter/signup.ts b/src/helpers/recruiter/signup.ts new file mode 100644 index 00000000..0fa30e74 --- /dev/null +++ b/src/helpers/recruiter/signup.ts @@ -0,0 +1,23 @@ +import { apiCall } from "../api"; + +export async function getCompanies() { + return apiCall("/companies", { isAuth: false }); +} + +export async function signupRecruiter(data) { + return apiCall("/auth/recruiter", { + isAuth: false, + method: "POST", + body: data, + recieveResponse: true + }); +} + +export async function postCompany(data) { + return apiCall("/companies", { + isAuth: false, + method: "POST", + body: [data], + recieveResponse: true, + }); +} diff --git a/src/helpers/recruiter/types.ts b/src/helpers/recruiter/types.ts index 751d38da..b349ba04 100644 --- a/src/helpers/recruiter/types.ts +++ b/src/helpers/recruiter/types.ts @@ -217,3 +217,21 @@ export interface ProfileFC { socialMediaLink: string; }; } + +export interface CompanyPostFC { + name: string; + category: string; + yearOfEstablishment: string; + website: string; + size: 0; + annualTurnover: string; + socialMediaLink: string; + domains: string[]; + address: { + line1: string; + line2: string; + city: string; + state: string; + country: string; + }; +} diff --git a/src/middleware.ts b/src/middleware.ts index c633137c..6182c2ca 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -1,6 +1,6 @@ import { NextResponse } from "next/server"; import type { NextRequest } from "next/server"; -import jwt from "jsonwebtoken"; +import { jwtDecode } from "jwt-decode"; const adminRoutes = [ "/admin/company", @@ -37,7 +37,7 @@ export function middleware(request: NextRequest) { if (accessToken) { try { - const decoded = jwt.decode(accessToken.value); + const decoded: any = jwtDecode(accessToken.value); user = decoded ? { role: decoded.role } : null; } catch (error) { console.error("JWT decoding error:", error); diff --git a/yarn.lock b/yarn.lock index 2dfb74d8..75c1d9c3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1852,11 +1852,6 @@ browserslist@^4.23.0: node-releases "^2.0.14" update-browserslist-db "^1.0.16" -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== - busboy@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" @@ -2248,13 +2243,6 @@ eastasianwidth@^0.2.0: resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== -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" - electron-to-chromium@^1.4.796: version "1.4.816" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.816.tgz#3624649d1e7fde5cdbadf59d31a524245d8ee85f" @@ -3351,22 +3339,6 @@ json5@^1.0.2: dependencies: minimist "^1.2.0" -jsonwebtoken@^9.0.2: - 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" - "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.5: version "3.3.5" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" @@ -3377,23 +3349,6 @@ jsonwebtoken@^9.0.2: object.assign "^4.1.4" object.values "^1.1.6" -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" - -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" - jwt-decode@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-4.0.0.tgz#2270352425fd413785b2faf11f6e755c5151bd4b" @@ -3453,46 +3408,11 @@ lodash-es@^4.17.21: resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== -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.16.6, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -4688,11 +4608,6 @@ safe-array-concat@^1.1.2: has-symbols "^1.0.3" isarray "^2.0.5" -safe-buffer@^5.0.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - safe-regex-test@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.3.tgz#a5b4c0f06e0ab50ea2c395c14d8371232924c377"