analytica-frontend-lib 1.1.91 → 1.1.93

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -155,8 +155,13 @@ __export(src_exports, {
155
155
  getSubjectName: () => getSubjectName,
156
156
  syncDropdownState: () => syncDropdownState,
157
157
  useApiConfig: () => useApiConfig,
158
+ useAppContent: () => useAppContent,
159
+ useAppInitialization: () => useAppInitialization,
160
+ useAppStore: () => useAppStore,
158
161
  useAuth: () => useAuth,
159
162
  useAuthGuard: () => useAuthGuard,
163
+ useAuthStore: () => useAuthStore,
164
+ useInstitutionId: () => useInstitutionId,
160
165
  useMobile: () => useMobile,
161
166
  useQuizStore: () => useQuizStore,
162
167
  useRouteAuth: () => useRouteAuth,
@@ -8389,7 +8394,6 @@ var DownloadButton = ({
8389
8394
  await new Promise((resolve) => setTimeout(resolve, 200));
8390
8395
  }
8391
8396
  } catch (error) {
8392
- console.error(`Erro ao baixar ${item.label}:`, error);
8393
8397
  onDownloadError?.(
8394
8398
  item.type,
8395
8399
  error instanceof Error ? error : new Error(`Falha ao baixar ${item.label}`)
@@ -9927,7 +9931,7 @@ var HeaderAlternative = (0, import_react31.forwardRef)(
9927
9931
  );
9928
9932
 
9929
9933
  // src/components/Auth/zustandAuthAdapter.ts
9930
- function createZustandAuthAdapter(useAuthStore) {
9934
+ function createZustandAuthAdapter(useAuthStore2) {
9931
9935
  return {
9932
9936
  /**
9933
9937
  * Check if the user is authenticated based on sessionInfo and tokens
@@ -9935,7 +9939,7 @@ function createZustandAuthAdapter(useAuthStore) {
9935
9939
  * @returns {Promise<boolean>} Promise that resolves to authentication status
9936
9940
  */
9937
9941
  checkAuth: async () => {
9938
- const { sessionInfo, tokens } = useAuthStore.getState();
9942
+ const { sessionInfo, tokens } = useAuthStore2.getState();
9939
9943
  return Boolean(sessionInfo && tokens);
9940
9944
  },
9941
9945
  /**
@@ -9943,26 +9947,26 @@ function createZustandAuthAdapter(useAuthStore) {
9943
9947
  *
9944
9948
  * @returns {unknown} Current user data from the store
9945
9949
  */
9946
- getUser: () => useAuthStore.getState().user,
9950
+ getUser: () => useAuthStore2.getState().user,
9947
9951
  /**
9948
9952
  * Get the current session information from the store
9949
9953
  *
9950
9954
  * @returns {unknown} Current session info from the store
9951
9955
  */
9952
- getSessionInfo: () => useAuthStore.getState().sessionInfo,
9956
+ getSessionInfo: () => useAuthStore2.getState().sessionInfo,
9953
9957
  /**
9954
9958
  * Get the current authentication tokens from the store
9955
9959
  *
9956
9960
  * @returns {unknown} Current tokens from the store
9957
9961
  */
9958
- getTokens: () => useAuthStore.getState().tokens,
9962
+ getTokens: () => useAuthStore2.getState().tokens,
9959
9963
  /**
9960
9964
  * Sign out the user by calling the store's signOut function if available
9961
9965
  *
9962
9966
  * @returns {void}
9963
9967
  */
9964
9968
  signOut: () => {
9965
- const signOutFn = useAuthStore.getState().signOut;
9969
+ const signOutFn = useAuthStore2.getState().signOut;
9966
9970
  if (typeof signOutFn === "function") signOutFn();
9967
9971
  }
9968
9972
  };
@@ -10252,7 +10256,6 @@ var useQuizStore = (0, import_zustand9.create)()(
10252
10256
  const activityId = quiz.id;
10253
10257
  const userId = get().getUserId();
10254
10258
  if (!userId || userId === "") {
10255
- console.warn("selectAnswer called before userId is set");
10256
10259
  return;
10257
10260
  }
10258
10261
  const question = quiz.questions.find((q) => q.id === questionId);
@@ -10286,7 +10289,6 @@ var useQuizStore = (0, import_zustand9.create)()(
10286
10289
  const activityId = quiz.id;
10287
10290
  const userId = get().getUserId();
10288
10291
  if (!userId || userId === "") {
10289
- console.warn("selectMultipleAnswer called before userId is set");
10290
10292
  return;
10291
10293
  }
10292
10294
  const question = quiz.questions.find((q) => q.id === questionId);
@@ -10321,16 +10323,10 @@ var useQuizStore = (0, import_zustand9.create)()(
10321
10323
  const activityId = quiz.id;
10322
10324
  const userId = get().getUserId();
10323
10325
  if (!userId || userId === "") {
10324
- console.warn(
10325
- "selectDissertativeAnswer called before userId is set"
10326
- );
10327
10326
  return;
10328
10327
  }
10329
10328
  const question = quiz.questions.find((q) => q.id === questionId);
10330
10329
  if (!question || question.questionType !== "DISSERTATIVA" /* DISSERTATIVA */) {
10331
- console.warn(
10332
- "selectDissertativeAnswer called for non-dissertative question"
10333
- );
10334
10330
  return;
10335
10331
  }
10336
10332
  const existingAnswerIndex = userAnswers.findIndex(
@@ -10364,7 +10360,6 @@ var useQuizStore = (0, import_zustand9.create)()(
10364
10360
  const activityId = quiz.id;
10365
10361
  const userId = get().getUserId();
10366
10362
  if (!userId || userId === "") {
10367
- console.warn("skipQuestion called before userId is set");
10368
10363
  return;
10369
10364
  }
10370
10365
  const existingAnswerIndex = userAnswers.findIndex(
@@ -10397,7 +10392,6 @@ var useQuizStore = (0, import_zustand9.create)()(
10397
10392
  const activityId = quiz.id;
10398
10393
  const userId = get().getUserId();
10399
10394
  if (!userId || userId === "") {
10400
- console.warn("addUserAnswer called before userId is set");
10401
10395
  return;
10402
10396
  }
10403
10397
  const question = quiz.questions.find((q) => q.id === questionId);
@@ -10625,9 +10619,6 @@ var useQuizStore = (0, import_zustand9.create)()(
10625
10619
  );
10626
10620
  }
10627
10621
  if (questionIndex === -1) {
10628
- console.warn(
10629
- `Question with id "${question.id}" not found in active quiz`
10630
- );
10631
10622
  return;
10632
10623
  }
10633
10624
  set({ currentQuestionIndex: questionIndex });
@@ -11984,34 +11975,16 @@ var QuizFooter = (0, import_react36.forwardRef)(
11984
11975
  children: "Avan\xE7ar"
11985
11976
  }
11986
11977
  )
11987
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex flex-row items-center justify-between w-full", children: [
11988
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { children: quiz?.canRetry && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
11989
- Button_default,
11990
- {
11991
- variant: "link",
11992
- action: "primary",
11993
- size: "medium",
11994
- onClick: () => openModal("modalResolution"),
11995
- children: "Ver Resolu\xE7\xE3o"
11996
- }
11997
- ) }),
11998
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
11999
- Button_default,
12000
- {
12001
- variant: "solid",
12002
- action: "primary",
12003
- size: "medium",
12004
- onClick: () => {
12005
- if (quiz?.canRetry) {
12006
- onRepeat?.();
12007
- } else {
12008
- openModal("modalResolution");
12009
- }
12010
- },
12011
- children: quiz?.canRetry ? `Repetir ${getTypeLabel(quiz.type)}` : "Ver Resolu\xE7\xE3o"
12012
- }
12013
- )
12014
- ] })
11978
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "flex flex-row items-center justify-center w-full", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
11979
+ Button_default,
11980
+ {
11981
+ variant: "link",
11982
+ action: "primary",
11983
+ size: "medium",
11984
+ onClick: () => openModal("modalResolution"),
11985
+ children: "Ver resolu\xE7\xE3o"
11986
+ }
11987
+ ) })
12015
11988
  }
12016
11989
  ),
12017
11990
  /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
@@ -12290,17 +12263,32 @@ var QuizHeaderResult = (0, import_react37.forwardRef)(
12290
12263
  );
12291
12264
  }
12292
12265
  );
12293
- var QuizResultHeaderTitle = (0, import_react37.forwardRef)(({ className, showBadge = true, ...props }, ref) => {
12266
+ var QuizResultHeaderTitle = (0, import_react37.forwardRef)(({ className, showBadge = true, onRepeat, canRetry, ...props }, ref) => {
12294
12267
  const { quiz } = useQuizStore();
12295
12268
  return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
12296
12269
  "div",
12297
12270
  {
12298
12271
  ref,
12299
- className: cn("flex flex-row pt-4 justify-between", className),
12272
+ className: cn(
12273
+ "flex flex-row pt-4 justify-between items-center",
12274
+ className
12275
+ ),
12300
12276
  ...props,
12301
12277
  children: [
12302
12278
  /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("p", { className: "text-text-950 font-bold text-2xl", children: "Resultado" }),
12303
- showBadge && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(QuizBadge, { subtype: quiz?.subtype || void 0 })
12279
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "flex flex-row gap-3 items-center", children: [
12280
+ canRetry && onRepeat && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
12281
+ Button_default,
12282
+ {
12283
+ variant: "solid",
12284
+ action: "primary",
12285
+ size: "medium",
12286
+ onClick: onRepeat,
12287
+ children: "Repetir question\xE1rio"
12288
+ }
12289
+ ),
12290
+ showBadge && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(QuizBadge, { subtype: quiz?.subtype || void 0 })
12291
+ ] })
12304
12292
  ]
12305
12293
  }
12306
12294
  );
@@ -12492,14 +12480,15 @@ var QuizListResult = (0, import_react37.forwardRef)(({ className, onSubjectClick
12492
12480
  });
12493
12481
  var QuizListResultByMateria = ({
12494
12482
  subject,
12495
- onQuestionClick
12483
+ onQuestionClick,
12484
+ subjectName
12496
12485
  }) => {
12497
12486
  const { getQuestionsGroupedBySubject, getQuestionIndex } = useQuizStore();
12498
12487
  const groupedQuestions = getQuestionsGroupedBySubject();
12499
12488
  const answeredQuestions = groupedQuestions[subject] || [];
12500
12489
  const formattedQuestions = subject == "all" ? Object.values(groupedQuestions).flat() : answeredQuestions;
12501
12490
  return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "flex flex-col", children: [
12502
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "flex flex-row pt-4 justify-between", children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("p", { className: "text-text-950 font-bold text-2xl", children: answeredQuestions?.[0]?.knowledgeMatrix?.[0]?.subject?.name ?? "Sem mat\xE9ria" }) }),
12491
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "flex flex-row pt-4 justify-between", children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("p", { className: "text-text-950 font-bold text-2xl", children: subjectName || formattedQuestions?.[0]?.knowledgeMatrix?.[0]?.subject?.name || "Sem mat\xE9ria" }) }),
12503
12492
  /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("section", { className: "flex flex-col ", children: [
12504
12493
  /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("p", { className: "pt-6 pb-4 text-text-950 font-bold text-lg", children: "Resultado das quest\xF5es" }),
12505
12494
  /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("ul", { className: "flex flex-col gap-2 pt-4", children: formattedQuestions.map((question) => {
@@ -12530,6 +12519,310 @@ var QuizListResultByMateria = ({
12530
12519
  ] })
12531
12520
  ] });
12532
12521
  };
12522
+
12523
+ // src/hooks/useAppInitialization.ts
12524
+ var import_react39 = require("react");
12525
+
12526
+ // src/hooks/useInstitution.ts
12527
+ var import_react38 = require("react");
12528
+ function useInstitutionId() {
12529
+ const [institutionId, setInstitutionId] = (0, import_react38.useState)(() => {
12530
+ return document.querySelector('meta[name="institution-id"]')?.getAttribute("content") ?? null;
12531
+ });
12532
+ (0, import_react38.useEffect)(() => {
12533
+ const metaTag = document.querySelector('meta[name="institution-id"]');
12534
+ if (!metaTag) return;
12535
+ const observer = new MutationObserver(() => {
12536
+ const newValue = metaTag.getAttribute("content");
12537
+ setInstitutionId(newValue);
12538
+ });
12539
+ observer.observe(metaTag, {
12540
+ attributes: true,
12541
+ attributeFilter: ["content"]
12542
+ });
12543
+ return () => observer.disconnect();
12544
+ }, []);
12545
+ return institutionId;
12546
+ }
12547
+
12548
+ // src/store/appStore.ts
12549
+ var import_zustand10 = require("zustand");
12550
+ var import_middleware4 = require("zustand/middleware");
12551
+ var useAppStore = (0, import_zustand10.create)()(
12552
+ (0, import_middleware4.persist)(
12553
+ (set, get) => ({
12554
+ institutionId: null,
12555
+ initialized: false,
12556
+ /**
12557
+ * Set the institution ID
12558
+ * @param {string | null} institutionId - The institution ID from meta tag
12559
+ * @returns {void}
12560
+ */
12561
+ setInstitutionId: (institutionId) => {
12562
+ set({ institutionId });
12563
+ },
12564
+ /**
12565
+ * Set the initialized state
12566
+ * @param {boolean} initialized - Whether the app has been initialized
12567
+ * @returns {void}
12568
+ */
12569
+ setInitialized: (initialized) => {
12570
+ set({ initialized });
12571
+ },
12572
+ /**
12573
+ * Initialize the app by reading the institution ID from meta tag
12574
+ * @returns {void}
12575
+ */
12576
+ initialize: (id) => {
12577
+ const { initialized } = get();
12578
+ if (initialized) {
12579
+ return;
12580
+ }
12581
+ set({
12582
+ institutionId: id,
12583
+ initialized: true
12584
+ });
12585
+ }
12586
+ }),
12587
+ {
12588
+ name: "@app-storage:analytica:v2" /* APP_STORAGE */,
12589
+ storage: (0, import_middleware4.createJSONStorage)(() => localStorage)
12590
+ }
12591
+ )
12592
+ );
12593
+
12594
+ // src/store/authStore.ts
12595
+ var import_zustand11 = require("zustand");
12596
+ var import_middleware5 = require("zustand/middleware");
12597
+ var useAuthStore = (0, import_zustand11.create)()(
12598
+ (0, import_middleware5.persist)(
12599
+ (set, get) => ({
12600
+ user: null,
12601
+ tokens: null,
12602
+ isAuthenticated: false,
12603
+ profiles: [],
12604
+ selectedProfile: null,
12605
+ sessionInfo: null,
12606
+ /**
12607
+ * Set the current user
12608
+ * @param {User | null} user - The user object or null to clear
12609
+ * @returns {void}
12610
+ */
12611
+ setUser: (user) => {
12612
+ set({ user, isAuthenticated: !!user });
12613
+ },
12614
+ /**
12615
+ * Set the authentication tokens
12616
+ * @param {AuthTokens | null} tokens - The authentication tokens or null to clear
12617
+ * @returns {void}
12618
+ */
12619
+ setTokens: (tokens) => {
12620
+ set({ tokens });
12621
+ },
12622
+ /**
12623
+ * Set user profiles
12624
+ * @param {UserProfile[]} profiles - Array of user profiles
12625
+ * @returns {void}
12626
+ */
12627
+ setProfiles: (profiles) => {
12628
+ set({ profiles });
12629
+ },
12630
+ /**
12631
+ * Set the selected profile
12632
+ * @param {UserProfile | null} profile - The selected profile or null to clear
12633
+ * @returns {void}
12634
+ */
12635
+ setSelectedProfile: (profile) => {
12636
+ set({ selectedProfile: profile });
12637
+ },
12638
+ /**
12639
+ * Set the session info
12640
+ * @param {SessionInfo | null} sessionInfo - The session info or null to clear
12641
+ * @returns {void}
12642
+ */
12643
+ setSessionInfo: (sessionInfo) => {
12644
+ set({ sessionInfo });
12645
+ },
12646
+ /**
12647
+ * Sign in user with complete auth data
12648
+ * @param {User} user - The user object
12649
+ * @param {AuthTokens} tokens - The authentication tokens
12650
+ * @param {UserProfile[]} profiles - Array of user profiles
12651
+ * @returns {void}
12652
+ */
12653
+ signIn: (user, tokens, profiles) => {
12654
+ set({
12655
+ user,
12656
+ tokens,
12657
+ profiles,
12658
+ isAuthenticated: true
12659
+ });
12660
+ },
12661
+ /**
12662
+ * Sign out user and clear all auth data
12663
+ * @returns {void}
12664
+ */
12665
+ signOut: () => {
12666
+ set({
12667
+ user: null,
12668
+ tokens: null,
12669
+ isAuthenticated: false,
12670
+ profiles: [],
12671
+ selectedProfile: null,
12672
+ sessionInfo: null
12673
+ });
12674
+ },
12675
+ /**
12676
+ * Update user session data (after login completion)
12677
+ * @param {Partial<User>} sessionData - Partial user data to update
12678
+ * @returns {void}
12679
+ */
12680
+ updateUserSession: (sessionData) => {
12681
+ const { user } = get();
12682
+ if (user) {
12683
+ const updatedUser = { ...user, ...sessionData };
12684
+ set({ user: updatedUser });
12685
+ }
12686
+ }
12687
+ }),
12688
+ {
12689
+ name: "@auth-storage:analytica:v2" /* AUTH_STORAGE */,
12690
+ storage: (0, import_middleware5.createJSONStorage)(() => localStorage)
12691
+ }
12692
+ )
12693
+ );
12694
+
12695
+ // src/hooks/useAppInitialization.ts
12696
+ function useAppInitialization() {
12697
+ const getInstitutionId = useInstitutionId();
12698
+ const { initialize, initialized, institutionId } = useAppStore();
12699
+ const authFunctions = (0, import_react39.useMemo)(
12700
+ () => ({
12701
+ checkAuth: async () => {
12702
+ const { sessionInfo, tokens } = useAuthStore.getState();
12703
+ return Boolean(sessionInfo && tokens);
12704
+ },
12705
+ signOut: () => {
12706
+ const { signOut } = useAuthStore.getState();
12707
+ signOut();
12708
+ },
12709
+ getUser: () => {
12710
+ const { user } = useAuthStore.getState();
12711
+ return user;
12712
+ },
12713
+ getSessionInfo: () => {
12714
+ const { sessionInfo } = useAuthStore.getState();
12715
+ return sessionInfo;
12716
+ },
12717
+ getTokens: () => {
12718
+ const { tokens } = useAuthStore.getState();
12719
+ return tokens;
12720
+ }
12721
+ }),
12722
+ []
12723
+ );
12724
+ return {
12725
+ // Estado da inicialização
12726
+ getInstitutionId,
12727
+ initialize,
12728
+ initialized,
12729
+ institutionId,
12730
+ // Funções de autenticação
12731
+ authFunctions
12732
+ };
12733
+ }
12734
+
12735
+ // src/hooks/useAppContent.ts
12736
+ var import_react40 = require("react");
12737
+ var import_react_router_dom3 = require("react-router-dom");
12738
+ function useAppContent(config) {
12739
+ const navigate = (0, import_react_router_dom3.useNavigate)();
12740
+ const { setTokens, setSessionInfo, setSelectedProfile } = useAuthStore();
12741
+ const {
12742
+ api,
12743
+ getInstitutionId,
12744
+ initialize,
12745
+ initialized,
12746
+ endpoint = "/auth/session-info",
12747
+ maxRetries = 1,
12748
+ retryDelay = 2e3,
12749
+ onClearParamsFromURL,
12750
+ onError,
12751
+ onNotFoundNavigation
12752
+ } = config;
12753
+ const apiConfig = useApiConfig(api);
12754
+ useTheme();
12755
+ const handleNotFoundNavigation = () => {
12756
+ if (onNotFoundNavigation) {
12757
+ onNotFoundNavigation();
12758
+ } else {
12759
+ navigate("/painel");
12760
+ }
12761
+ };
12762
+ const handleSetSelectedProfile = (0, import_react40.useCallback)(
12763
+ (profile) => {
12764
+ setSelectedProfile(profile);
12765
+ },
12766
+ [setSelectedProfile]
12767
+ );
12768
+ const handleClearParamsFromURL = (0, import_react40.useCallback)(() => {
12769
+ if (onClearParamsFromURL) {
12770
+ onClearParamsFromURL();
12771
+ } else {
12772
+ globalThis.location.replace("/painel");
12773
+ }
12774
+ }, [onClearParamsFromURL]);
12775
+ const handleError = (0, import_react40.useCallback)(
12776
+ (error) => {
12777
+ if (onError) {
12778
+ onError(error);
12779
+ } else {
12780
+ console.error("Erro ao obter informa\xE7\xF5es da sess\xE3o:", error);
12781
+ navigate("/", { replace: true });
12782
+ }
12783
+ },
12784
+ [navigate, onError]
12785
+ );
12786
+ const urlAuthConfig = (0, import_react40.useMemo)(
12787
+ () => ({
12788
+ setTokens,
12789
+ setSessionInfo,
12790
+ setSelectedProfile: handleSetSelectedProfile,
12791
+ api: apiConfig,
12792
+ endpoint,
12793
+ clearParamsFromURL: handleClearParamsFromURL,
12794
+ maxRetries,
12795
+ retryDelay,
12796
+ onError: handleError
12797
+ }),
12798
+ [
12799
+ setTokens,
12800
+ setSessionInfo,
12801
+ handleSetSelectedProfile,
12802
+ apiConfig,
12803
+ endpoint,
12804
+ handleClearParamsFromURL,
12805
+ maxRetries,
12806
+ retryDelay,
12807
+ handleError
12808
+ ]
12809
+ );
12810
+ useUrlAuthentication(urlAuthConfig);
12811
+ const { sessionInfo } = useAuth();
12812
+ const institutionIdToUse = (0, import_react40.useMemo)(() => {
12813
+ return sessionInfo?.institutionId || getInstitutionId;
12814
+ }, [sessionInfo?.institutionId, getInstitutionId]);
12815
+ (0, import_react40.useEffect)(() => {
12816
+ if (institutionIdToUse && !initialized) {
12817
+ initialize(institutionIdToUse);
12818
+ }
12819
+ }, [institutionIdToUse, initialize, initialized]);
12820
+ return {
12821
+ handleNotFoundNavigation,
12822
+ urlAuthConfig,
12823
+ institutionIdToUse
12824
+ };
12825
+ }
12533
12826
  // Annotate the CommonJS export names for ESM import in node:
12534
12827
  0 && (module.exports = {
12535
12828
  ANSWER_STATUS,
@@ -12657,8 +12950,13 @@ var QuizListResultByMateria = ({
12657
12950
  getSubjectName,
12658
12951
  syncDropdownState,
12659
12952
  useApiConfig,
12953
+ useAppContent,
12954
+ useAppInitialization,
12955
+ useAppStore,
12660
12956
  useAuth,
12661
12957
  useAuthGuard,
12958
+ useAuthStore,
12959
+ useInstitutionId,
12662
12960
  useMobile,
12663
12961
  useQuizStore,
12664
12962
  useRouteAuth,