diff --git a/index.html b/index.html index a1429e4..5549d19 100644 --- a/index.html +++ b/index.html @@ -1,157 +1,164 @@ - - - - - - - Timetable Generator - - - -

NISER Timetable Generator

+ + + + -
- -
-

Select Courses

-
-
+ + Timetable Generator + + -
-
+ +

NISER Timetable Generator

+ +
+ +
+

Select Courses

+
+
+ +
+
-
-
- -
-
- - - - +
+
+ +
+ + + + + +

ICS files can be added to Google (or any other) Calendar. Currently this feature only works when you + generate with codes. If you want to generate the timetable pdf with nicknames, do so after the ICS + file is downloaded. Will fix soon.

- +
+ - -
-

Generated Timetable

-
- - - - - - - - - - - - - - - - + +
+

Generated Timetable

+
+ +
Day08:3009:3010:3011:3012:3013:3014:3015:3016:3017:3018:30
+ + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - -
Day08:3009:3010:3011:3012:3013:3014:3015:3016:3017:3018:30
MondayABCDLunch BreakEGHIJK
MondayABCDLunch BreakEGHIJK
TuesdayFABCLunch BreakDGHIKJ
TuesdayFABCLunch BreakDGHIKJ
WednesdayEFABLunch BreakCGHIJK
WednesdayEFABLunch BreakCGHIJK
ThursdayDEFALunch BreakBGHIKJ
ThursdayDEFALunch BreakBGHIKJ
FridayCDEFLunch BreakNo ClassNo ClassNo ClassNo ClassNo ClassNo Class
-
- -
    -
+ + Friday + C + D + E + F + Lunch Break + No Class + No Class + No Class + No Class + No Class + No Class + +
- + +
    +
+ +
- + + + + + + + + + - - - - - - - + \ No newline at end of file diff --git a/scripts/data.js b/scripts/data.js index 0c4aabb..77104dc 100644 --- a/scripts/data.js +++ b/scripts/data.js @@ -2,168 +2,271 @@ let year = '2024'; let semester = 'Fall'; function School(code, name, courses) { - this.code = code; - this.name = name; - this.courses = courses; + this.code = code; + this.name = name; + this.courses = courses; } function short_name(school) { - return school.name.split(' ').slice(2).join(' ') + return school.name.split(' ').slice(2).join(' ') } function Course(name, nick, slot) { - this.name = name; - this.nick = nick; - this.slot = slot; + this.name = name; + this.nick = nick; + this.slot = slot; } let schools = { - 'SCS': new School('C', 'School of Chemical Sciences', []), - 'SBS': new School('B', 'School of Biological Sciences', []), - 'SPS': new School('P', 'School of Physical Sciences', []), - 'SMS': new School('M', 'School of Mathematical Sciences', []), - 'SCPS': new School('CS', 'School of Computer Sciences', []), - 'SHSS': new School('H', 'School of Humanities and Social Sciences', []), - 'CMRP': new School('R', 'Center for Medical and Radiation Physics', []), + 'SCS': new School('C', 'School of Chemical Sciences', []), + 'SBS': new School('B', 'School of Biological Sciences', []), + 'SPS': new School('P', 'School of Physical Sciences', []), + 'SMS': new School('M', 'School of Mathematical Sciences', []), + 'SCPS': new School('CS', 'School of Computer Sciences', []), + 'SHSS': new School('H', 'School of Humanities and Social Sciences', []), + 'CMRP': new School('R', 'Center for Medical and Radiation Physics', []), }; let courses = { - // always use A1, A2, ... for degenerates of slot A - /* Biology */ - 'B201': new Course('Microbiology (B1)', 'MicroBio', 'A'), - 'B202': new Course('Biochemistry (B1)', 'Biochem', 'B'), - - 'B301': new Course('Animal Physiology (B2)', 'Animal Physio', 'B'), - 'B302': new Course('Plant Physiology (B2)', 'Plant Physio', 'C'), - 'B303': new Course('Ecology (LH3)', 'Ecology', 'A'), - 'B353': new Course('Plant Developmental Biology (B2)', 'Plant DevBio', 'E'), - 'B354': new Course('Neurobiology (B4)', 'Neuro', 'C'), - - 'B402': new Course('Developmental Biology (LH2)', 'DevBio', 'B'), - 'B405': new Course('Biotechniques (LH2)', 'Biotech', 'A'), - 'B406': new Course('Introductory Biophysics (LH3)', 'Biophys', 'C'), - 'B451': new Course('Advanced Cell Biology (B1)', 'Adv CellBio', 'D'), - 'B455': new Course('Enzymology (B5)', 'Enzymo', 'C'), - 'B466': new Course('Model organisms in Biomedical Research (B5)','BioMed','B'), - // 'B465': new Course('Structural Biology (B5)', 'StrBio', 'B'), - - 'B551': new Course('Advanced Molecular Biology (B3)', 'Adv MolBio', 'D'), - 'B552': new Course('Advanced Immunology (B4)', 'Adv Immuno', 'A'), - 'B555': new Course('Advanced Genetics (B6)', 'Adv Genetics', 'B'), - - /* Chemistry */ - 'C201': new Course('Basic Inorganic Chemistry (C6)', 'Inorganic', 'D'), - 'C203': new Course('Reaction Mechanism in Organic Chemistry (C6)', 'Organic', 'E'), - 'C207': new Course('Mathematical Methods for Chemists (LH4)', 'MMC', 'C'), - - 'C301': new Course('Physical Organic Chemistry (C1)', 'POC', 'D'), - 'C302': new Course('Molecular Spectroscopy and Group Theory (C5)', 'MolSpec', 'B'), - 'C307': new Course('Thermodynamics and Electrochemistry (LH4)', 'Thermo', 'F'), - - 'C401': new Course('Physical Methods in Chemistry-II (C4)', 'PMC2', 'B'), - 'C403': new Course('Chemistry of Heterocycles and Natural Products (C5)', 'Hetero cycles', 'E'), - - // 'C552': new Course('Solid State Chemistry (LH4)', 'SSC', 'C'), - // 'C557': new Course('Nuclear Magnetic Resonance (C5)', 'NMR', 'A'), - 'C560': new Course('Chemistry of Nanomaterials (C6)', 'Nano', 'A'), - 'C568': new Course('Advanced Fluorescence Spectroscopy (LH1)', 'Fluoro Spec', 'A'), - 'C572': new Course('Frontiers in Organic Synthesis (C2)', 'OrgSynth', 'B'), - - /* Computer Science */ - 'CS201': new Course('Theory of Computation (M1)', 'ToC', 'J'), - 'CS301': new Course('Design and Analysis of Algorithm (M4)', 'DAA', 'K'), - 'CS452': new Course('Algorithmic Coding Theory (M4)', 'AlgoCode', 'B'), - 'CS425': new Course('Randomized Algorithms (M5)', 'RA', 'K'), - 'CS453': new Course('Complexity Theory (M5)', 'CompTheory', 'A'), - // 'CS461': new Course('Advanced Machine Learning (M5)', 'AdvML', 'J'), - // 'CS452': new Course('Algorithmic Coding Theory (M5)', 'ACT', 'K'), - - /* Humanities */ - 'H209': new Course('Speculative Fiction (LH5)', 'Spec Fiction', 'K1'), - 'H225': new Course('Introduction to Psychology (LH5)', 'Psycho', 'K2'), - 'H235': new Course('Sociology of Science & Technology (LH4)', 'Socio', 'J2'), - 'H238': new Course('Life & Communication in Urban (LH4)', 'Urban', 'J1'), - - /* Mathematics */ - 'M201': new Course('Real Analysis (M1)', 'Real', 'A'), - 'M203': new Course('Discrete Mathematics (M1)', 'DM', 'B'), - 'M205': new Course('Linear Algebra (M1)', 'LinAl', 'D'), - - 'M302': new Course('Rings and Modules (M2)', 'R&M', 'A'), - 'M303': new Course('Differential Equation (M2)', 'DE', 'E'), - 'M305': new Course('Number Theory (M2)', 'NT', 'B'), - 'M306': new Course('Calculus of Several Variables (M2)', 'CSV', 'C'), - // 'M305': new Course('Statistics (M5)', 'Stats', 'B'), - - 'M401': new Course('Functional Analysis (M3)', 'FA', 'F'), - 'M405': new Course('Topology (M3)', 'Topology', 'D'), - 'M484': new Course('Commutative Algebra (M3)', 'CA', 'B'), - 'M479': new Course('Random Graphs (M3)', 'RG', 'C'), - 'M453': new Course('Advanced Linear Algebra (M3)', 'ALA', 'A'), - 'M476': new Course('Lie Algebras (M3)', 'LA', 'E'), - 'M478': new Course('Advanced Partial Differential Equations (M2)', 'APDE', 'D'), - // 'M466': new Course('Measure Theory (M5)', 'MT', 'A'), - // 'M464': new Course('Information and Coding Theory (M4)', 'ICT', 'G'), - // 'M459*': new Course('Statistics (M4)', 'Stat', 'B'), - // 'M458': new Course('Algebraic Number Theory (M4)', 'ANT', 'I'), - - // 'M562': new Course('Brownian Motion and Stochastic Calculus (M5)', 'BM&SC', 'H'), - // 'M556*': new Course('Lie Groups and Lie Algebra I (M4)', 'LG&LA', 'H'), - - /* Physics */ - 'P201': new Course('Classical Mechanics I (P127)', 'CM1', 'A'), - 'P202': new Course('Mathematical Methods I (P127)', 'MM1', 'C'), - 'P207': new Course('Linear Optics (P127)', 'Lin Optics', 'B'), - 'P245': new Course('Basic Electronics Theory and Lab (P127)', 'Electro Lab', 'F'), - - 'P302': new Course('Statistical Mechanics (P126)', 'StatMech', 'E'), - 'P303': new Course('Quantum Mechanics - II (P126)', 'QM2', 'D'), - 'P304': new Course('Special Theory of Relativity (P126)', 'STR', 'C'), - - 'P401': new Course('Classical Mechanics II: Mechanics of Continuous Media (P107)', 'CM2', 'F'), - 'P405': new Course('Atoms, molecules and Radiation (P107)', 'AMR', 'E'), - - 'P453': new Course('Quantum Field Theory I (P107)', 'QFT1', 'C'), - // 'P451': new Course('Advanced Solid State Physics (P107)', 'ASS', 'B'), - // 'P462': new Course('Introduction to Quantum Optics (P108)', 'IQO', 'C'), - // 'P473': new Course('Experimental Techniques (LH1)', 'ExpTech', 'A'), - // 'P474': new Course('Introduction to Cosmology (P127)', 'Cosmo', 'D'), - 'P460': new Course('Many-Particle Physics (P107)', 'Many Particle', 'D'), - 'P463': new Course('Astronomy and Astrophysics (P108)', 'Astro', 'D'), - 'P469': new Course('Density Functional Theory of Atoms, Molecules and Solids (P156)', 'DFT', 'A'), - 'P472': new Course('Experimental High Energy Physics (P126)', 'Expt HEP', 'B'), - 'P476': new Course('Non-Equilibrium Statistical Mechanics (P127)', 'NE StatMech', 'J'), - - /* CMRP */ - '11-PHYS26-511-C': new Course('Classical Mechanics (CL-001)', 'CM', 'A'), - '11-PHYS26-512-C': new Course('Statistical Mechanics and Thermodynamics (CL-001)', 'SM& Thermo', 'B'), - '11-PHYS26-513-C': new Course('Mathematical Physics (CL-001)', 'MP', 'C'), - '11-PHYS26-514-C': new Course('Electrodynamics (CL-001)', 'Electro', 'D'), - - 'R211': new Course('Radiation Physics and Radiation Generators (CL-002)', 'RadGen', 'A'), - 'R212': new Course('Radiological Mathematics (CL-002)', 'RadMath', 'B'), - 'R213': new Course('Radiation Dosimetry and Standardization (CL-002)', 'RadDosi', 'C'), - 'R214': new Course('Radiation Detectors and Instrumentation (CL-002)', 'RadDetec', 'D'), + // always use A1, A2, ... for degenerates of slot A + /* Biology */ + 'B201': new Course('Microbiology (B1)', 'MicroBio', 'A'), + 'B202': new Course('Biochemistry (B1)', 'Biochem', 'B'), + + 'B301': new Course('Animal Physiology (B2)', 'Animal Physio', 'B'), + 'B302': new Course('Plant Physiology (B2)', 'Plant Physio', 'C'), + 'B303': new Course('Ecology (LH3)', 'Ecology', 'A'), + 'B353': new Course('Plant Developmental Biology (B2)', 'Plant DevBio', 'E'), + 'B354': new Course('Neurobiology (B4)', 'Neuro', 'C'), + + 'B402': new Course('Developmental Biology (LH2)', 'DevBio', 'B'), + 'B405': new Course('Biotechniques (LH2)', 'Biotech', 'A'), + 'B406': new Course('Introductory Biophysics (LH3)', 'Biophys', 'C'), + 'B451': new Course('Advanced Cell Biology (B1)', 'Adv CellBio', 'D'), + 'B455': new Course('Enzymology (B5)', 'Enzymo', 'C'), + 'B466': new Course('Model organisms in Biomedical Research (B5)', 'BioMed', 'B'), + // 'B465': new Course('Structural Biology (B5)', 'StrBio', 'B'), + + 'B551': new Course('Advanced Molecular Biology (B3)', 'Adv MolBio', 'D'), + 'B552': new Course('Advanced Immunology (B4)', 'Adv Immuno', 'A'), + 'B555': new Course('Advanced Genetics (B6)', 'Adv Genetics', 'B'), + + /* Chemistry */ + 'C201': new Course('Basic Inorganic Chemistry (C6)', 'Inorganic', 'D'), + 'C203': new Course('Reaction Mechanism in Organic Chemistry (C6)', 'Organic', 'E'), + 'C207': new Course('Mathematical Methods for Chemists (LH4)', 'MMC', 'C'), + + 'C301': new Course('Physical Organic Chemistry (C1)', 'POC', 'D'), + 'C302': new Course('Molecular Spectroscopy and Group Theory (C5)', 'MolSpec', 'B'), + 'C307': new Course('Thermodynamics and Electrochemistry (LH4)', 'Thermo', 'F'), + + 'C401': new Course('Physical Methods in Chemistry-II (C4)', 'PMC2', 'B'), + 'C403': new Course('Chemistry of Heterocycles and Natural Products (C5)', 'Hetero cycles', 'E'), + + // 'C552': new Course('Solid State Chemistry (LH4)', 'SSC', 'C'), + // 'C557': new Course('Nuclear Magnetic Resonance (C5)', 'NMR', 'A'), + 'C560': new Course('Chemistry of Nanomaterials (C6)', 'Nano', 'A'), + 'C568': new Course('Advanced Fluorescence Spectroscopy (LH1)', 'Fluoro Spec', 'A'), + 'C572': new Course('Frontiers in Organic Synthesis (C2)', 'OrgSynth', 'B'), + + /* Computer Science */ + 'CS201': new Course('Theory of Computation (M1)', 'ToC', 'J'), + 'CS301': new Course('Design and Analysis of Algorithm (M4)', 'DAA', 'K'), + 'CS452': new Course('Algorithmic Coding Theory (M4)', 'AlgoCode', 'B'), + 'CS425': new Course('Randomized Algorithms (M5)', 'RA', 'K'), + 'CS453': new Course('Complexity Theory (M5)', 'CompTheory', 'A'), + // 'CS461': new Course('Advanced Machine Learning (M5)', 'AdvML', 'J'), + // 'CS452': new Course('Algorithmic Coding Theory (M5)', 'ACT', 'K'), + + /* Humanities */ + 'H209': new Course('Speculative Fiction (LH5)', 'Spec Fiction', 'K1'), + 'H225': new Course('Introduction to Psychology (LH5)', 'Psycho', 'K2'), + 'H235': new Course('Sociology of Science & Technology (LH4)', 'Socio', 'J2'), + 'H238': new Course('Life & Communication in Urban (LH4)', 'Urban', 'J1'), + + /* Mathematics */ + 'M201': new Course('Real Analysis (M1)', 'Real', 'A'), + 'M203': new Course('Discrete Mathematics (M1)', 'DM', 'B'), + 'M205': new Course('Linear Algebra (M1)', 'LinAl', 'D'), + + 'M302': new Course('Rings and Modules (M2)', 'R&M', 'A'), + 'M303': new Course('Differential Equation (M2)', 'DE', 'E'), + 'M305': new Course('Number Theory (M2)', 'NT', 'B'), + 'M306': new Course('Calculus of Several Variables (M2)', 'CSV', 'C'), + // 'M305': new Course('Statistics (M5)', 'Stats', 'B'), + + 'M401': new Course('Functional Analysis (M3)', 'FA', 'F'), + 'M405': new Course('Topology (M3)', 'Topology', 'D'), + 'M484': new Course('Commutative Algebra (M3)', 'CA', 'B'), + 'M479': new Course('Random Graphs (M3)', 'RG', 'C'), + 'M453': new Course('Advanced Linear Algebra (M3)', 'ALA', 'A'), + 'M476': new Course('Lie Algebras (M3)', 'LA', 'E'), + 'M478': new Course('Advanced Partial Differential Equations (M2)', 'APDE', 'D'), + // 'M466': new Course('Measure Theory (M5)', 'MT', 'A'), + // 'M464': new Course('Information and Coding Theory (M4)', 'ICT', 'G'), + // 'M459*': new Course('Statistics (M4)', 'Stat', 'B'), + // 'M458': new Course('Algebraic Number Theory (M4)', 'ANT', 'I'), + + // 'M562': new Course('Brownian Motion and Stochastic Calculus (M5)', 'BM&SC', 'H'), + // 'M556*': new Course('Lie Groups and Lie Algebra I (M4)', 'LG&LA', 'H'), + + /* Physics */ + 'P201': new Course('Classical Mechanics I (P127)', 'CM1', 'A'), + 'P202': new Course('Mathematical Methods I (P127)', 'MM1', 'C'), + 'P207': new Course('Linear Optics (P127)', 'Lin Optics', 'B'), + 'P245': new Course('Basic Electronics Theory and Lab (P127)', 'Electro Lab', 'F'), + + 'P302': new Course('Statistical Mechanics (P126)', 'StatMech', 'E'), + 'P303': new Course('Quantum Mechanics - II (P126)', 'QM2', 'D'), + 'P304': new Course('Special Theory of Relativity (P126)', 'STR', 'C'), + + 'P401': new Course('Classical Mechanics II: Mechanics of Continuous Media (P107)', 'CM2', 'F'), + 'P405': new Course('Atoms, molecules and Radiation (P107)', 'AMR', 'E'), + + 'P453': new Course('Quantum Field Theory I (P107)', 'QFT1', 'C'), + // 'P451': new Course('Advanced Solid State Physics (P107)', 'ASS', 'B'), + // 'P462': new Course('Introduction to Quantum Optics (P108)', 'IQO', 'C'), + // 'P473': new Course('Experimental Techniques (LH1)', 'ExpTech', 'A'), + // 'P474': new Course('Introduction to Cosmology (P127)', 'Cosmo', 'D'), + 'P460': new Course('Many-Particle Physics (P107)', 'Many Particle', 'D'), + 'P463': new Course('Astronomy and Astrophysics (P108)', 'Astro', 'D'), + 'P469': new Course('Density Functional Theory of Atoms, Molecules and Solids (P156)', 'DFT', 'A'), + 'P472': new Course('Experimental High Energy Physics (P126)', 'Expt HEP', 'B'), + 'P476': new Course('Non-Equilibrium Statistical Mechanics (P127)', 'NE StatMech', 'J'), + + /* CMRP */ + '11-PHYS26-511-C': new Course('Classical Mechanics (CL-001)', 'CM', 'A'), + '11-PHYS26-512-C': new Course('Statistical Mechanics and Thermodynamics (CL-001)', 'SM& Thermo', 'B'), + '11-PHYS26-513-C': new Course('Mathematical Physics (CL-001)', 'MP', 'C'), + '11-PHYS26-514-C': new Course('Electrodynamics (CL-001)', 'Electro', 'D'), + + 'R211': new Course('Radiation Physics and Radiation Generators (CL-002)', 'RadGen', 'A'), + 'R212': new Course('Radiological Mathematics (CL-002)', 'RadMath', 'B'), + 'R213': new Course('Radiation Dosimetry and Standardization (CL-002)', 'RadDosi', 'C'), + 'R214': new Course('Radiation Detectors and Instrumentation (CL-002)', 'RadDetec', 'D'), }; for (let course in courses) { - for (let school in schools) { - if (schools[school].code === course.match(/^[^0-9]*/)[0]) { - schools[school].courses.push(course); - } - } + for (let school in schools) { + if (schools[school].code === course.match(/^[^0-9]*/)[0]) { + schools[school].courses.push(course); + } + } } // Colorblindness-friendly color palette from: https://davidmathlogic.com/colorblind/ let colors = [ - '#117733', - '#44aa99', - '#d55e00', - '#88ccee', - '#0072b2', - '#ddcc77', - '#cc6677', - '#aa4499', - '#882255', - '#e69f00' + '#117733', + '#44aa99', + '#d55e00', + '#88ccee', + '#0072b2', + '#ddcc77', + '#cc6677', + '#aa4499', + '#882255', + '#e69f00' ]; + + +// let colors = [ +// "#1f77b4", // tab:blue +// "#ff7f0e", // tab:orange +// "#2ca02c", // tab:green +// "#d62728", // tab:red +// "#9467bd", // tab:purple +// "#8c564b", // tab:brown +// "#e377c2", // tab:pink +// "#7f7f7f", // tab:gray +// "#bcbd22", // tab:olive +// "#17becf", // tab:cyan +// ] + +let slots = { // only used for ICS generation + 'A': [ + ["Monday", "08:30 am", "09:30 am"], + ["Tuesday", "9:30 am", "10:30 am"], + ["Wednesday", "10:30 am", "11:30 am"], + ["Thursday", "11:30 am", "12:30 pm"], + ], + 'B': [ + ["Monday", "09:30 am", "10:30 am"], + ["Tuesday", "10:30 am", "11:30 am"], + ["Wednesday", "11:30 am", "12:30 pm"], + ["Thursday", "01:30 pm", "02:30 pm"], + ], + 'C': [ + ["Monday", "10:30 am", "11:30 am"], + ["Tuesday", "11:30 am", "12:30 pm"], + ["Wednesday", "01:30 pm", "02:30 pm"], + ["Friday", "08:30 am", "09:30 am"], + ], + 'D': [ + ["Monday", "11:30 am", "12:30 pm"], + ["Tuesday", "01:30 pm", "02:30 pm"], + ["Thursday", "08:30 am", "09:30 am"], + ["Friday", "09:30 am", "10:30 am"], + ], + 'E': [ + ["Monday", "01:30 pm", "02:30 pm"], + ["Wednesday", "08:30 am", "09:30 am"], + ["Thursday", "09:30 am", "10:30 am"], + ["Friday", "10:30 am", "11:30 am"], + ], + 'F': [ + ["Tuesday", "08:30 am", "09:30 am"], + ["Wednesday", "09:30 am", "10:30 am"], + ["Thursday", "10:30 am", "11:30 am"], + ["Friday", "11:30 am", "12:30 pm"], + ], + 'G': [ + ["Monday", "02:30 pm", "03:30 pm"], + ["Tuesday", "02:30 pm", "03:30 pm"], + ["Wednesday", "02:30 pm", "03:30 pm"], + ["Thursday", "02:30 pm", "03:30 pm"], + ], + 'H': [ + ["Monday", "03:30 pm", "04:30 pm"], + ["Tuesday", "03:30 pm", "04:30 pm"], + ["Wednesday", "03:30 pm", "04:30 pm"], + ["Thursday", "03:30 pm", "04:30 pm"], + ], + 'I': [ + ["Monday", "04:30 pm", "05:30 pm"], + ["Tuesday", "04:30 pm", "05:30 pm"], + ["Wednesday", "04:30 pm", "05:30 pm"], + ["Thursday", "04:30 pm", "05:30 pm"], + ], + 'J': [ + ["Monday", "05:30 pm", "06:30 pm"], + ["Tuesday", "06:30 pm", "07:30 pm"], + ["Wednesday", "05:30 pm", "06:30 pm"], + ["Thursday", "06:30 pm", "07:30 pm"], + ], + 'K': [ + ["Monday", "04:30 pm", "05:30 pm"], + ["Tuesday", "06:30 pm", "07:30 pm"], + ["Wednesday", "04:30 pm", "05:30 pm"], + ["Thursday", "06:30 pm", "07:30 pm"], + ], + 'J1': [ + ["Monday", "05:30 pm", "06:30 pm"], + ["Wednesday", "05:30 pm", "06:30 pm"], + ], + 'J2': [ + ["Tuesday", "06:30 pm", "07:30 pm"], + ["Thursday", "06:30 pm", "07:30 pm"], + + ], + 'K1': [ + ["Monday", "04:30 pm", "05:30 pm"], + ["Wednesday", "04:30 pm", "05:30 pm"], + ], + 'K2': [ + ["Tuesday", "06:30 pm", "07:30 pm"], + ["Thursday", "06:30 pm", "07:30 pm"], + ], +} + + +const startdate = new Date(); \ No newline at end of file diff --git a/scripts/data_fall.js b/scripts/data_fall.js index 63fb7ac..abd6126 100644 --- a/scripts/data_fall.js +++ b/scripts/data_fall.js @@ -2,168 +2,271 @@ let year = '2024'; let semester = 'Fall'; function School(code, name, courses) { - this.code = code; - this.name = name; - this.courses = courses; + this.code = code; + this.name = name; + this.courses = courses; } function short_name(school) { - return school.name.split(' ').slice(2).join(' ') + return school.name.split(' ').slice(2).join(' ') } function Course(name, nick, slot) { - this.name = name; - this.nick = nick; - this.slot = slot; + this.name = name; + this.nick = nick; + this.slot = slot; } let schools = { - 'SCS': new School('C', 'School of Chemical Sciences', []), - 'SBS': new School('B', 'School of Biological Sciences', []), - 'SPS': new School('P', 'School of Physical Sciences', []), - 'SMS': new School('M', 'School of Mathematical Sciences', []), - 'SCPS': new School('CS', 'School of Computer Sciences', []), - 'SHSS': new School('H', 'School of Humanities and Social Sciences', []), - 'CMRP': new School('R', 'Center for Medical and Radiation Physics', []), + 'SCS': new School('C', 'School of Chemical Sciences', []), + 'SBS': new School('B', 'School of Biological Sciences', []), + 'SPS': new School('P', 'School of Physical Sciences', []), + 'SMS': new School('M', 'School of Mathematical Sciences', []), + 'SCPS': new School('CS', 'School of Computer Sciences', []), + 'SHSS': new School('H', 'School of Humanities and Social Sciences', []), + 'CMRP': new School('R', 'Center for Medical and Radiation Physics', []), }; let courses = { - // always use A1, A2, ... for degenerates of slot A - /* Biology */ - 'B201': new Course('Microbiology (B1)', 'MicroBio', 'A'), - 'B202': new Course('Biochemistry (B1)', 'Biochem', 'B'), - - 'B301': new Course('Animal Physiology (B2)', 'Animal Physio', 'B'), - 'B302': new Course('Plant Physiology (B2)', 'Plant Physio', 'C'), - 'B303': new Course('Ecology (LH3)', 'Ecology', 'A'), - 'B353': new Course('Plant Developmental Biology (B2)', 'Plant DevBio', 'E'), - 'B354': new Course('Neurobiology (B4)', 'Neuro', 'C'), - - 'B402': new Course('Developmental Biology (LH2)', 'DevBio', 'B'), - 'B405': new Course('Biotechniques (LH2)', 'Biotech', 'A'), - 'B406': new Course('Introductory Biophysics (LH3)', 'Biophys', 'C'), - 'B451': new Course('Advanced Cell Biology (B1)', 'Adv CellBio', 'D'), - 'B455': new Course('Enzymology (B5)', 'Enzymo', 'C'), - 'B466': new Course('Model organisms in Biomedical Research (B5)','BioMed','B'), - // 'B465': new Course('Structural Biology (B5)', 'StrBio', 'B'), - - 'B551': new Course('Advanced Molecular Biology (B3)', 'Adv MolBio', 'D'), - 'B552': new Course('Advanced Immunology (B4)', 'Adv Immuno', 'A'), - 'B555': new Course('Advanced Genetics (B6)', 'Adv Genetics', 'B'), - - /* Chemistry */ - 'C201': new Course('Basic Inorganic Chemistry (C6)', 'Inorganic', 'D'), - 'C203': new Course('Reaction Mechanism in Organic Chemistry (LH4)', 'Organic', 'C'), - 'C207': new Course('Mathematical Methods for Chemists (C6)', 'MMC', 'E'), - - 'C301': new Course('Physical Organic Chemistry (C1)', 'POC', 'D'), - 'C302': new Course('Molecular Spectroscopy and Group Theory (C5)', 'MolSpec', 'B'), - 'C307': new Course('Thermodynamics and Electrochemistry (LH4)', 'Thermo', 'A'), - - 'C401': new Course('Physical Methods in Chemsitry-II (C4)', 'PMC2', 'B'), - 'C403': new Course('Chemistry of Heterocycles and Natural Products (C5)', 'Hetero cycles', 'E'), - - // 'C552': new Course('Solid State Chemistry (LH4)', 'SSC', 'C'), - // 'C557': new Course('Nuclear Magnetic Resonance (C5)', 'NMR', 'A'), - 'C560': new Course('Chemistry of Nanomaterials (C6)', 'Nano', 'A'), - 'C568': new Course('Advanced Fluoroscence Spectroscopy (LH1)', 'Fluoro Spec', 'A'), - 'C572': new Course('Frontiers in Organic Synthesis (C2)', 'OrgSynth', 'B'), - - /* Computer Science */ - 'CS201': new Course('Theory of Computation (M1)', 'ToC', 'J'), - 'CS301': new Course('Design and Analysis of Algorithm (M4)', 'DAA', 'K'), - 'CS452': new Course('Algorithmic Coding Theory (M4)', 'AlgoCode', 'B'), - 'CS425': new Course('Randomized Algorithms (M5)', 'RA', 'K'), - 'CS453': new Course('Compexity Theory (M5)', 'CompTheory', 'A'), - // 'CS461': new Course('Advanced Machine Learning (M5)', 'AdvML', 'J'), - // 'CS452': new Course('Algorithmic Coding Theory (M5)', 'ACT', 'K'), - - /* Humanities */ - 'H209': new Course('Speculative Fiction (LH5)', 'Spec Fiction', 'K1'), - 'H225': new Course('Introduction to Psychology (LH5)', 'Psycho', 'K2'), - 'H235': new Course('Sociology of Science & Technology (LH4)', 'Socio', 'J2'), - 'H238': new Course('Life & Communication in Urban (LH4)', 'Urban', 'J1'), - - /* Mathematics */ - 'M201': new Course('Real Analysis (M1)', 'Real', 'A'), - 'M203': new Course('Discrete Mathematics (M1)', 'DM', 'B'), - 'M205': new Course('Linear Algebra (M1)', 'LinAl', 'C'), - - 'M302': new Course('Rings and Modules (M2)', 'R&M', 'A'), - 'M303': new Course('Differential Equation (M2)', 'DE', 'E'), - 'M305': new Course('Number Theory (M2)', 'NT', 'B'), - 'M306': new Course('Calculus of Several Variables (M2)', 'CSV', 'C'), - // 'M305': new Course('Statistics (M5)', 'Stats', 'B'), - - 'M401': new Course('Functional Analysis (M3)', 'FA', 'F'), - 'M405': new Course('Topology (M3)', 'Topology', 'D'), - 'M484': new Course('Commutative Algebra (M3)', 'CA', 'B'), - 'M479': new Course('Random Graphs (M3)', 'RG', 'C'), - 'M453': new Course('Advanced Linear Algebra (M3)', 'ALA', 'A'), - 'M476': new Course('Lie Algebras (M3)', 'LA', 'E'), - 'M478': new Course('Advanced Partial Differential Equations (M2)', 'APDE', 'D'), - // 'M466': new Course('Measure Theory (M5)', 'MT', 'A'), - // 'M464': new Course('Information and Coding Theory (M4)', 'ICT', 'G'), - // 'M459*': new Course('Statistics (M4)', 'Stat', 'B'), - // 'M458': new Course('Algebraic Number Theory (M4)', 'ANT', 'I'), - - // 'M562': new Course('Brownian Motion and Stochastic Calculus (M5)', 'BM&SC', 'H'), - // 'M556*': new Course('Lie Groups and Lie Algebra I (M4)', 'LG&LA', 'H'), - - /* Physics */ - 'P201': new Course('Classical Mechanics I (P127)', 'CM1', 'A'), - 'P202': new Course('Mathematical Methods I (P127)', 'MM1', 'C'), - 'P207': new Course('Linear Optics (P127)', 'Lin Optics', 'B'), - 'P245': new Course('Basic Electronics Theory and Lab (P127)', 'Electro Lab', 'D'), - - 'P302': new Course('Statistical Mechanics (P126)', 'StatMech', 'E'), - 'P303': new Course('Quantum Mechanics - II (P126)', 'QM2', 'D'), - 'P304': new Course('Special Theory of Relativity (P126)', 'STR', 'C'), - - 'P401': new Course('Classical Mechanics II: Mechanics of Continuous Media (P107)', 'CM2', 'F'), - 'P405': new Course('Atoms, molecules and Radiation (P107)', 'AMR', 'E'), - - 'P453': new Course('Quantum Field Theory I (P107)', 'QFT1', 'C'), - // 'P451': new Course('Advanced Solid State Physics (P107)', 'ASS', 'B'), - // 'P462': new Course('Introduction to Quantum Optics (P108)', 'IQO', 'C'), - // 'P473': new Course('Experimental Techniques (LH1)', 'ExpTech', 'A'), - // 'P474': new Course('Introduction to Cosmology (P127)', 'Cosmo', 'D'), - 'P460': new Course('Many Particle Physics (P126)', 'Many Particle', 'F'), - 'P463': new Course('Astronomy and Astrophysics (P127)', 'Astro', 'F'), - 'P469': new Course('Density Functional Theory of Atoms, Molecules and Solids (P156)', 'DFT', 'A'), - 'P472': new Course('Experimental High Energy Physics (P126)', 'Expt HEP', 'B'), - 'P476': new Course('Non-Equilibrium Statistical Mechanics (P127)', 'NE StatMech', 'D'), - - /* CMRP */ - '11-PHYS26-511-C': new Course('Classical Mechanics (CL-001)', 'CM', 'A'), - '11-PHYS26-512-C': new Course('Statistical Mechanics and Thermodynamics (CL-001)', 'SM& Thermo', 'B'), - '11-PHYS26-513-C': new Course('Mathematical Physics (CL-001)', 'MP', 'C'), - '11-PHYS26-514-C': new Course('Electrodynamics (CL-001)', 'Electro', 'D'), - - 'R211': new Course('Radiation Physics and Radiation Generators (CL-002)', 'RadGen', 'A'), - 'R212': new Course('Radiological Mathematics (CL-002)', 'RadMath', 'B'), - 'R213': new Course('Radiation Dosimetry and Standardization (CL-002)', 'RadDosi', 'C'), - 'R214': new Course('Radiation Detectors and Instrumentation (CL-002)', 'RadDetec', 'D'), + // always use A1, A2, ... for degenerates of slot A + /* Biology */ + 'B201': new Course('Microbiology (B1)', 'MicroBio', 'A'), + 'B202': new Course('Biochemistry (B1)', 'Biochem', 'B'), + + 'B301': new Course('Animal Physiology (B2)', 'Animal Physio', 'B'), + 'B302': new Course('Plant Physiology (B2)', 'Plant Physio', 'C'), + 'B303': new Course('Ecology (LH3)', 'Ecology', 'A'), + 'B353': new Course('Plant Developmental Biology (B2)', 'Plant DevBio', 'E'), + 'B354': new Course('Neurobiology (B4)', 'Neuro', 'C'), + + 'B402': new Course('Developmental Biology (LH2)', 'DevBio', 'B'), + 'B405': new Course('Biotechniques (LH2)', 'Biotech', 'A'), + 'B406': new Course('Introductory Biophysics (LH3)', 'Biophys', 'C'), + 'B451': new Course('Advanced Cell Biology (B1)', 'Adv CellBio', 'D'), + 'B455': new Course('Enzymology (B5)', 'Enzymo', 'C'), + 'B466': new Course('Model organisms in Biomedical Research (B5)','BioMed','B'), + // 'B465': new Course('Structural Biology (B5)', 'StrBio', 'B'), + + 'B551': new Course('Advanced Molecular Biology (B3)', 'Adv MolBio', 'D'), + 'B552': new Course('Advanced Immunology (B4)', 'Adv Immuno', 'A'), + 'B555': new Course('Advanced Genetics (B6)', 'Adv Genetics', 'B'), + + /* Chemistry */ + 'C201': new Course('Basic Inorganic Chemistry (C6)', 'Inorganic', 'D'), + 'C203': new Course('Reaction Mechanism in Organic Chemistry (LH4)', 'Organic', 'C'), + 'C207': new Course('Mathematical Methods for Chemists (C6)', 'MMC', 'E'), + + 'C301': new Course('Physical Organic Chemistry (C1)', 'POC', 'D'), + 'C302': new Course('Molecular Spectroscopy and Group Theory (C5)', 'MolSpec', 'B'), + 'C307': new Course('Thermodynamics and Electrochemistry (LH4)', 'Thermo', 'A'), + + 'C401': new Course('Physical Methods in Chemsitry-II (C4)', 'PMC2', 'B'), + 'C403': new Course('Chemistry of Heterocycles and Natural Products (C5)', 'Hetero cycles', 'E'), + + // 'C552': new Course('Solid State Chemistry (LH4)', 'SSC', 'C'), + // 'C557': new Course('Nuclear Magnetic Resonance (C5)', 'NMR', 'A'), + 'C560': new Course('Chemistry of Nanomaterials (C6)', 'Nano', 'A'), + 'C568': new Course('Advanced Fluoroscence Spectroscopy (LH1)', 'Fluoro Spec', 'A'), + 'C572': new Course('Frontiers in Organic Synthesis (C2)', 'OrgSynth', 'B'), + + /* Computer Science */ + 'CS201': new Course('Theory of Computation (M1)', 'ToC', 'J'), + 'CS301': new Course('Design and Analysis of Algorithm (M4)', 'DAA', 'K'), + 'CS452': new Course('Algorithmic Coding Theory (M4)', 'AlgoCode', 'B'), + 'CS425': new Course('Randomized Algorithms (M5)', 'RA', 'K'), + 'CS453': new Course('Compexity Theory (M5)', 'CompTheory', 'A'), + // 'CS461': new Course('Advanced Machine Learning (M5)', 'AdvML', 'J'), + // 'CS452': new Course('Algorithmic Coding Theory (M5)', 'ACT', 'K'), + + /* Humanities */ + 'H209': new Course('Speculative Fiction (LH5)', 'Spec Fiction', 'K1'), + 'H225': new Course('Introduction to Psychology (LH5)', 'Psycho', 'K2'), + 'H235': new Course('Sociology of Science & Technology (LH4)', 'Socio', 'J2'), + 'H238': new Course('Life & Communication in Urban (LH4)', 'Urban', 'J1'), + + /* Mathematics */ + 'M201': new Course('Real Analysis (M1)', 'Real', 'A'), + 'M203': new Course('Discrete Mathematics (M1)', 'DM', 'B'), + 'M205': new Course('Linear Algebra (M1)', 'LinAl', 'C'), + + 'M302': new Course('Rings and Modules (M2)', 'R&M', 'A'), + 'M303': new Course('Differential Equation (M2)', 'DE', 'E'), + 'M305': new Course('Number Theory (M2)', 'NT', 'B'), + 'M306': new Course('Calculus of Several Variables (M2)', 'CSV', 'C'), + // 'M305': new Course('Statistics (M5)', 'Stats', 'B'), + + 'M401': new Course('Functional Analysis (M3)', 'FA', 'F'), + 'M405': new Course('Topology (M3)', 'Topology', 'D'), + 'M484': new Course('Commutative Algebra (M3)', 'CA', 'B'), + 'M479': new Course('Random Graphs (M3)', 'RG', 'C'), + 'M453': new Course('Advanced Linear Algebra (M3)', 'ALA', 'A'), + 'M476': new Course('Lie Algebras (M3)', 'LA', 'E'), + 'M478': new Course('Advanced Partial Differential Equations (M2)', 'APDE', 'D'), + // 'M466': new Course('Measure Theory (M5)', 'MT', 'A'), + // 'M464': new Course('Information and Coding Theory (M4)', 'ICT', 'G'), + // 'M459*': new Course('Statistics (M4)', 'Stat', 'B'), + // 'M458': new Course('Algebraic Number Theory (M4)', 'ANT', 'I'), + + // 'M562': new Course('Brownian Motion and Stochastic Calculus (M5)', 'BM&SC', 'H'), + // 'M556*': new Course('Lie Groups and Lie Algebra I (M4)', 'LG&LA', 'H'), + + /* Physics */ + 'P201': new Course('Classical Mechanics I (P127)', 'CM1', 'A'), + 'P202': new Course('Mathematical Methods I (P127)', 'MM1', 'C'), + 'P207': new Course('Linear Optics (P127)', 'Lin Optics', 'B'), + 'P245': new Course('Basic Electronics Theory and Lab (P127)', 'Electro Lab', 'D'), + + 'P302': new Course('Statistical Mechanics (P126)', 'StatMech', 'E'), + 'P303': new Course('Quantum Mechanics - II (P126)', 'QM2', 'D'), + 'P304': new Course('Special Theory of Relativity (P126)', 'STR', 'C'), + + 'P401': new Course('Classical Mechanics II: Mechanics of Continuous Media (P107)', 'CM2', 'F'), + 'P405': new Course('Atoms, molecules and Radiation (P107)', 'AMR', 'E'), + + 'P453': new Course('Quantum Field Theory I (P107)', 'QFT1', 'C'), + // 'P451': new Course('Advanced Solid State Physics (P107)', 'ASS', 'B'), + // 'P462': new Course('Introduction to Quantum Optics (P108)', 'IQO', 'C'), + // 'P473': new Course('Experimental Techniques (LH1)', 'ExpTech', 'A'), + // 'P474': new Course('Introduction to Cosmology (P127)', 'Cosmo', 'D'), + 'P460': new Course('Many Particle Physics (P126)', 'Many Particle', 'F'), + 'P463': new Course('Astronomy and Astrophysics (P127)', 'Astro', 'F'), + 'P469': new Course('Density Functional Theory of Atoms, Molecules and Solids (P156)', 'DFT', 'A'), + 'P472': new Course('Experimental High Energy Physics (P126)', 'Expt HEP', 'B'), + 'P476': new Course('Non-Equilibrium Statistical Mechanics (P127)', 'NE StatMech', 'D'), + + /* CMRP */ + '11-PHYS26-511-C': new Course('Classical Mechanics (CL-001)', 'CM', 'A'), + '11-PHYS26-512-C': new Course('Statistical Mechanics and Thermodynamics (CL-001)', 'SM& Thermo', 'B'), + '11-PHYS26-513-C': new Course('Mathematical Physics (CL-001)', 'MP', 'C'), + '11-PHYS26-514-C': new Course('Electrodynamics (CL-001)', 'Electro', 'D'), + + 'R211': new Course('Radiation Physics and Radiation Generators (CL-002)', 'RadGen', 'A'), + 'R212': new Course('Radiological Mathematics (CL-002)', 'RadMath', 'B'), + 'R213': new Course('Radiation Dosimetry and Standardization (CL-002)', 'RadDosi', 'C'), + 'R214': new Course('Radiation Detectors and Instrumentation (CL-002)', 'RadDetec', 'D'), }; for (let course in courses) { - for (let school in schools) { - if (schools[school].code === course.match(/^[^0-9]*/)[0]) { - schools[school].courses.push(course); - } - } + for (let school in schools) { + if (schools[school].code === course.match(/^[^0-9]*/)[0]) { + schools[school].courses.push(course); + } + } } // Colorblindness-friendly color palette from: https://davidmathlogic.com/colorblind/ +// let colors = [ +// '#117733', +// '#44aa99', +// '#d55e00', +// '#88ccee', +// '#0072b2', +// '#ddcc77', +// '#cc6677', +// '#aa4499', +// '#882255', +// '#e69f00' +// ]; + + let colors = [ - '#117733', - '#44aa99', - '#d55e00', - '#88ccee', - '#0072b2', - '#ddcc77', - '#cc6677', - '#aa4499', - '#882255', - '#e69f00' -]; + "#1f77b4", // tab:blue + "#ff7f0e", // tab:orange + "#2ca02c", // tab:green + "#d62728", // tab:red + "#9467bd", // tab:purple + "#8c564b", // tab:brown + "#e377c2", // tab:pink + "#7f7f7f", // tab:gray + "#bcbd22", // tab:olive + "#17becf", // tab:cyan +] + +let slots = { // only used for ICS generation + 'A': [ + ["Monday", "08:30 am", "09:30 am"], + ["Tuesday", "9:30 am", "10:30 am"], + ["Wednesday", "10:30 am", "11:30 am"], + ["Thursday", "11:30 am", "12:30 pm"], + ], + 'B': [ + ["Monday", "09:30 am", "10:30 am"], + ["Tuesday", "10:30 am", "11:30 am"], + ["Wednesday", "11:30 am", "12:30 pm"], + ["Thursday", "01:30 pm", "02:30 pm"], + ], + 'C': [ + ["Monday", "10:30 am", "11:30 am"], + ["Tuesday", "11:30 am", "12:30 pm"], + ["Wednesday", "01:30 pm", "02:30 pm"], + ["Friday", "08:30 am", "09:30 am"], + ], + 'D': [ + ["Monday", "11:30 am", "12:30 pm"], + ["Tuesday", "01:30 pm", "02:30 pm"], + ["Thursday", "08:30 am", "09:30 am"], + ["Friday", "09:30 am", "10:30 am"], + ], + 'E': [ + ["Monday", "01:30 pm", "02:30 pm"], + ["Wednesday", "08:30 am", "09:30 am"], + ["Thursday", "09:30 am", "10:30 am"], + ["Friday", "10:30 am", "11:30 am"], + ], + 'F': [ + ["Tuesday", "08:30 am", "09:30 am"], + ["Wednesday", "09:30 am", "10:30 am"], + ["Thursday", "10:30 am", "11:30 am"], + ["Friday", "11:30 am", "12:30 pm"], + ], + 'G': [ + ["Monday", "02:30 pm", "03:30 pm"], + ["Tuesday", "02:30 pm", "03:30 pm"], + ["Wednesday", "02:30 pm", "03:30 pm"], + ["Thursday", "02:30 pm", "03:30 pm"], + ], + 'H': [ + ["Monday", "03:30 pm", "04:30 pm"], + ["Tuesday", "03:30 pm", "04:30 pm"], + ["Wednesday", "03:30 pm", "04:30 pm"], + ["Thursday", "03:30 pm", "04:30 pm"], + ], + 'I': [ + ["Monday", "04:30 pm", "05:30 pm"], + ["Tuesday", "04:30 pm", "05:30 pm"], + ["Wednesday", "04:30 pm", "05:30 pm"], + ["Thursday", "04:30 pm", "05:30 pm"], + ], + 'J': [ + ["Monday", "05:30 pm", "06:30 pm"], + ["Tuesday", "06:30 pm", "07:30 pm"], + ["Wednesday", "05:30 pm", "06:30 pm"], + ["Thursday", "06:30 pm", "07:30 pm"], + ], + 'K': [ + ["Monday", "04:30 pm", "05:30 pm"], + ["Tuesday", "06:30 pm", "07:30 pm"], + ["Wednesday", "04:30 pm", "05:30 pm"], + ["Thursday", "06:30 pm", "07:30 pm"], + ], + 'J1': [ + ["Monday", "05:30 pm", "06:30 pm"], + ["Wednesday", "05:30 pm", "06:30 pm"], + ], + 'J2': [ + ["Tuesday", "06:30 pm", "07:30 pm"], + ["Thursday", "06:30 pm", "07:30 pm"], + + ], + 'K1': [ + ["Monday", "04:30 pm", "05:30 pm"], + ["Wednesday", "04:30 pm", "05:30 pm"], + ], + 'K2': [ + ["Tuesday", "06:30 pm", "07:30 pm"], + ["Thursday", "06:30 pm", "07:30 pm"], + ], +} + + +const startdate = new Date(); diff --git a/scripts/data_spring.js b/scripts/data_spring.js index 9716337..79e848e 100644 --- a/scripts/data_spring.js +++ b/scripts/data_spring.js @@ -2,140 +2,243 @@ let year = '2024'; let semester = 'Spring'; function School(code, name, courses) { - this.code = code; - this.name = name; - this.courses = courses; + this.code = code; + this.name = name; + this.courses = courses; } function short_name(school) { - return school.name.split(' ').slice(2).join(' ') + return school.name.split(' ').slice(2).join(' ') } function Course(name, nick, slot) { - this.name = name; - this.nick = nick; - this.slot = slot; + this.name = name; + this.nick = nick; + this.slot = slot; } let schools = { - 'SCS': new School('C', 'School of Chemical Sciences', []), - 'SBS': new School('B', 'School of Biological Sciences', []), - 'SPS': new School('P', 'School of Physical Sciences', []), - 'SMS': new School('M', 'School of Mathematical Sciences', []), - 'SCPS': new School('CS', 'School of Computer Sciences', []), - 'SHSS': new School('H', 'School of Humanities and Social Sciences', []), - 'CMRP': new School('R', 'Center for Medical and Radiation Physics', []), + 'SCS': new School('C', 'School of Chemical Sciences', []), + 'SBS': new School('B', 'School of Biological Sciences', []), + 'SPS': new School('P', 'School of Physical Sciences', []), + 'SMS': new School('M', 'School of Mathematical Sciences', []), + 'SCPS': new School('CS', 'School of Computer Sciences', []), + 'SHSS': new School('H', 'School of Humanities and Social Sciences', []), + 'CMRP': new School('R', 'Center for Medical and Radiation Physics', []), }; let courses = { - // always use A1, A2, ... for degenerates of slot A - /* Biology */ - 'B204': new Course('Cell Biology (LH3)', 'CellBio', 'C'), - 'B206': new Course('Moleclar Biology (B4)', 'MolBio', 'E'), - - 'B305': new Course('Immunology (LH2)', 'Immuno', 'D'), - 'B306': new Course('Evolutionary Biology (LH2)', 'EvoBio', 'F'), - 'B307': new Course('Genetics (LH2)', 'Gene', 'B'), - - 'B403': new Course('Bioinformatics and Computational Biology (LH2)', 'BioInfo', 'A'), - 'B407': new Course('Quantitative and Systems Biology (LH2)', 'SysBio', 'C'), - 'B453': new Course('Advanced Biochemistry (B5)', 'AdvBiochem', 'B'), - 'B454': new Course('Advanced Microbiology (B5)', 'AdvMicroBio', 'F'), - 'B462': new Course('Endocrinology (B6)', 'Endo', 'E'), - 'B463': new Course('Plant Developmental Biology (B5)', 'PlantDevBio', 'D'), - - 'B554': new Course('Cancer Biology (B3)', 'Cancer', 'B'), - - /* Chemistry */ - 'C204': new Course('Reagents in Organic Syntheses (LH3)', 'Organic', 'D'), - 'C205': new Course('Main Group and Organometallic Chemistry (C7)', 'Inorganic', 'A'), - 'C206': new Course('Quantum Chemistry - I (LH3)', 'QC1', 'F'), - - 'C304': new Course('Coordination Chemistry (LH3)', 'CoordChem', 'A'), - 'C305': new Course('Chemical Binding (LH4)', 'ChemBind', 'B'), - 'C306': new Course('Physical Methods in Chemistry - I (LH3)', 'PMC', 'E'), - - 'C402': new Course('Chemical Rate Processes (LH4)', 'ChemRate', 'D'), - - 'C554': new Course('Crystallography (C2)', 'Crystallo', 'B'), - 'C556': new Course('Advanced Bio-Inorganic Chemistry (LH1)', 'BioInorgChem', 'F'), - 'C559': new Course('Supramolecular Chemistry (C3)', 'Supra', 'A'), - 'C565': new Course('Advanced Organic Chemistry (C4)', 'AdvOrgChem', 'C'), - 'C566': new Course('Catalysis: Reaction Mechanism and Applications (LH1)', 'Catalysis', 'C'), - - /* Computer Science */ - 'CS202': new Course('Discrete Structures and Computation (M1)', 'DSC', 'E'), - 'CS457': new Course('Paramterized Algorihms (M3)', 'ML', 'F'), - 'CS460': new Course('Machine Learning (M4)', 'ML', 'E'), - - /* Humanities */ - 'H227': new Course('Organisational Behaviour (LH4)', 'OB', 'J'), - 'H205': new Course('Environmental Economics and Environmental Impact Assessment (LH3)', 'EnvEco', 'K2'), - 'H210': new Course('The City in Modern Fiction (LH3)', 'ModFiction', 'K1'), - - /* Mathematics */ - 'M202': new Course('Group Theory (M2)', 'GrpTheory', 'E'), - 'M204': new Course('Metric Spaces (M2)', 'MetSpace', 'F'), - 'M206': new Course('Probability Theory (M2)', 'PT', 'A'), - - 'M301': new Course('Lebesque Integration (M5)', 'LI', 'B'), - 'M307': new Course('Field Theory (M5)', 'FT', 'E'), - 'M308': new Course('Complex Analysis (M5)', 'CA', 'C'), - 'M309': new Course('Graph Theory (M5)', 'GraphTheo', 'D'), - - 'M402': new Course('Representations of Finite Groups (M2)', 'FG', 'B'), - 'M404': new Course('Algebraic Topology (M1)', 'AT', 'E'), - 'M406': new Course('Geometry of Curves and Surfaces (M1)', 'C&S', 'D'), - 'M451': new Course('Advanced Complex Analysis (M3)', 'ACA', 'B'), - 'M454': new Course('Partial Differential Equation (M3)', 'PDE', 'C'), - 'M457': new Course('Algebraic Graph Theory (M3)', 'AGT', 'F'), - 'M475': new Course('Incidence Geometry (M4)', 'IG', 'A'), - 'M485': new Course('Algebraic Topology (M1)', 'AT', 'E'), - - 'M555': new Course('Harmonic Analysis (M2)', 'HA', 'D'), - 'M557': new Course('Operator Algebras (M3)', 'OA', 'E'), - - /* Physics */ - 'P204': new Course('Electromagnetism I (P126)', 'EM1', 'C'), - 'P205': new Course('Mathematical Methods II (P126)', 'MM2', 'D'), - 'P206': new Course('Quantum Mechanics - I (P127)', 'QM1', 'B'), - - 'P301': new Course('Electromagnetism - II (P107)', 'EM2', 'C'), - 'P306': new Course('Introdution to Condensed Matter Physics (P127)', 'CMP', 'B'), - 'P307': new Course('Nuclei and Particles (LH3)', 'Nuclei', 'A'), - - 'P452': new Course('Computational Physics (LH1)', 'CompPhy', 'D'), - 'P456': new Course('Non-Linear Optics (P108)', 'NLO', 'B'), - 'P457': new Course('General Theory of Relativity and Cosmology (P108)', 'GTR', 'A'), - 'P464': new Course('Plasma Physics and Magnetohydrodynamics (P108)', 'PlasmaPhys', 'C'), - 'P470': new Course('Quantum Field Theory II (P109)', 'QFT2', 'C'), - 'P471': new Course('Quantum Information and Quantum Computation (P107)', 'QIQC', 'E'), - - /* CMRP */ - 'R121': new Course('Quantum Mechanics (CL-001)', 'QM', 'A'), - 'R122': new Course('Electronics and Instrumentation (CL-001)', 'E&I', 'B'), - 'R123': new Course('Solid State Physics (CL-001)', 'SSP', 'C'), - 'R124': new Course('Nuclear Physics (CL-001)', 'NP', 'D'), + // always use A1, A2, ... for degenerates of slot A + /* Biology */ + 'B204': new Course('Cell Biology (LH3)', 'CellBio', 'C'), + 'B206': new Course('Moleclar Biology (B4)', 'MolBio', 'E'), + + 'B305': new Course('Immunology (LH2)', 'Immuno', 'D'), + 'B306': new Course('Evolutionary Biology (LH2)', 'EvoBio', 'F'), + 'B307': new Course('Genetics (LH2)', 'Gene', 'B'), + + 'B403': new Course('Bioinformatics and Computational Biology (LH2)', 'BioInfo', 'A'), + 'B407': new Course('Quantitative and Systems Biology (LH2)', 'SysBio', 'C'), + 'B453': new Course('Advanced Biochemistry (B5)', 'AdvBiochem', 'B'), + 'B454': new Course('Advanced Microbiology (B5)', 'AdvMicroBio', 'F'), + 'B462': new Course('Endocrinology (B6)', 'Endo', 'E'), + 'B463': new Course('Plant Developmental Biology (B5)', 'PlantDevBio', 'D'), + + 'B554': new Course('Cancer Biology (B3)', 'Cancer', 'B'), + + /* Chemistry */ + 'C204': new Course('Reagents in Organic Syntheses (LH3)', 'Organic', 'D'), + 'C205': new Course('Main Group and Organometallic Chemistry (C7)', 'Inorganic', 'A'), + 'C206': new Course('Quantum Chemistry - I (LH3)', 'QC1', 'F'), + + 'C304': new Course('Coordination Chemistry (LH3)', 'CoordChem', 'A'), + 'C305': new Course('Chemical Binding (LH4)', 'ChemBind', 'B'), + 'C306': new Course('Physical Methods in Chemistry - I (LH3)', 'PMC', 'E'), + + 'C402': new Course('Chemical Rate Processes (LH4)', 'ChemRate', 'D'), + + 'C554': new Course('Crystallography (C2)', 'Crystallo', 'B'), + 'C556': new Course('Advanced Bio-Inorganic Chemistry (LH1)', 'BioInorgChem', 'F'), + 'C559': new Course('Supramolecular Chemistry (C3)', 'Supra', 'A'), + 'C565': new Course('Advanced Organic Chemistry (C4)', 'AdvOrgChem', 'C'), + 'C566': new Course('Catalysis: Reaction Mechanism and Applications (LH1)', 'Catalysis', 'C'), + + /* Computer Science */ + 'CS202': new Course('Discrete Structures and Computation (M1)', 'DSC', 'E'), + 'CS457': new Course('Paramterized Algorihms (M3)', 'ML', 'F'), + 'CS460': new Course('Machine Learning (M4)', 'ML', 'E'), + + /* Humanities */ + 'H227': new Course('Organisational Behaviour (LH4)', 'OB', 'J'), + 'H205': new Course('Environmental Economics and Environmental Impact Assessment (LH3)', 'EnvEco', 'K2'), + 'H210': new Course('The City in Modern Fiction (LH3)', 'ModFiction', 'K1'), + + /* Mathematics */ + 'M202': new Course('Group Theory (M2)', 'GrpTheory', 'E'), + 'M204': new Course('Metric Spaces (M2)', 'MetSpace', 'F'), + 'M206': new Course('Probability Theory (M2)', 'PT', 'A'), + + 'M301': new Course('Lebesque Integration (M5)', 'LI', 'B'), + 'M307': new Course('Field Theory (M5)', 'FT', 'E'), + 'M308': new Course('Complex Analysis (M5)', 'CA', 'C'), + 'M309': new Course('Graph Theory (M5)', 'GraphTheo', 'D'), + + 'M402': new Course('Representations of Finite Groups (M2)', 'FG', 'B'), + 'M404': new Course('Algebraic Topology (M1)', 'AT', 'E'), + 'M406': new Course('Geometry of Curves and Surfaces (M1)', 'C&S', 'D'), + 'M451': new Course('Advanced Complex Analysis (M3)', 'ACA', 'B'), + 'M454': new Course('Partial Differential Equation (M3)', 'PDE', 'C'), + 'M457': new Course('Algebraic Graph Theory (M3)', 'AGT', 'F'), + 'M475': new Course('Incidence Geometry (M4)', 'IG', 'A'), + 'M485': new Course('Algebraic Topology (M1)', 'AT', 'E'), + + 'M555': new Course('Harmonic Analysis (M2)', 'HA', 'D'), + 'M557': new Course('Operator Algebras (M3)', 'OA', 'E'), + + /* Physics */ + 'P204': new Course('Electromagnetism I (P126)', 'EM1', 'C'), + 'P205': new Course('Mathematical Methods II (P126)', 'MM2', 'D'), + 'P206': new Course('Quantum Mechanics - I (P127)', 'QM1', 'B'), + + 'P301': new Course('Electromagnetism - II (P107)', 'EM2', 'C'), + 'P306': new Course('Introdution to Condensed Matter Physics (P127)', 'CMP', 'B'), + 'P307': new Course('Nuclei and Particles (LH3)', 'Nuclei', 'A'), + + 'P452': new Course('Computational Physics (LH1)', 'CompPhy', 'D'), + 'P456': new Course('Non-Linear Optics (P108)', 'NLO', 'B'), + 'P457': new Course('General Theory of Relativity and Cosmology (P108)', 'GTR', 'A'), + 'P464': new Course('Plasma Physics and Magnetohydrodynamics (P108)', 'PlasmaPhys', 'C'), + 'P470': new Course('Quantum Field Theory II (P109)', 'QFT2', 'C'), + 'P471': new Course('Quantum Information and Quantum Computation (P107)', 'QIQC', 'E'), + + /* CMRP */ + 'R121': new Course('Quantum Mechanics (CL-001)', 'QM', 'A'), + 'R122': new Course('Electronics and Instrumentation (CL-001)', 'E&I', 'B'), + 'R123': new Course('Solid State Physics (CL-001)', 'SSP', 'C'), + 'R124': new Course('Nuclear Physics (CL-001)', 'NP', 'D'), }; for (let course in courses) { - for (let school in schools) { - if (schools[school].code === course.match(/^[^0-9]*/)[0]) { - schools[school].courses.push(course); - } - } + for (let school in schools) { + if (schools[school].code === course.match(/^[^0-9]*/)[0]) { + schools[school].courses.push(course); + } + } } // Colorblindness-friendly color palette from: https://davidmathlogic.com/colorblind/ +// let colors = [ +// '#117733', +// '#44aa99', +// '#d55e00', +// '#88ccee', +// '#0072b2', +// '#ddcc77', +// '#cc6677', +// '#aa4499', +// '#882255', +// '#e69f00' +// ]; + + let colors = [ - '#117733', - '#44aa99', - '#d55e00', - '#88ccee', - '#0072b2', - '#ddcc77', - '#cc6677', - '#aa4499', - '#882255', - '#e69f00' -]; + "#1f77b4", // tab:blue + "#ff7f0e", // tab:orange + "#2ca02c", // tab:green + "#d62728", // tab:red + "#9467bd", // tab:purple + "#8c564b", // tab:brown + "#e377c2", // tab:pink + "#7f7f7f", // tab:gray + "#bcbd22", // tab:olive + "#17becf", // tab:cyan +] + +let slots = { // only used for ICS generation + 'A': [ + ["Monday", "08:30 am", "09:30 am"], + ["Tuesday", "9:30 am", "10:30 am"], + ["Wednesday", "10:30 am", "11:30 am"], + ["Thursday", "11:30 am", "12:30 pm"], + ], + 'B': [ + ["Monday", "09:30 am", "10:30 am"], + ["Tuesday", "10:30 am", "11:30 am"], + ["Wednesday", "11:30 am", "12:30 pm"], + ["Thursday", "01:30 pm", "02:30 pm"], + ], + 'C': [ + ["Monday", "10:30 am", "11:30 am"], + ["Tuesday", "11:30 am", "12:30 pm"], + ["Wednesday", "01:30 pm", "02:30 pm"], + ["Friday", "08:30 am", "09:30 am"], + ], + 'D': [ + ["Monday", "11:30 am", "12:30 pm"], + ["Tuesday", "01:30 pm", "02:30 pm"], + ["Thursday", "08:30 am", "09:30 am"], + ["Friday", "09:30 am", "10:30 am"], + ], + 'E': [ + ["Monday", "01:30 pm", "02:30 pm"], + ["Wednesday", "08:30 am", "09:30 am"], + ["Thursday", "09:30 am", "10:30 am"], + ["Friday", "10:30 am", "11:30 am"], + ], + 'F': [ + ["Tuesday", "08:30 am", "09:30 am"], + ["Wednesday", "09:30 am", "10:30 am"], + ["Thursday", "10:30 am", "11:30 am"], + ["Friday", "11:30 am", "12:30 pm"], + ], + 'G': [ + ["Monday", "02:30 pm", "03:30 pm"], + ["Tuesday", "02:30 pm", "03:30 pm"], + ["Wednesday", "02:30 pm", "03:30 pm"], + ["Thursday", "02:30 pm", "03:30 pm"], + ], + 'H': [ + ["Monday", "03:30 pm", "04:30 pm"], + ["Tuesday", "03:30 pm", "04:30 pm"], + ["Wednesday", "03:30 pm", "04:30 pm"], + ["Thursday", "03:30 pm", "04:30 pm"], + ], + 'I': [ + ["Monday", "04:30 pm", "05:30 pm"], + ["Tuesday", "04:30 pm", "05:30 pm"], + ["Wednesday", "04:30 pm", "05:30 pm"], + ["Thursday", "04:30 pm", "05:30 pm"], + ], + 'J': [ + ["Monday", "05:30 pm", "06:30 pm"], + ["Tuesday", "06:30 pm", "07:30 pm"], + ["Wednesday", "05:30 pm", "06:30 pm"], + ["Thursday", "06:30 pm", "07:30 pm"], + ], + 'K': [ + ["Monday", "04:30 pm", "05:30 pm"], + ["Tuesday", "06:30 pm", "07:30 pm"], + ["Wednesday", "04:30 pm", "05:30 pm"], + ["Thursday", "06:30 pm", "07:30 pm"], + ], + 'J1': [ + ["Monday", "05:30 pm", "06:30 pm"], + ["Wednesday", "05:30 pm", "06:30 pm"], + ], + 'J2': [ + ["Tuesday", "06:30 pm", "07:30 pm"], + ["Thursday", "06:30 pm", "07:30 pm"], + + ], + 'K1': [ + ["Monday", "04:30 pm", "05:30 pm"], + ["Wednesday", "04:30 pm", "05:30 pm"], + ], + 'K2': [ + ["Tuesday", "06:30 pm", "07:30 pm"], + ["Thursday", "06:30 pm", "07:30 pm"], + ], +} + + +const startdate = new Date(); diff --git a/scripts/ics.min.js b/scripts/ics.min.js new file mode 100644 index 0000000..07ba70a --- /dev/null +++ b/scripts/ics.min.js @@ -0,0 +1,4 @@ +/*! ics.js Wed Aug 20 2014 17:23:02 */ +var saveAs=saveAs||function(e){"use strict";if(typeof e==="undefined"||typeof navigator!=="undefined"&&/MSIE [1-9]\./.test(navigator.userAgent)){return}var t=e.document,n=function(){return e.URL||e.webkitURL||e},r=t.createElementNS("http://www.w3.org/1999/xhtml","a"),o="download"in r,a=function(e){var t=new MouseEvent("click");e.dispatchEvent(t)},i=/constructor/i.test(e.HTMLElement)||e.safari,f=/CriOS\/[\d]+/.test(navigator.userAgent),u=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},s="application/octet-stream",d=1e3*40,c=function(e){var t=function(){if(typeof e==="string"){n().revokeObjectURL(e)}else{e.remove()}};setTimeout(t,d)},l=function(e,t,n){t=[].concat(t);var r=t.length;while(r--){var o=e["on"+t[r]];if(typeof o==="function"){try{o.call(e,n||e)}catch(a){u(a)}}}},p=function(e){if(/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)){return new Blob([String.fromCharCode(65279),e],{type:e.type})}return e},v=function(t,u,d){if(!d){t=p(t)}var v=this,w=t.type,m=w===s,y,h=function(){l(v,"writestart progress write writeend".split(" "))},S=function(){if((f||m&&i)&&e.FileReader){var r=new FileReader;r.onloadend=function(){var t=f?r.result:r.result.replace(/^data:[^;]*;/,"data:attachment/file;");var n=e.open(t,"_blank");if(!n)e.location.href=t;t=undefined;v.readyState=v.DONE;h()};r.readAsDataURL(t);v.readyState=v.INIT;return}if(!y){y=n().createObjectURL(t)}if(m){e.location.href=y}else{var o=e.open(y,"_blank");if(!o){e.location.href=y}}v.readyState=v.DONE;h();c(y)};v.readyState=v.INIT;if(o){y=n().createObjectURL(t);setTimeout(function(){r.href=y;r.download=u;a(r);h();c(y);v.readyState=v.DONE});return}S()},w=v.prototype,m=function(e,t,n){return new v(e,t||e.name||"download",n)};if(typeof navigator!=="undefined"&&navigator.msSaveOrOpenBlob){return function(e,t,n){t=t||e.name||"download";if(!n){e=p(e)}return navigator.msSaveOrOpenBlob(e,t)}}w.abort=function(){};w.readyState=w.INIT=0;w.WRITING=1;w.DONE=2;w.error=w.onwritestart=w.onprogress=w.onwrite=w.onabort=w.onerror=w.onwriteend=null;return m}(typeof self!=="undefined"&&self||typeof window!=="undefined"&&window||this.content);if(typeof module!=="undefined"&&module.exports){module.exports.saveAs=saveAs}else if(typeof define!=="undefined"&&define!==null&&define.amd!==null){define("FileSaver.js",function(){return saveAs})} + +var ics=function(e,t){"use strict";{if(!(navigator.userAgent.indexOf("MSIE")>-1&&-1==navigator.userAgent.indexOf("MSIE 10"))){void 0===e&&(e="default"),void 0===t&&(t="Calendar");var r=-1!==navigator.appVersion.indexOf("Win")?"\r\n":"\n",n=[],i=["BEGIN:VCALENDAR","PRODID:"+t,"VERSION:2.0"].join(r),o=r+"END:VCALENDAR",a=["SU","MO","TU","WE","TH","FR","SA"];return{events:function(){return n},calendar:function(){return i+r+n.join(r)+o},addEvent:function(t,i,o,l,u,s){if(void 0===t||void 0===i||void 0===o||void 0===l||void 0===u)return!1;if(s&&!s.rrule){if("YEARLY"!==s.freq&&"MONTHLY"!==s.freq&&"WEEKLY"!==s.freq&&"DAILY"!==s.freq)throw"Recurrence rrule frequency must be provided and be one of the following: 'YEARLY', 'MONTHLY', 'WEEKLY', or 'DAILY'";if(s.until&&isNaN(Date.parse(s.until)))throw"Recurrence rrule 'until' must be a valid date string";if(s.interval&&isNaN(parseInt(s.interval)))throw"Recurrence rrule 'interval' must be an integer";if(s.count&&isNaN(parseInt(s.count)))throw"Recurrence rrule 'count' must be an integer";if(void 0!==s.byday){if("[object Array]"!==Object.prototype.toString.call(s.byday))throw"Recurrence rrule 'byday' must be an array";if(s.byday.length>7)throw"Recurrence rrule 'byday' array must not be longer than the 7 days in a week";s.byday=s.byday.filter(function(e,t){return s.byday.indexOf(e)==t});for(var c in s.byday)if(a.indexOf(s.byday[c])<0)throw"Recurrence rrule 'byday' values must include only the following: 'SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'"}}var g=new Date(l),d=new Date(u),f=new Date,S=("0000"+g.getFullYear().toString()).slice(-4),E=("00"+(g.getMonth()+1).toString()).slice(-2),v=("00"+g.getDate().toString()).slice(-2),y=("00"+g.getHours().toString()).slice(-2),A=("00"+g.getMinutes().toString()).slice(-2),T=("00"+g.getSeconds().toString()).slice(-2),b=("0000"+d.getFullYear().toString()).slice(-4),D=("00"+(d.getMonth()+1).toString()).slice(-2),N=("00"+d.getDate().toString()).slice(-2),h=("00"+d.getHours().toString()).slice(-2),I=("00"+d.getMinutes().toString()).slice(-2),R=("00"+d.getMinutes().toString()).slice(-2),M=("0000"+f.getFullYear().toString()).slice(-4),w=("00"+(f.getMonth()+1).toString()).slice(-2),L=("00"+f.getDate().toString()).slice(-2),O=("00"+f.getHours().toString()).slice(-2),p=("00"+f.getMinutes().toString()).slice(-2),Y=("00"+f.getMinutes().toString()).slice(-2),U="",V="";y+A+T+h+I+R!=0&&(U="T"+y+A+T,V="T"+h+I+R);var B,C=S+E+v+U,j=b+D+N+V,m=M+w+L+("T"+O+p+Y);if(s)if(s.rrule)B=s.rrule;else{if(B="rrule:FREQ="+s.freq,s.until){var x=new Date(Date.parse(s.until)).toISOString();B+=";UNTIL="+x.substring(0,x.length-13).replace(/[-]/g,"")+"000000Z"}s.interval&&(B+=";INTERVAL="+s.interval),s.count&&(B+=";COUNT="+s.count),s.byday&&s.byday.length>0&&(B+=";BYDAY="+s.byday.join(","))}(new Date).toISOString();var H=["BEGIN:VEVENT","UID:"+n.length+"@"+e,"CLASS:PUBLIC","DESCRIPTION:"+i,"DTSTAMP;VALUE=DATE-TIME:"+m,"DTSTART;VALUE=DATE-TIME:"+C,"DTEND;VALUE=DATE-TIME:"+j,"LOCATION:"+o,"SUMMARY;LANGUAGE=en-us:"+t,"TRANSP:TRANSPARENT","END:VEVENT"];return B&&H.splice(4,0,B),H=H.join(r),n.push(H),H},download:function(e,t){if(n.length<1)return!1;t=void 0!==t?t:".ics",e=void 0!==e?e:"calendar";var a,l=i+r+n.join(r)+o;if(-1===navigator.userAgent.indexOf("MSIE 10"))a=new Blob([l]);else{var u=new BlobBuilder;u.append(l),a=u.getBlob("text/x-vCalendar;charset="+document.characterSet)}return saveAs(a,e+t),l},build:function(){return!(n.length<1)&&i+r+n.join(r)+o}}}console.log("Unsupported Browser")}}; \ No newline at end of file diff --git a/scripts/main.js b/scripts/main.js index b9ed510..9c088cb 100644 --- a/scripts/main.js +++ b/scripts/main.js @@ -1,4 +1,3 @@ -let courseUl = document.querySelector('#course-list'); let schoolTabs = document.querySelector('#school-tabs'); let schoolList = document.querySelector('#school-list'); @@ -7,212 +6,278 @@ let occupiedSlotsGlob = []; /* Generating the DOM tree containing the schools * and the list of courses */ for (let school in schools) { - let schoolTab = document.createElement('button'); - schoolTab.textContent = school; - schoolTab.addEventListener('click', function() { - document.querySelectorAll('.school').forEach(function(b) { b.classList.add('hidden') }); - let schoolCourses = document.querySelector('#' + school); - schoolCourses.classList.remove('hidden'); - schoolCourses.classList.add('visible'); - }); - schoolTabs.appendChild(schoolTab); - - let schoolDiv = document.createElement('div'); - schoolDiv.classList.add('school'); - school !== 'SBS' ? schoolDiv.classList.add('hidden') : null; - schoolDiv.setAttribute('id', school); - - let schoolHeader = document.createElement('h3'); - schoolHeader.textContent = schools[school].name; - - let schoolUl = document.createElement('ul'); - schoolList.appendChild(schoolDiv); - schoolDiv.appendChild(schoolHeader); - schoolDiv.appendChild(schoolUl); - - schools[school].courses.forEach(function(course) { - let slot = courses[course].slot; - - let courseLabel = document.createElement('label'); - courseLabel.setAttribute('for', course); - courseLabel.textContent = course; - courseLabel.textContent += ": " + courses[course].name; - - let courseLi = document.createElement('li'); - courseLi.classList.add('course'); - - let courseCheckBox = document.createElement('input'); - courseCheckBox.setAttribute('type', 'checkbox'); - courseCheckBox.setAttribute('value', course); - courseCheckBox.setAttribute('id', course); - - schoolUl.appendChild(courseLi); - courseLi.appendChild(courseCheckBox); - courseLi.appendChild(courseLabel); - }); + + // Making the buttons for each school + let schoolTab = document.createElement('button'); + schoolTab.textContent = school; + schoolTab.addEventListener('click', function () { + document.querySelectorAll('.school').forEach(function (b) { b.classList.add('hidden') }); // Hide all schools + let schoolCourses = document.querySelector('#' + school); // get the selected school + schoolCourses.classList.remove('hidden'); // Show the selected school + schoolCourses.classList.add('visible'); // Show the selected school + }); + schoolTabs.appendChild(schoolTab); + + + let schoolDiv = document.createElement('div'); + schoolDiv.classList.add('school'); + school !== 'SCS' ? schoolDiv.classList.add('hidden') : null; + schoolDiv.setAttribute('id', school); + + let schoolHeader = document.createElement('h3'); + schoolHeader.textContent = schools[school].name; + + let schoolUl = document.createElement('ul'); + schoolList.appendChild(schoolDiv); + schoolDiv.appendChild(schoolHeader); + schoolDiv.appendChild(schoolUl); + + schools[school].courses.forEach(function (course) { + let slot = courses[course].slot; + + let courseLabel = document.createElement('label'); + courseLabel.setAttribute('for', course); + courseLabel.textContent = course; + courseLabel.textContent += ": " + courses[course].name; + // courseLabel.innerHTML += "(" + courses[course].slot + ")"; + + let courseLi = document.createElement('li'); + courseLi.classList.add('course'); + + let courseCheckBox = document.createElement('input'); + courseCheckBox.setAttribute('type', 'checkbox'); + courseCheckBox.setAttribute('value', course); + courseCheckBox.setAttribute('id', course); + + schoolUl.appendChild(courseLi); + courseLi.appendChild(courseCheckBox); + courseLi.appendChild(courseLabel); + }); } + /* A function that cleans the cells of the timetable */ function clean() { - let slotsInTimetable = document.querySelectorAll('td:not(.lunch)'); - - slotsInTimetable.forEach(function(slot) { - slot.textContent = ''; - }); - // Cleans legend - document.getElementById("legend").textContent = ""; - - // Removes colors from cells - let slots = document.getElementsByTagName("td"); - for (let i = 0; i < slotsInTimetable.length; i++) { - slots[i].style.backgroundColor = '#fff'; - } + let slotsInTimetable = document.querySelectorAll('td:not(.lunch)'); + + slotsInTimetable.forEach(function (slot) { + slot.textContent = ''; + }); + // Cleans legend + document.getElementById("legend").textContent = ""; + + // Removes colors from cells + let slots = document.getElementsByTagName("td"); + slotsInTimetable.forEach(slot => { + slot.style.backgroundColor = '#fff'; + }); } + /* To deal with conflicts like A and A1 */ function slotCompare(currentc, newc) { - if(currentc.length != newc.length) - return currentc.charAt(0) === newc.charAt(0); - return currentc === newc; + if (currentc.length != newc.length) + return currentc.charAt(0) === newc.charAt(0); + return currentc === newc; } -/* Replaces the slots in the timetable with the selected - * course in that slot */ + +// Replaces the slots in the timetable with the selected course in that slot function generate(nick) { - clean(); - let courseCheckBoxes = document.querySelectorAll("input:not([id='color'])"); - let occupiedSlots = []; - let legendItems = []; - - let h2leg = document.getElementById('h2leg'); - h2leg.classList.remove('hidden'); - h2leg.classList.add('visible'); - - let addColors = document.getElementById("color").checked; - - courseCheckBoxes.forEach(function(course) { - if (course.checked) { - let courseCode = course.getAttribute('id'); - let [courseName, courseNick, courseSlot] = Object.values(courses[courseCode]); - legendItems.push([courseSlot, courseCode, courseNick, courseName]); - - for (let i = 0; i < occupiedSlots.length; ++i) { - if (slotCompare(occupiedSlots[i], courseSlot)) { - alert("Schedule conflict detected. Course selection may need a modification."); - location = location; - } - } - - occupiedSlots.push(courseSlot); - - let courseSlotInTimetable = document.querySelectorAll('td.' + courseSlot); - courseSlotInTimetable.forEach(function(slotInTimetable) { - slotInTimetable.textContent = nick ? courseNick : courseCode; - }); - } - }) - - // Coloring - if (addColors) { - occupiedSlots = occupiedSlots.sort(); - occupiedSlots.forEach((courseSlot, i) => { - let courseSlotInTimetable = document.querySelectorAll('td.' + courseSlot); - courseSlotInTimetable.forEach(slotInTimetable => { - slotInTimetable.style.backgroundColor = colors[i]; - }); - }); - } - - // Legend - legendItems = legendItems.sort(function(a, b) { + clean(); + let courseCheckBoxes = document.querySelectorAll("input:not([id='color'])"); + let occupiedSlots = []; + let legendItems = []; + + let h2leg = document.getElementById('h2leg'); + h2leg.classList.remove('hidden'); + h2leg.classList.add('visible'); + + let addColors = document.getElementById("color").checked; + + courseCheckBoxes.forEach(function (course) { + if (course.checked) { + let courseCode = course.getAttribute('id'); + let [courseName, courseNick, courseSlot] = Object.values(courses[courseCode]); + + legendItems.push([courseSlot, courseCode, courseNick, courseName]); + + // Conflict detection + for (let i = 0; i < occupiedSlots.length; ++i) { + if (slotCompare(occupiedSlots[i], courseSlot)) { + alert("Schedule conflict detected. Course selection may need a modification."); + location = location; // Refreshes the page + } + } + + occupiedSlots.push(courseSlot); + + let courseSlotInTimetable = document.querySelectorAll('td.' + courseSlot); + courseSlotInTimetable.forEach(function (slotInTimetable) { + slotInTimetable.textContent = nick ? courseNick : courseCode; + }); + } + }) + + // Coloring + if (addColors) { + occupiedSlots = occupiedSlots.sort(); + occupiedSlots.forEach((courseSlot, i) => { + let courseSlotInTimetable = document.querySelectorAll('td.' + courseSlot); + courseSlotInTimetable.forEach(slotInTimetable => { + slotInTimetable.style.backgroundColor = colors[i]; + }); + }); + } + + // Legend + legendItems = legendItems.sort(function (a, b) { return a[0] > b[0] ? 1 : -1; }); - legendItems.forEach((element, i) => { + legendItems.forEach((element, i) => { let listItem = document.createElement("li"); listItem.textContent = "Slot " + element[0] + ": " + element[1] + " / " + element[2] + ": " + element[3]; - if (addColors) - listItem.style.color = colors[i]; + if (addColors) + listItem.style.color = colors[i]; document.getElementById("legend").appendChild(listItem); - }); + }); - // Preparing for PDF generation - occupiedSlotsGlob = []; - legendItems.forEach(item => { - occupiedSlotsGlob.push(nick ? item[2] : item[1]); - }); + // Preparing for PDF generation + occupiedSlotsGlob = []; + legendItems.forEach(item => { + occupiedSlotsGlob.push(nick ? item[2] : item[1]); + }); - occupiedSlots = []; - legendItems = []; + occupiedSlots = []; + legendItems = []; } function generatePdf() { - let doc = new jspdf.jsPDF({ - orientation: 'landscape', - unit: 'pt' - }); - - let notPainted = [ - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', - '', 'Day', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', - '08:30', '09:30', '10:30', '11:30', '12:30', '13:30', '14:30', '15:30', - '16:30', '17:30', '18:30', 'No Class', 'No', 'Lunch Break', 'Lunch' - ]; - - let centerX = doc.internal.pageSize.getWidth() / 2; - doc.text('Timetable for Fall Semester 2024', centerX, 25, {align: 'center'}); - doc.autoTable({ - html: 'table', - theme: 'plain', - styles: { - cellPadding: 10, - fontSize: 12, - lineColor: 10, - lineWidth: .5, - overflow: 'linebreak', - halign: 'center', - valign: 'middle' - }, - // Coloring in PDF - didParseCell(data) { - let addColors = document.getElementById("color").checked; - if (addColors) { - // Zips two arrays of differing lengths with the final array of arrays having the length of the smaller array - const zip = (a, b) => Array(Math.min(b.length, a.length)).fill().map((_, i) => [a[i], b[i]]); - // Creates a Course-Color dictionary - let zippedDict = Object.fromEntries(zip(occupiedSlotsGlob, colors)); - // Paints cells - if (!notPainted.includes(data.cell.text[0])) - data.cell.styles.fillColor = zippedDict[data.cell.text[0]]; - } - } - }); - - // Legend - let finalY = doc.lastAutoTable.finalY + 30; - doc.text('Legend', 40, finalY); - doc.html(document.getElementById('legend'), { - callback: function (doc) { - doc.save("timetable_fall24.pdf"); - }, - x: 40, - y: finalY + 7, - html2canvas: { - scale: 0.8, - } - }); + let doc = new jspdf.jsPDF({ + orientation: 'landscape', + unit: 'pt' + }); + + let notPainted = [ + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', + '', 'Day', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', + '08:30', '09:30', '10:30', '11:30', '12:30', '13:30', '14:30', '15:30', + '16:30', '17:30', '18:30', 'No Class', 'No', 'Lunch Break', 'Lunch' + ]; + + let centerX = doc.internal.pageSize.getWidth() / 2; + doc.text('Timetable for Fall Semester 2024', centerX, 25, { align: 'center' }); + doc.autoTable({ + html: 'table', + theme: 'plain', + styles: { + cellPadding: 10, + fontSize: 12, + lineColor: 10, + lineWidth: .5, + overflow: 'linebreak', + halign: 'center', + valign: 'middle' + }, + // Coloring in PDF + didParseCell(data) { + let addColors = document.getElementById("color").checked; + if (addColors) { + // Zips two arrays of differing lengths with the final array of arrays having the length of the smaller array + const zip = (a, b) => Array(Math.min(b.length, a.length)).fill().map((_, i) => [a[i], b[i]]); + // Creates a Course-Color dictionary + let zippedDict = Object.fromEntries(zip(occupiedSlotsGlob, colors)); + // Paints cells + if (!notPainted.includes(data.cell.text[0])) + data.cell.styles.fillColor = zippedDict[data.cell.text[0]]; + } + } + }); + + // Legend + let finalY = doc.lastAutoTable.finalY + 30; + doc.text('Legend', 40, finalY); + doc.html(document.getElementById('legend'), { + callback: function (doc) { + doc.save("timetable_fall24.pdf"); + }, + x: 40, + y: finalY + 7, + html2canvas: { + scale: 0.8, + } + }); +} + + +function formatted_time_string(day, time) { + const daysOfWeek = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; + const targetDayIndex = daysOfWeek.indexOf(day); + const currentDayIndex = startdate.getDay(); + let dayDifference = (targetDayIndex - currentDayIndex + 7) % 7; + const nextDate = new Date(startdate); + nextDate.setDate(startdate.getDate() + dayDifference); + const formattedDate = `${nextDate.getMonth() + 1}/${nextDate.getDate()}/${nextDate.getFullYear()}`; + return `${formattedDate} ${time}`; +} + + +function generateICS() { + var cal = ics(); + // cal.addEvent(subject, description, location, begin, end, rrule = {}); + // cal.download(filename); + + + + console.log("ICS file generated"); + console.log(occupiedSlotsGlob); // list of selected course codes + + // if length of occupiedSlotsGlob is 0, then alert the user + if (occupiedSlotsGlob.length == 0) { + alert("Please Generate the timetable first!"); + return; + } + + let location = "NISER"; + let rrule = { + freq: 'WEEKLY', + count: 20, + }; + + occupiedSlotsGlob.forEach(courseCode => { + let [courseName, courseNick, courseSlot] = Object.values(courses[courseCode]); + console.log(`courseName=${courseName},\ncourseNick=${courseNick},\ncourseSlot=${courseSlot},\ncourseCode=${courseCode}`); + + let subject = `${courseNick}: ${courseName}`; + let description = `Class for ${courseNick} at slot ${courseSlot}`; + slots[courseSlot].forEach(slot => { + let [day, start, end] = slot; + // console.log(day, start, end); + let begin = formatted_time_string(day, start); + let finish = formatted_time_string(day, end); + + cal.addEvent(subject, description, location, begin, finish, rrule); + }); + }) + + cal.download("timetable"); + } let generateCodeButton = document.querySelector('button#gen-code'); -generateCodeButton.addEventListener('click', function() { generate(false) }); +generateCodeButton.addEventListener('click', function () { generate(false) }); let generateNickButton = document.querySelector('button#gen-nick'); -generateNickButton.addEventListener('click', function() { generate(true) }); +generateNickButton.addEventListener('click', function () { generate(true) }); let pdfButton = document.querySelector('button#pdf'); pdfButton.onclick = generatePdf; +let icsButton = document.querySelector('button#ics'); +icsButton.onclick = generateICS; + let resetButton = document.querySelector('button#reset'); -resetButton.onclick = function() { - location = location; +resetButton.onclick = function () { + location = location; }