{"version":3,"sources":["jsdelivr-header.js","/npm/jsjiit@0.0.24/src/exceptions.js","/npm/jsjiit@0.0.24/src/registration.js","/npm/jsjiit@0.0.24/src/attendance.js","/npm/jsjiit@0.0.24/src/exam.js","/npm/jsjiit@0.0.24/src/utils.js","/npm/jsjiit@0.0.24/src/encryption.js","/npm/jsjiit@0.0.24/src/wrapper.js"],"names":[],"mappings":"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","file":"/npm/jsjiit@0.0.24/dist/jsjiit.esm.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/jsjiit@0.0.24/dist/jsjiit.esm.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","/**\n * @module Exceptions\n */\n/**\n * Error classes for handling various API and session-related exceptions\n * @class APIError\n * @extends {Error} Base JavaScript Error class\n * @param {string} message - Error message describing what went wrong\n * @description Base class for API-related errors. Thrown when there is a general API error that doesn't fit other categories.\n */\nexport class APIError extends Error {\n  constructor(message) {\n    super(message);\n    this.name = 'APIError';\n  }\n}\n\n/**\n * Error classes for handling various API and session-related exceptions\n * @class LoginError\n * @extends {APIError} Base API error class\n * @param {string} message - Error message describing what went wrong\n * @description Error thrown during login attempts. Indicates authentication failed, invalid credentials, or other login-specific issues.\n */\nexport class LoginError extends APIError {\n  constructor(message) {\n    super(message);\n    this.name = 'LoginError';\n  }\n}\n\n/**\n * Error classes for handling various API and session-related exceptions\n * @class SessionError\n * @extends {Error} Base JavaScript Error class\n * @param {string} message - Error message describing what went wrong\n * @description Base class for session-related errors. Handles issues with user sessions and authentication state.\n */\nexport class SessionError extends Error {\n  constructor(message) {\n    super(message);\n    this.name = 'SessionError';\n  }\n}\n\n/**\n * Error classes for handling various API and session-related exceptions\n * @class SessionExpired\n * @extends {SessionError} Base session error class\n * @param {string} message - Error message describing what went wrong\n * @description Error thrown when the user's session has expired. Indicates the user needs to log in again to refresh their session.\n */\nexport class SessionExpired extends SessionError {\n  constructor(message) {\n    super(message);\n    this.name = 'SessionExpired';\n  }\n}\n\n/**\n * Error classes for handling various API and session-related exceptions\n * @class NotLoggedIn\n * @extends {SessionError} Base session error class\n * @param {string} message - Error message describing what went wrong\n * @description Error thrown when attempting authenticated operations without being logged in. Indicates the user needs to log in before accessing protected resources.\n */\nexport class NotLoggedIn extends SessionError {\n  constructor(message) {\n    super(message);\n    this.name = 'NotLoggedIn';\n  }\n}\n\n/**\n * Error classes for handling various API and session-related exceptions\n * @class AccountAPIError\n * @extends {Error} Base JavaScript Error class\n * @param {string} message - Error message describing what went wrong\n * @description Error thrown during account management operations. Handles errors related to account actions like password changes.\n */\nexport class AccountAPIError extends Error {\n  constructor(message) {\n    super(message);\n    this.name = 'AccountAPIError';\n  }\n}\n","/**\n * @module Registration\n */\nexport class RegisteredSubject {\n  /**\n   * Class containing registered subject info like Lecturer name, credits, etc\n   * @param {string} employee_name - Name of the employee/lecturer\n   * @param {string} employee_code - Code of the employee\n   * @param {string} minor_subject - Minor subject information\n   * @param {string} remarks - Any remarks\n   * @param {string} stytype - Style type\n   * @param {number} credits - Number of credits\n   * @param {string} subject_code - Code of the subject\n   * @param {string} subject_component_code - Component code of the subject\n   * @param {string} subject_desc - Description of the subject\n   * @param {string} subject_id - ID of the subject\n   * @param {string} audtsubject - Audit subject information\n   */\n  constructor(\n    employee_name,\n    employee_code,\n    minor_subject,\n    remarks,\n    stytype,\n    credits,\n    subject_code,\n    subject_component_code,\n    subject_desc,\n    subject_id,\n    audtsubject\n  ) {\n    this.employee_name = employee_name;\n    this.employee_code = employee_code;\n    this.minor_subject = minor_subject;\n    this.remarks = remarks;\n    this.stytype = stytype;\n    this.credits = credits;\n    this.subject_code = subject_code;\n    this.subject_component_code = subject_component_code;\n    this.subject_desc = subject_desc;\n    this.subject_id = subject_id;\n    this.audtsubject = audtsubject;\n  }\n\n  /**\n   * Static method to create a RegisteredSubject from a JSON object\n   * @param {object} resp - JSON object representing RegisteredSubject\n   * @returns {RegisteredSubject} A new RegisteredSubject instance\n   */\n  static from_json(resp) {\n    return new RegisteredSubject(\n      resp[\"employeename\"],\n      resp[\"employeecode\"],\n      resp[\"minorsubject\"],\n      resp[\"remarks\"],\n      resp[\"stytype\"],\n      resp[\"credits\"],\n      resp[\"subjectcode\"],\n      resp[\"subjectcomponentcode\"],\n      resp[\"subjectdesc\"],\n      resp[\"subjectid\"],\n      resp[\"audtsubject\"]\n    );\n  }\n}\n\nexport class Registrations {\n  /**\n   * Class containing all registered subjects and total course credits for the semester\n   * @param {object} resp - JSON response object with registrations and total credits\n   */\n  constructor(resp) {\n    this.raw_response = resp;\n    this.total_credits = resp[\"totalcreditpoints\"];\n    this.subjects = resp[\"registrations\"].map(RegisteredSubject.from_json);\n  }\n}\n","/**\n * @module Attendance\n */\nexport class AttendanceHeader {\n  /**\n   * Class which contains header info in the Attendance API\n   * @param {string} branchdesc - Description of the branch\n   * @param {string} name - Name of the student or entity\n   * @param {string} programdesc - Description of the program\n   * @param {string} stynumber - Style number or identifier\n   */\n  constructor(branchdesc, name, programdesc, stynumber) {\n    this.branchdesc = branchdesc;\n    this.name = name;\n    this.programdesc = programdesc;\n    this.stynumber = stynumber;\n  }\n\n  /**\n   * Static method to create an AttendanceHeader from a JSON object\n   * @param {object} resp - JSON object representing AttendanceHeader\n   * @returns {AttendanceHeader} A new AttendanceHeader instance\n   */\n  static from_json(resp) {\n    return new AttendanceHeader(resp.branchdesc, resp.name, resp.programdesc, resp.stynumber);\n  }\n}\n\nexport class Semester {\n  /**\n   * Class which contains Semester info\n   * @param {string} registration_code - Registration code of the semester\n   * @param {string} registration_id - Registration ID of the semester\n   */\n  constructor(registration_code, registration_id) {\n    this.registration_code = registration_code;\n    this.registration_id = registration_id;\n  }\n\n  /**\n   * Static method to create a Semester from a JSON object\n   * @param {object} resp - JSON object representing Semester\n   * @returns {Semester} A new Semester instance\n   */\n  static from_json(resp) {\n    return new Semester(resp.registrationcode, resp.registrationid);\n  }\n}\n\nexport class AttendanceMeta {\n  /**\n   * Class which contains metadata for Attendance\n   * @param {object} resp - JSON response object with headers and semesters\n   */\n  constructor(resp) {\n    this.raw_response = resp;\n    this.headers = resp.headerlist.map(AttendanceHeader.from_json);\n    this.semesters = resp.semlist.map(Semester.from_json);\n  }\n\n  /**\n   * Returns the latest AttendanceHeader\n   * @returns {AttendanceHeader} The first header in the list\n   */\n  latest_header() {\n    return this.headers[0];\n  }\n\n  /**\n   * Returns the latest Semester\n   * @returns {Semester} The first semester in the list\n   */\n  latest_semester() {\n    return this.semesters[0];\n  }\n}","/**\n * @module Exams\n */\nexport class ExamEvent {\n  /**\n   * Class containing exam event info\n   * @param {string} exam_event_code - Code of the exam event\n   * @param {number} event_from - Event from timestamp\n   * @param {string} exam_event_desc - Description of the exam event\n   * @param {string} registration_id - Registration ID\n   * @param {string} exam_event_id - Exam event ID\n   */\n  constructor(exam_event_code, event_from, exam_event_desc, registration_id, exam_event_id) {\n    this.exam_event_code = exam_event_code;\n    this.event_from = event_from;\n    this.exam_event_desc = exam_event_desc;\n    this.registration_id = registration_id;\n    this.exam_event_id = exam_event_id;\n  }\n\n  /**\n   * Static method to create an ExamEvent from a JSON object\n   * @param {object} resp - JSON object representing ExamEvent\n   * @returns {ExamEvent} A new ExamEvent instance\n   */\n  static from_json(resp) {\n    return new ExamEvent(\n      resp[\"exameventcode\"],\n      resp[\"eventfrom\"],\n      resp[\"exameventdesc\"],\n      resp[\"registrationid\"],\n      resp[\"exameventid\"]\n    );\n  }\n}\n","/**\n * @module Utils\n */\n/**\n * Generates a date sequence string from a given date or current date\n * The sequence format is: d[0]m[0]y[0]w[0]d[1]m[1]y[1] where:\n * d = day padded to 2 digits\n * m = month padded to 2 digits\n * y = last 2 digits of year\n * w = weekday number (0-6)\n * @param {Date} [date=null] - Date object to generate sequence from. If null, uses current date\n * @returns {string} The generated date sequence string\n */\nexport function generate_date_seq(date = null) {\n  if (date === null) {\n    date = new Date();\n  }\n  const day = String(date.getDate()).padStart(2, \"0\");\n  const month = String(date.getMonth() + 1).padStart(2, \"0\"); // Months are 0-indexed in JS\n  const year = String(date.getFullYear()).slice(2);\n  const weekday = String(date.getDay());\n\n  return day[0] + month[0] + year[0] + weekday + day[1] + month[1] + year[1];\n}\n\n/**\n * Generates a random string of specified length using alphanumeric characters\n * @param {number} n - Length of random string to generate\n * @returns {string} Random string of length n containing alphanumeric characters\n */\nexport function get_random_char_seq(n) {\n  const charset = \"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n  let result = \"\";\n\n  for (let i = 0; i < n; i++) {\n    const randomIndex = Math.floor(Math.random() * charset.length);\n    result += charset[randomIndex];\n  }\n\n  return result;\n}\n","import { generate_date_seq, get_random_char_seq } from \"./utils.js\";\n\n/**\n * @module Encryption\n */\n/**\n * Encodes binary data to base64 string\n * @param {Uint8Array} data - Binary data to encode\n * @returns {string} Base64 encoded string\n */\nexport function base64Encode(data) {\n  return btoa(String.fromCharCode.apply(null, new Uint8Array(data)));\n}\n\n/**\n * Decodes base64 string to binary data\n * @param {string} data - Base64 string to decode\n * @returns {Uint8Array} Decoded binary data\n */\nexport function base64Decode(data) {\n  return Uint8Array.from(atob(data), (c) => c.charCodeAt(0));\n}\n\n// Initialization Vector (IV)\nconst IV = new TextEncoder().encode(\"dcek9wb8frty1pnm\");\n\n/**\n * Generates an AES key based on date sequence\n * @param {Date} [date=null] - Optional date to use for key generation\n * @returns {Promise<CryptoKey>} Generated AES-CBC key\n */\nexport async function generate_key(date = null) {\n  const dateSeq = generate_date_seq(date);\n  const keyData = new TextEncoder().encode(\"qa8y\" + dateSeq + \"ty1pn\");\n  return window.crypto.subtle.importKey(\"raw\", keyData, { name: \"AES-CBC\" }, false, [\"encrypt\", \"decrypt\"]);\n}\n\n/**\n * Generates an encrypted local name for request headers\n * @param {Date} [date=null] - Optional date to use for name generation\n * @returns {Promise<string>} Base64 encoded encrypted local name\n */\nexport async function generate_local_name(date = null) {\n  const randomCharSeq = get_random_char_seq(4);\n  const dateSeq = generate_date_seq(date);\n  const randomSuffix = get_random_char_seq(5);\n  const nameBytes = new TextEncoder().encode(randomCharSeq + dateSeq + randomSuffix);\n  const encryptedBytes = await encrypt(nameBytes);\n\n  return base64Encode(encryptedBytes);\n}\n\n/**\n * Encrypts data using AES-CBC\n * @param {Uint8Array} data - Data to encrypt\n * @returns {Promise<Uint8Array>} Encrypted data\n */\nexport async function encrypt(data) {\n  const key = await generate_key();\n  const encrypted = await window.crypto.subtle.encrypt({ name: \"AES-CBC\", iv: IV }, key, data);\n  return new Uint8Array(encrypted);\n}\n\n/**\n * Decrypts data using AES-CBC\n * @param {Uint8Array} data - Data to decrypt\n * @returns {Promise<Uint8Array>} Decrypted data\n */\nexport async function decrypt(data) {\n  const key = await generate_key();\n  const decrypted = await window.crypto.subtle.decrypt({ name: \"AES-CBC\", iv: IV }, key, data);\n  return new Uint8Array(decrypted);\n}\n\n/**\n * Deserializes an encrypted base64 payload\n * @param {string} payload - Base64 encoded encrypted payload\n * @returns {Promise<object>} Decrypted and parsed JSON object\n */\nexport async function deserialize_payload(payload) {\n  const pbytes = base64Decode(payload);\n  const raw = await decrypt(pbytes);\n  return JSON.parse(new TextDecoder().decode(raw));\n}\n\n/**\n * Serializes and encrypts a payload object\n * @param {object} payload - Object to serialize and encrypt\n * @returns {Promise<string>} Base64 encoded encrypted payload\n */\nexport async function serialize_payload(payload) {\n  const raw = new TextEncoder().encode(JSON.stringify(payload));\n  const pbytes = await encrypt(raw);\n  return base64Encode(pbytes);\n}\n","import { NotLoggedIn, SessionExpired, SessionError, AccountAPIError, LoginError, APIError } from \"./exceptions.js\";\nimport { RegisteredSubject, Registrations } from \"./registration.js\";\nimport { AttendanceMeta, AttendanceHeader, Semester } from \"./attendance.js\";\nimport { ExamEvent } from \"./exam.js\";\nimport { generate_local_name, serialize_payload } from \"./encryption.js\";\n\n/**\n * @module Wrapper\n */\n/**\n * Base API endpoint for the JIIT web portal\n * @constant {string}\n */\nexport const API = \"https://webportal.jiit.ac.in:6011/StudentPortalAPI\";\n\n/**\n * Default CAPTCHA values used for login\n * @constant {{captcha: string, hidden: string}}\n */\nexport const DEFCAPTCHA = { captcha: \"phw5n\", hidden: \"gmBctEffdSg=\" };\n\n/**\n * Class representing a session with the web portal\n */\nexport class WebPortalSession {\n  /**\n   * Creates a WebPortalSession instance from API response\n   * @param {Object} resp - Response object from login API\n   * @param {Object} resp.regdata - Registration data containing user details\n   * @param {Array} resp.regdata.institutelist - List of institutes user has access to\n   * @param {string} resp.regdata.memberid - Member ID of the user\n   * @param {string} resp.regdata.userid - User ID\n   * @param {string} resp.regdata.token - Token for authentication\n   * @param {string} resp.regdata.clientid - Client ID\n   * @param {string} resp.regdata.membertype - Type of member\n   * @param {string} resp.regdata.name - Name of the user\n   * @param {string} resp.regdata.enrollmentno - Enrollment number\n   */\n  constructor(resp) {\n    this.raw_response = resp;\n    this.regdata = resp[\"regdata\"];\n\n    let institute = this.regdata[\"institutelist\"][0];\n    this.institute = institute[\"label\"];\n    this.instituteid = institute[\"value\"];\n    this.memberid = this.regdata[\"memberid\"];\n    this.userid = this.regdata[\"userid\"];\n\n    this.token = this.regdata[\"token\"];\n    let expiry_timestamp = JSON.parse(atob(this.token.split(\".\")[1]))[\"exp\"];\n    this.expiry = new Date(expiry_timestamp * 1000); // In JavaScript, Date expects milliseconds\n\n    this.clientid = this.regdata[\"clientid\"];\n    this.membertype = this.regdata[\"membertype\"];\n    this.name = this.regdata[\"name\"];\n    this.enrollmentno = this.regdata[\"enrollmentno\"];\n  }\n\n  /**\n   * Generates authentication headers for API requests\n   * @returns {Promise<Object>} Headers object containing Authorization and LocalName\n   */\n  async get_headers() {\n    const localname = await generate_local_name();\n    return {\n      Authorization: `Bearer ${this.token}`,\n      LocalName: localname,\n    };\n  }\n}\n\n/**\n * Main class for interacting with the JIIT web portal API\n */\nexport class WebPortal {\n  /**\n   * Creates a WebPortal instance\n   * @param {Object} [options={}] - Configuration options\n   * @param {boolean} [options.useProxy=false] - Whether to use a CORS proxy\n   * @param {string} [options.proxyUrl] - CORS proxy URL (required if useProxy is true)\n   * @param {string} [options.apiUrl=API] - Base API URL (for advanced use cases)\n   */\n  constructor(options = {}) {\n    this.session = null;\n    this.useProxy = options.useProxy || false;\n    this.proxyUrl = options.proxyUrl;\n    this.apiUrl = options.apiUrl || API;\n\n    // Validate that proxyUrl is provided when useProxy is true\n    if (this.useProxy && !this.proxyUrl) {\n      throw new Error('proxyUrl is required when useProxy is true');\n    }\n  }\n\n  /**\n   * Internal method to make HTTP requests to the API\n   * @private\n   * @param {string} method - HTTP method (GET, POST etc)\n   * @param {string} url - API endpoint URL\n   * @param {Object} [options={}] - Request options\n   * @param {Object} [options.headers] - Additional headers\n   * @param {Object} [options.json] - JSON payload\n   * @param {string} [options.body] - Raw body payload\n   * @param {boolean} [options.authenticated] - Whether request needs authentication\n   * @param {Error} [options.exception] - Custom error class to throw\n   * @returns {Promise<Object>} API response\n   * @throws {APIError} On API or network errors\n   */\n  async __hit(method, url, options = {}) {\n    let exception = APIError; // Default exception\n    if (options.exception) {\n      exception = options.exception;\n      delete options.exception;\n    }\n\n    console.log(options);\n    let header;\n    if (options.authenticated) {\n      header = await this.session.get_headers(); // Assumes calling method is authenticated\n      delete options.authenticated;\n    } else {\n      let localname = await generate_local_name();\n      header = { LocalName: localname };\n    }\n\n    if (options.headers) {\n      options.headers = { ...options.headers, ...header };\n    } else {\n      options.headers = header;\n    }\n\n    let fetchOptions = {\n      method: method,\n      headers: {\n        \"Content-Type\": \"application/json\",\n        ...options.headers,\n      },\n    };\n\n    if (options.json) {\n      fetchOptions.body = JSON.stringify(options.json);\n    } else {\n      fetchOptions.body = options.body;\n    }\n\n    // Construct the final URL based on proxy mode\n    let finalUrl;\n    if (this.useProxy) {\n      // Proxy mode: Send request to proxy with original URL as path\n      // Remove the API base from the URL if it exists to avoid duplication\n      let endpoint = url.replace(this.apiUrl, '');\n      finalUrl = `${this.proxyUrl}/proxy${endpoint}`;\n    } else {\n      // Direct mode: Use the URL as-is\n      finalUrl = url;\n    }\n\n    try {\n      console.log(\"fetching\", finalUrl, \"with options\", fetchOptions);\n      const response = await fetch(finalUrl, fetchOptions);\n\n      if (response.status === 513) {\n        throw new exception(\"JIIT Web Portal server is temporarily unavailable (HTTP 513). Please try again later.\");\n      }\n      if (response.status === 401) {\n        throw new SessionExpired(response.error);\n      }\n\n      const resp = await response.json();\n\n      if (resp.status && resp.status.responseStatus !== \"Success\") {\n        throw new exception(`status:\\n${JSON.stringify(resp.status, null, 2)}`);\n      }\n      return resp;\n    } catch (error) {\n      // Handle CORS errors\n      if (error instanceof TypeError && error.message.includes(\"CORS\")) {\n        throw new exception(\n          \"CORS error: Cannot access JIIT Web Portal API. \" +\n          \"If you're running this from a browser, try enabling proxy mode: \" +\n          \"new WebPortal({ useProxy: true })\"\n        );\n      }\n      throw new exception(error.message || \"Unknown error\");\n    }\n  }\n\n  /**\n   * Logs in a student user\n   * @param {string} username - Student username\n   * @param {string} password - Student password\n   * @param {{captcha: string, hidden: string}} [captcha=DEFCAPTCHA] - CAPTCHA\n   * @returns {Promise<WebPortalSession>} New session instance\n   * @throws {LoginError} On login failure\n   */\n  async student_login(username, password, captcha = DEFCAPTCHA) {\n    let pretoken_endpoint = \"/token/pretoken-check\";\n    let token_endpoint = \"/token/generate-token1\";\n\n    let payload = { username: username, usertype: \"S\", captcha: captcha };\n    payload = await serialize_payload(payload);\n\n    let resp = await this.__hit(\"POST\", this.apiUrl + pretoken_endpoint, { body: payload, exception: LoginError });\n\n    let payload2 = resp[\"response\"];\n    delete payload2[\"rejectedData\"];\n    payload2[\"Modulename\"] = \"STUDENTMODULE\";\n    payload2[\"passwordotpvalue\"] = password;\n    payload2 = await serialize_payload(payload2);\n\n    const resp2 = await this.__hit(\"POST\", this.apiUrl + token_endpoint, { body: payload2, exception: LoginError });\n    this.session = new WebPortalSession(resp2[\"response\"]);\n    return this.session;\n  }\n\n  /**\n   * Gets personal information of logged in student\n   * @returns {Promise<Object>} Student personal information\n   */\n  async get_personal_info() {\n    const ENDPOINT = \"/studentpersinfo/getstudent-personalinformation\";\n    const payload = {\n      clinetid: \"SOAU\",\n      instituteid: this.session.instituteid,\n    };\n    const resp = await this.__hit(\"POST\", this.apiUrl + ENDPOINT, { json: payload, authenticated: true });\n    return resp[\"response\"];\n  }\n\n  /**\n   * Gets bank account information of logged in student\n   * @returns {Promise<Object>} Student bank information\n   */\n  async get_student_bank_info() {\n    const ENDPOINT = \"/studentbankdetails/getstudentbankinfo\";\n    const payload = {\n      instituteid: this.session.instituteid,\n      studentid: this.session.memberid,\n    };\n    const resp = await this.__hit(\"POST\", this.apiUrl + ENDPOINT, { json: payload, authenticated: true });\n    return resp[\"response\"];\n  }\n\n  /**\n   * Changes password for logged in student\n   * @param {string} old_password - Current password\n   * @param {string} new_password - New password\n   * @returns {Promise<Object>} Response indicating success/failure\n   * @throws {AccountAPIError} On password change failure\n   */\n  async change_password(old_password, new_password) {\n    const ENDPOINT = \"/clxuser/changepassword\";\n    const payload = {\n      membertype: this.session.membertype,\n      oldpassword: old_password,\n      newpassword: new_password,\n      confirmpassword: new_password,\n    };\n    const resp = await this.__hit(\"POST\", this.apiUrl + ENDPOINT, {\n      json: payload,\n      authenticated: true,\n      exception: AccountAPIError,\n    });\n    return resp[\"response\"];\n  }\n\n  /**\n   * Gets attendance metadata including headers and semesters\n   * @returns {Promise<AttendanceMeta>} Attendance metadata\n   */\n  async get_attendance_meta() {\n    const ENDPOINT = \"/StudentClassAttendance/getstudentInforegistrationforattendence\";\n\n    const payload = {\n      clientid: this.session.clientid,\n      instituteid: this.session.instituteid,\n      membertype: this.session.membertype,\n    };\n\n    const resp = await this.__hit(\"POST\", this.apiUrl + ENDPOINT, { json: payload, authenticated: true });\n    return new AttendanceMeta(resp[\"response\"]);\n  }\n\n  /**\n   * Gets attendance details for a semester\n   * @param {AttendanceHeader} header - Attendance header\n   * @param {Semester} semester - Semester object\n   * @returns {Promise<Object>} Attendance details\n   */\n  async get_attendance(header, semester) {\n    const ENDPOINT = \"/StudentClassAttendance/getstudentattendancedetail\";\n\n    const payload = await serialize_payload({\n      clientid: this.session.clientid,\n      instituteid: this.session.instituteid,\n      registrationcode: semester.registration_code,\n      registrationid: semester.registration_id,\n      stynumber: header.stynumber,\n    });\n\n    // console.log(payload)\n\n    const resp = await this.__hit(\"POST\", this.apiUrl + ENDPOINT, { json: payload, authenticated: true });\n    return resp[\"response\"];\n  }\n\n  /**\n   * Gets attendance for every class of the subject for the semester.\n   * @param {Semester} semester - Semester object\n   * @param {string} subjectid - Subject ID\n   * @param {string} individualsubjectcode - Individual subject code\n   * @param {Array<string>} subjectcomponentids - Array of subject component IDs\n   * @returns {Promise<Object>} Subject attendance details\n   */\n  async get_subject_daily_attendance(semester, subjectid, individualsubjectcode, subjectcomponentids) {\n    const ENDPOINT = \"/StudentClassAttendance/getstudentsubjectpersentage\";\n    const payload = await serialize_payload({\n      cmpidkey: subjectcomponentids.map((id) => ({ subjectcomponentid: id })),\n      clientid: this.session.clientid,\n      instituteid: this.session.instituteid,\n      registrationcode: semester.registration_code,\n      registrationid: semester.registration_id,\n      subjectcode: individualsubjectcode,\n      subjectid: subjectid,\n    });\n    const resp = await this.__hit(\"POST\", this.apiUrl + ENDPOINT, { json: payload, authenticated: true });\n    return resp[\"response\"];\n  }\n\n  /**\n   * Gets list of registered semesters\n   * @returns {Promise<Array<Semester>>} Array of semester objects\n   */\n  async get_registered_semesters() {\n    const ENDPOINT = \"/reqsubfaculty/getregistrationList\";\n\n    const payload = await serialize_payload({\n      instituteid: this.session.instituteid,\n      studentid: this.session.memberid,\n    });\n    const resp = await this.__hit(\"POST\", this.apiUrl + ENDPOINT, { json: payload, authenticated: true });\n    return resp[\"response\"][\"registrations\"].map((i) => Semester.from_json(i));\n  }\n\n  /**\n   * Gets registered subjects and faculty details for a semester\n   * @param {Semester} semester - Semester object\n   * @returns {Promise<Registrations>} Registration details\n   */\n  async get_registered_subjects_and_faculties(semester) {\n    const ENDPOINT = \"/reqsubfaculty/getfaculties\";\n    const payload = await serialize_payload({\n      instituteid: this.session.instituteid,\n      studentid: this.session.memberid,\n      registrationid: semester.registration_id,\n    });\n    const resp = await this.__hit(\"POST\", this.apiUrl + ENDPOINT, { json: payload, authenticated: true });\n    return new Registrations(resp[\"response\"]);\n  }\n\n  /**\n   * Gets semesters that have exam events\n   * @returns {Promise<Array<Semester>>} Array of semester objects\n   */\n  async get_semesters_for_exam_events() {\n    const ENDPOINT = \"/studentcommonsontroller/getsemestercode-withstudentexamevents\";\n    const payload = await serialize_payload({\n      clientid: this.session.clientid,\n      instituteid: this.session.instituteid,\n      memberid: this.session.memberid,\n    });\n\n    const resp = await this.__hit(\"POST\", this.apiUrl + ENDPOINT, { json: payload, authenticated: true });\n    return resp[\"response\"][\"semesterCodeinfo\"][\"semestercode\"].map((i) => Semester.from_json(i));\n  }\n\n  /**\n   * Gets exam events for a semester\n   * @param {Semester} semester - Semester object\n   * @returns {Promise<Array<ExamEvent>>} Array of exam event objects\n   */\n  async get_exam_events(semester) {\n    const ENDPOINT = \"/studentcommonsontroller/getstudentexamevents\";\n    const payload = await serialize_payload({\n      instituteid: this.session.instituteid,\n      registationid: semester.registration_id, // not a typo\n    });\n\n    const resp = await this.__hit(\"POST\", this.apiUrl + ENDPOINT, { json: payload, authenticated: true });\n    return resp[\"response\"][\"eventcode\"][\"examevent\"].map((i) => ExamEvent.from_json(i));\n  }\n\n  /**\n   * Gets exam schedule for an exam event\n   * @param {ExamEvent} exam_event - Exam event object\n   * @returns {Promise<Object>} Exam schedule details\n   */\n  async get_exam_schedule(exam_event) {\n    const ENDPOINT = \"/studentsttattview/getstudent-examschedule\";\n    const payload = await serialize_payload({\n      instituteid: this.session.instituteid,\n      registrationid: exam_event.registration_id,\n      exameventid: exam_event.exam_event_id,\n    });\n    const resp = await this.__hit(\"POST\", this.apiUrl + ENDPOINT, { json: payload, authenticated: true });\n    return resp[\"response\"];\n  }\n\n  /**\n   * Gets semesters that have marks available\n   * @returns {Promise<Array<Semester>>} Array of semester objects\n   */\n  async get_semesters_for_marks() {\n    const ENDPOINT = \"/studentcommonsontroller/getsemestercode-exammarks\";\n    const payload = await serialize_payload({\n      instituteid: this.session.instituteid,\n      studentid: this.session.memberid,\n    });\n    const resp = await this.__hit(\"POST\", this.apiUrl + ENDPOINT, { json: payload, authenticated: true });\n    return resp[\"response\"][\"semestercode\"].map((i) => Semester.from_json(i));\n  }\n\n  /**\n   * Downloads marks PDF for a semester\n   * @param {Semester} semester - Semester object\n   * @throws {APIError} On download failure\n   */\n  async download_marks(semester) {\n    const ENDPOINT =\n      \"/studentsexamview/printstudent-exammarks/\" +\n      // this.session.memberid +\n      // \"/\" +\n      this.session.instituteid +\n      \"/\" +\n      semester.registration_id +\n      \"/\" +\n      semester.registration_code;\n    const localname = await generate_local_name();\n    let _headers = await this.session.get_headers(localname);\n    const fetchOptions = {\n      method: \"GET\",\n      headers: _headers,\n    };\n\n    try {\n      let downloadUrl = this.apiUrl + ENDPOINT;\n      if (this.useProxy) {\n        // Remove the API base from the URL if it exists to avoid duplication\n        let endpoint = downloadUrl.replace(this.apiUrl, '');\n        downloadUrl = `${this.proxyUrl}/proxy${endpoint}`;\n      }\n      const resp = await fetch(downloadUrl, fetchOptions);\n      const blob = await resp.blob();\n      const url = window.URL.createObjectURL(blob);\n      const a = document.createElement(\"a\");\n      a.href = url;\n      a.download = `marks_${semester.registration_code}.pdf`;\n      document.body.appendChild(a);\n      a.click();\n      window.URL.revokeObjectURL(url);\n      a.remove();\n    } catch (error) {\n      throw new APIError(error);\n    }\n  }\n\n  /**\n   * Gets semesters that have grade cards available\n   * @returns {Promise<Array<Semester>>} Array of semester objects\n   */\n  async get_semesters_for_grade_card() {\n    const ENDPOINT = \"/studentgradecard/getregistrationList\";\n    const payload = await serialize_payload({\n      instituteid: this.session.instituteid,\n    });\n    const resp = await this.__hit(\"POST\", this.apiUrl + ENDPOINT, { json: payload, authenticated: true });\n    return resp[\"response\"][\"registrations\"].map((i) => Semester.from_json(i));\n  }\n\n  /**\n   * Gets program ID for grade card\n   * @private\n   * @returns {Promise<string>} Program ID\n   */\n  async __get_program_id() {\n    const ENDPOINT = \"/studentgradecard/getstudentinfo\";\n    const payload = await serialize_payload({\n      instituteid: this.session.instituteid,\n    });\n    const resp = await this.__hit(\"POST\", this.apiUrl + ENDPOINT, { json: payload, authenticated: true });\n    return resp[\"response\"][\"programid\"];\n  }\n\n  /**\n   * Gets grade card for a semester\n   * @param {Semester} semester - Semester object\n   * @returns {Promise<Object>} Grade card details\n   */\n  async get_grade_card(semester) {\n    const programid = await this.__get_program_id();\n    const ENDPOINT = \"/studentgradecard/showstudentgradecard\";\n    const payload = await serialize_payload({\n      branchid: this.session.branch_id,\n      instituteid: this.session.instituteid,\n      programid: programid,\n      registrationid: semester.registration_id,\n    });\n    const resp = await this.__hit(\"POST\", this.apiUrl + ENDPOINT, { json: payload, authenticated: true });\n    return resp[\"response\"];\n  }\n\n  /**\n   * Gets current semester number\n   * @private\n   * @returns {Promise<number>} Current semester number\n   */\n  async __get_semester_number() {\n    const ENDPOINT = \"/studentsgpacgpa/checkIfstudentmasterexist\";\n    const payload = await serialize_payload({\n      instituteid: this.session.instituteid,\n      studentid: this.session.memberid,\n      name: this.session.name,\n      enrollmentno: this.session.enrollmentno,\n    });\n    const resp = await this.__hit(\"POST\", this.apiUrl + ENDPOINT, { json: payload, authenticated: true });\n    return resp[\"response\"][\"studentlov\"][\"currentsemester\"];\n  }\n\n  /**\n   * Gets SGPA and CGPA details\n   * @returns {Promise<Object>} SGPA and CGPA details\n   */\n  async get_sgpa_cgpa() {\n    const ENDPOINT = \"/studentsgpacgpa/getallsemesterdata\";\n    const stynumber = await this.__get_semester_number();\n    const payload = await serialize_payload({\n      instituteid: this.session.instituteid,\n      studentid: this.session.memberid,\n      stynumber: stynumber,\n    });\n    const resp = await this.__hit(\"POST\", this.apiUrl + ENDPOINT, { json: payload, authenticated: true });\n    return resp[\"response\"];\n  }\n\n  /**\n   * Gets pending miscellaneous charges/fines for the logged-in student\n   * @returns {Promise<Object>} The raw 'response' dict from the API.\n   *                           If there are no pending payments, the API returns\n   *                           status: Failure with error \"NO APPROVED REQUEST FOUND\".\n   * @throws {APIError} On any non-Success responseStatus\n   */\n  async get_fines_msc_charges() {\n    const ENDPOINT = \"/collectionpendingpayments/getpendingpaymentsdata\";\n    const payload = await serialize_payload({\n      instituteid: this.session.instituteid,\n      studentid: this.session.memberid,\n    });\n    const resp = await this.__hit(\"POST\", this.apiUrl + ENDPOINT, { json: payload, authenticated: true });\n    return resp[\"response\"];\n  }\n\n  /**\n   * Gets the fee summary for the logged-in student\n   * @returns {Promise<Object>} The raw 'response' dict from the API\n   * @throws {APIError} On any non-Success responseStatus\n   */\n  async get_fee_summary() {\n    const ENDPOINT = \"/studentfeeledger/loadfeesummary\";\n    const payload = {\n      instituteid: this.session.instituteid,\n    };\n    const resp = await this.__hit(\"POST\", this.apiUrl + ENDPOINT, { json: payload, authenticated: true });\n    return resp[\"response\"];\n  }\n\n  /**\n   * Gets subject choices for a semester\n   * @param {Semester} semester - A Semester object\n   * @returns {Promise<Object>} A dictionary with subject choices data\n   * @throws {APIError} Raised for generic API error\n   */\n  async get_subject_choices(semester) {\n    const ENDPOINT = \"/studentchoiceprint/getsubjectpreference\";\n\n    const payload = await serialize_payload({\n      instituteid: this.session.instituteid,\n      clientid: this.session.clientid,\n      registrationid: semester.registration_id,\n    });\n    const resp = await this.__hit(\"POST\", this.apiUrl + ENDPOINT, { json: payload, authenticated: true });\n    return resp[\"response\"];\n  }\n\n  async get_hostel_details() {\n    const ENDPOINT = \"/myhostelallocationdetail/gethostelallocationdetail\";\n    const payload = {\n      clientid: this.session.clientid,\n      instituteid: this.session.instituteid,\n      studentid: this.session.memberid,\n    };\n\n    const resp = await this.__hit(\"POST\", this.apiUrl + ENDPOINT, { json: payload, authenticated: true });\n\n    if (!resp?.response) {\n      throw new Error(\"Hostel details not found\");\n    }\n\n    return resp.response;\n  }\n\n  async fill_feedback_form(feedback_option) {\n    const SEMESTER_ENDPOINT = \"/feedbackformcontroller/getFeedbackEvent\";\n    const payload = {\n      instituteid: this.session.instituteid,\n    };\n    const resp = await this.__hit(\"POST\", this.apiUrl + SEMESTER_ENDPOINT, { json: payload, authenticated: true });\n    let semesters = resp[\"response\"][\"eventList\"];\n    let latest_semester = semesters[semesters.length - 1];\n    let latest_semester_code = latest_semester[\"eventcode\"];\n    let latest_semester_event_id = latest_semester[\"eventid\"];\n    let latest_semester_event_description = latest_semester[\"eventdescription\"];\n\n    const GRID_ENDPOINT = \"/feedbackformcontroller/getGriddataForFeedback\";\n    const grid_payload = await serialize_payload({\n      instituteid: this.session.instituteid,\n      studentid: this.session.memberid,\n      eventid: latest_semester_event_id,\n    });\n    const grid_resp = await this.__hit(\"POST\", this.apiUrl + GRID_ENDPOINT, { json: grid_payload, authenticated: true });\n    let grid_data = grid_resp[\"response\"][\"gridData\"];\n\n    // instituteid\n    // eventid\n    // eventdescription\n    let question_feedback_payload_array = grid_data.map((data) => {\n      return {\n        instituteid: this.session.instituteid,\n        eventid: latest_semester_event_id,\n        eventdescription: latest_semester_event_description,\n        facultyid: data[\"employeeid\"],\n        facultyname: data[\"employeename\"],\n        registrationid: data[\"registrationid\"],\n        studentid: data[\"studentid\"],\n        subjectcode: data[\"subjectcode\"],\n        subjectcomponentcode: data[\"subjectcomponentcode\"],\n        subjectcomponentid: data[\"subjectcomponentid\"],\n        subjectdescription: data[\"subjectdescription\"],\n        subjectid: data[\"subjectid\"],\n      };\n    });\n    const GET_QUESTIONS_ENDPOINT = \"/feedbackformcontroller/getIemQuestion\";\n    const SAVE_ENDPOINT = \"/feedbackformcontroller/savedatalist\";\n\n    for (let question_feedback_payload of question_feedback_payload_array) {\n      try {\n        const questions_api_resp = await this.__hit(\"POST\", this.apiUrl + GET_QUESTIONS_ENDPOINT, {\n          json: question_feedback_payload,\n          authenticated: true,\n        });\n      } catch (error) {\n        continue;\n      }\n\n      // Process the response to get the list of questions\n      if (!questions_api_resp || !questions_api_resp.response || !questions_api_resp.response.questionList) {\n        console.error(\n          \"Failed to retrieve question list or invalid response structure for payload:\",\n          question_feedback_payload,\n          \"Response:\",\n          questions_api_resp\n        );\n        // Skip to the next feedback item if data is missing\n        continue;\n      }\n      let actual_question_list = questions_api_resp[\"response\"][\"questionList\"];\n\n      // Update each question with the provided feedback_option\n      let questions_to_submit = actual_question_list.map((q) => ({\n        ...q, // Spread existing question properties\n        rating: feedback_option, // Set the rating using the function's argument\n      }));\n\n      // Construct the payload for saving the feedback\n      let save_data_payload = {\n        instituteid: question_feedback_payload.instituteid, // This comes from this.session.instituteid via map\n        studentid: this.session.memberid, // Logged-in user's ID\n        eventid: question_feedback_payload.eventid, // This comes from latest_semester_event_id via map\n        subjectid: question_feedback_payload.subjectid, // From the specific grid item\n        facultyid: question_feedback_payload.facultyid, // From the specific grid item\n        registrationid: question_feedback_payload.registrationid, // From the specific grid item\n        questionid: questions_to_submit, // The list of questions with updated ratings\n        facultycomments: null, // Defaulting to null; can be parameterized if needed\n        coursecomments: null, // Defaulting to null; can be parameterized if needed\n      };\n      save_data_payload = await serialize_payload(save_data_payload);\n\n      // Send the feedback data to the SAVE_ENDPOINT\n      await this.__hit(\"POST\", this.apiUrl + SAVE_ENDPOINT, {\n        json: save_data_payload,\n        authenticated: true,\n      });\n      // Optionally, collect or handle the response from SAVE_ENDPOINT\n    }\n  }\n}\n\n/**\n * Decorator that checks if user is authenticated before executing method\n * @param {Function} method - Method to decorate\n * @returns {Function} Decorated method that checks authentication\n * @throws {NotLoggedIn} If user is not logged in\n */\nfunction authenticated(method) {\n  return function (...args) {\n    if (this.session == null) {\n      throw new NotLoggedIn();\n    }\n    return method.apply(this, args);\n  };\n}\n\n/**\n * List of methods that require authentication\n * @constant {Array<string>}\n */\nconst authenticatedMethods = [\n  \"get_personal_info\",\n  \"get_student_bank_info\",\n  \"change_password\",\n  \"get_attendance_meta\",\n  \"get_attendance\",\n  \"get_subject_daily_attendance\",\n  \"get_registered_semesters\",\n  \"get_registered_subjects_and_faculties\",\n  \"get_semesters_for_exam_events\",\n  \"get_exam_events\",\n  \"get_exam_schedule\",\n  \"get_semesters_for_marks\",\n  \"download_marks\",\n  \"get_semesters_for_grade_card\",\n  \"__get_program_id\",\n  \"get_grade_card\",\n  \"__get_semester_number\",\n  \"get_sgpa_cgpa\",\n  \"get_hostel_details\",\n  \"get_fines_msc_charges\",\n  \"get_fee_summary\",\n  \"get_subject_choices\",\n];\n\nauthenticatedMethods.forEach((methodName) => {\n  WebPortal.prototype[methodName] = authenticated(WebPortal.prototype[methodName]);\n});\n"]}