Lonelyguyse1 commited on
Commit
ef2b5ae
·
verified ·
1 Parent(s): 30a1b4e

Upload folder using huggingface_hub

Browse files
.gitattributes CHANGED
@@ -33,57 +33,3 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
- .nottracked/UG-CSE-2025.pdf filter=lfs diff=lfs merge=lfs -text
37
- .venv/bin/python filter=lfs diff=lfs merge=lfs -text
38
- .venv/bin/python3 filter=lfs diff=lfs merge=lfs -text
39
- .venv/bin/python3.14 filter=lfs diff=lfs merge=lfs -text
40
- .venv/bin/ruff filter=lfs diff=lfs merge=lfs -text
41
- .venv/bin/𝜋thon filter=lfs diff=lfs merge=lfs -text
42
- .venv/lib/python3.14/site-packages/PIL/__pycache__/Image.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
43
- .venv/lib/python3.14/site-packages/PIL/__pycache__/TiffImagePlugin.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
44
- .venv/lib/python3.14/site-packages/PIL/_imaging.cpython-314-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
45
- .venv/lib/python3.14/site-packages/PIL/_imagingcms.cpython-314-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
46
- .venv/lib/python3.14/site-packages/PIL/_imagingft.cpython-314-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
47
- .venv/lib/python3.14/site-packages/PIL/_imagingmath.cpython-314-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
48
- .venv/lib/python3.14/site-packages/PIL/_webp.cpython-314-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
49
- .venv/lib/python3.14/site-packages/__pycache__/typing_extensions.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
50
- .venv/lib/python3.14/site-packages/_brotli.cpython-314-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
51
- .venv/lib/python3.14/site-packages/_cffi_backend.cpython-314-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
52
- .venv/lib/python3.14/site-packages/_pytest/__pycache__/fixtures.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
53
- .venv/lib/python3.14/site-packages/_pytest/__pycache__/pytester.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
54
- .venv/lib/python3.14/site-packages/_pytest/__pycache__/terminal.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
55
- .venv/lib/python3.14/site-packages/_pytest/config/__pycache__/__init__.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
56
- .venv/lib/python3.14/site-packages/anyio/_backends/__pycache__/_asyncio.cpython-314-pytest-9.1.1.pyc filter=lfs diff=lfs merge=lfs -text
57
- .venv/lib/python3.14/site-packages/anyio/_backends/__pycache__/_asyncio.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
58
- .venv/lib/python3.14/site-packages/anyio/_backends/__pycache__/_trio.cpython-314-pytest-9.1.1.pyc filter=lfs diff=lfs merge=lfs -text
59
- .venv/lib/python3.14/site-packages/anyio/_backends/__pycache__/_trio.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
60
- .venv/lib/python3.14/site-packages/click/__pycache__/core.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
61
- .venv/lib/python3.14/site-packages/cryptography/hazmat/bindings/_rust.abi3.so filter=lfs diff=lfs merge=lfs -text
62
- .venv/lib/python3.14/site-packages/cryptography/x509/__pycache__/extensions.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
63
- .venv/lib/python3.14/site-packages/dns/__pycache__/resolver.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
64
- .venv/lib/python3.14/site-packages/fastapi/__pycache__/routing.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
65
- .venv/lib/python3.14/site-packages/fastar/fastar.cpython-314-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
66
- .venv/lib/python3.14/site-packages/fontTools/__pycache__/agl.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
67
- .venv/lib/python3.14/site-packages/fontTools/cffLib/__pycache__/__init__.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
68
- .venv/lib/python3.14/site-packages/fontTools/cu2qu/cu2qu.cpython-314-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
69
- .venv/lib/python3.14/site-packages/fontTools/designspaceLib/__pycache__/__init__.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
70
- .venv/lib/python3.14/site-packages/fontTools/feaLib/__pycache__/ast.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
71
- .venv/lib/python3.14/site-packages/fontTools/feaLib/__pycache__/parser.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
72
- .venv/lib/python3.14/site-packages/fontTools/feaLib/lexer.cpython-314-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
73
- .venv/lib/python3.14/site-packages/fontTools/misc/bezierTools.cpython-314-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
74
- .venv/lib/python3.14/site-packages/fontTools/otlLib/__pycache__/builder.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
75
- .venv/lib/python3.14/site-packages/fontTools/pens/momentsPen.cpython-314-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
76
- .venv/lib/python3.14/site-packages/fontTools/qu2cu/qu2cu.cpython-314-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
77
- .venv/lib/python3.14/site-packages/fontTools/subset/__pycache__/__init__.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
78
- .venv/lib/python3.14/site-packages/fontTools/ttLib/__pycache__/ttFont.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
79
- .venv/lib/python3.14/site-packages/fontTools/ttLib/tables/__pycache__/_g_l_y_f.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
80
- .venv/lib/python3.14/site-packages/fontTools/ttLib/tables/__pycache__/otConverters.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
81
- .venv/lib/python3.14/site-packages/fontTools/ttLib/tables/__pycache__/otData.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
82
- .venv/lib/python3.14/site-packages/fontTools/ttLib/tables/__pycache__/otTables.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
83
- .venv/lib/python3.14/site-packages/fontTools/ufoLib/__pycache__/__init__.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
84
- .venv/lib/python3.14/site-packages/fontTools/varLib/iup.cpython-314-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
85
- .venv/lib/python3.14/site-packages/hpack/__pycache__/huffman_table.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
86
- .venv/lib/python3.14/site-packages/httptools/parser/parser.cpython-314-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
87
- .venv/lib/python3.14/site-packages/httptools/parser/url_parser.cpython-314-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
88
- .venv/lib/python3.14/site-packages/jinja2/__pycache__/compiler.cpython-314.pyc filter=lfs diff=lfs merge=lfs -text
89
- .venv/lib/python3.14/site-packages/multidict/_multidict.cpython-314-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Dockerfile ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.12-slim
2
+
3
+ WORKDIR /app
4
+
5
+ COPY requirements.txt .
6
+
7
+ RUN pip install --no-cache-dir -r requirements.txt
8
+
9
+ COPY backend/ .
10
+
11
+ EXPOSE 7860
12
+
13
+ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "7860"]
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Lonely Guy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
README.md ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Curriculum Automation
2
+
3
+ ## Phase 1 Flow Proposal
4
+
5
+ ```mermaid id="phase1-flow"
6
+ flowchart TD
7
+
8
+ A[Professor opens form] --> B[Enter course details]
9
+ B --> C[Submit content, semester, credits, department, books]
10
+
11
+ C --> D[FastAPI receives submission]
12
+ D --> E[Check mandatory fields]
13
+
14
+ E -->|Invalid| F[Reject submission]
15
+ F --> G[Email professor with reasons]
16
+ G --> H[Professor opens edit link]
17
+ H --> I[Cached form shows old data and flagged issues]
18
+ I --> C
19
+
20
+ E -->|Valid| J[Generate derived fields]
21
+ J --> J1[Course code]
22
+ J --> J2[Credit pattern]
23
+ J --> J3[Course type]
24
+ J --> J4[Template data]
25
+
26
+ J1 --> K[AI refinement]
27
+ J2 --> K
28
+ J3 --> K
29
+ J4 --> K
30
+
31
+ K --> K1[Refine content]
32
+ K --> K2[Generate prelude]
33
+ K --> K3[Generate objectives]
34
+ K --> K4[Generate outcomes]
35
+ K --> K5[Recommend tools]
36
+
37
+ K1 --> L[Rubric check]
38
+ K2 --> L
39
+ K3 --> L
40
+ K4 --> L
41
+ K5 --> L
42
+
43
+ L -->|Low score| M[Reject draft]
44
+ M --> N[Store flagged issues]
45
+ N --> G
46
+
47
+ L -->|Pass| O[Create draft record]
48
+ O --> P[Render preview with Jinja2]
49
+
50
+ P --> Q[Faculty or admin review]
51
+
52
+ Q -->|Rejected| R[Store rejection reasons]
53
+ R --> G
54
+
55
+ Q -->|Accepted| S[Update remote database]
56
+ S --> T[Update curriculum template fields]
57
+ T --> U[Keep incomplete template pending]
58
+
59
+ U --> V{All course submissions received?}
60
+
61
+ V -->|No| W[Wait for remaining professors]
62
+ W --> U
63
+
64
+ V -->|Yes| X[Compile final curriculum document]
65
+ X --> Y[Final review]
66
+ Y --> Z[Export final PDF or DOCX]
67
+ ```
68
+
69
+ ## Phase 1 Summary
70
+
71
+ Professors submit only the required academic material.
72
+
73
+ The system generates derived fields, refines the content, checks it using a rubric, and stores accepted drafts in a remote database.
74
+
75
+ Rejected submissions are returned by email with reasons. The professor gets an edit link where previous data is already cached and flagged issues are shown.
76
+
77
+ Accepted submissions do not immediately become the final document. They update the shared curriculum template and remain pending until all required course submissions are received.
78
+
79
+ The final curriculum document is compiled only after every required course entry is complete.
backend/app/__init__.py ADDED
File without changes
backend/app/api.py ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pathlib import Path
2
+
3
+ from fastapi import APIRouter
4
+ from fastapi.responses import HTMLResponse, Response
5
+ from jinja2 import Environment, FileSystemLoader
6
+ from pydantic import BaseModel,Field, field_validator
7
+ from typing import Literal
8
+ from weasyprint import HTML
9
+
10
+ from app.preview import build_course_preview
11
+ from app.supabase import supabase
12
+
13
+ router=APIRouter()
14
+ templates=Environment(loader=FileSystemLoader("app/templates"))
15
+ FRONTEND_DIR=Path(__file__).resolve().parent/"templates"
16
+
17
+ class CourseSubmission(BaseModel):
18
+ faculty_email: str=Field(min_length=3, max_length=254)
19
+ course_title: str=Field(min_length=3, max_length=150)
20
+ offering_department: Literal["MA", "CS", "UZ"]
21
+ target_department: Literal["CSE", "ECE", "ME", "BT", "EEE", "AIML"]
22
+ semester: Literal["1", "2", "3", "4", "5", "6", "7", "8"]
23
+ credit_category: Literal["0", "2", "4", "5"]
24
+ raw_course_content: str=Field(min_length=50)
25
+ text_books: str=Field(min_length=5)
26
+ reference_books: str=""
27
+ preferred_tools: str=""
28
+
29
+ @field_validator("faculty_email","course_title","raw_course_content","text_books","reference_books","preferred_tools",mode="before")
30
+ @classmethod
31
+ def strip(cls, v):
32
+ return v.strip() if isinstance(v, str) else v
33
+
34
+ @router.post("/submissions")
35
+ def receive(data: CourseSubmission):
36
+ d=data.model_dump()
37
+ d["status"]="pending"
38
+ r=supabase.table("submissions").insert(d).execute()
39
+ return {"message":"Submission Received!","submission":r.data[0]}
40
+
41
+ @router.get("/preview/semester/{sem}/courses")
42
+ def list_courses(sem:str):
43
+ r=supabase.table("refined_submissions").select("id").execute()
44
+ return {"course_ids":[row["id"] for row in r.data]}
45
+
46
+ @router.get("/preview/course/{refined_id}")
47
+ def preview_course(refined_id:int):
48
+ r=supabase.table("refined_submissions").select("*").eq("id",refined_id).single().execute()
49
+ course=build_course_preview(r.data)
50
+ return HTMLResponse(templates.get_template("jinja_sample.html").render(course=course,curriculum_year="2025-2026",page_number=""))
51
+
52
+ @router.get("/preview/semester/{sem}/pdf")
53
+ def download_pdf(sem:str):
54
+ r=supabase.table("refined_submissions").select("id").execute()
55
+ ids=[row["id"] for row in r.data]
56
+ style=""
57
+ bodies=[]
58
+ for i,rid in enumerate(ids,1):
59
+ r=supabase.table("refined_submissions").select("*").eq("id",rid).single().execute()
60
+ h=templates.get_template("jinja_sample.html").render(course=build_course_preview(r.data),curriculum_year="2025-2026",page_number=str(i))
61
+ if not style:
62
+ s1=h.find("<style");e1=h.find("</style>")+8
63
+ style=h[s1:e1]
64
+ s2=h.find("<style",e1);e2=h.find("</style>",s2)+8
65
+ style+=h[s2:e2]
66
+ bs=h.find(">",h.find("<body"))+1;be=h.find("</body>")
67
+ cls="page-break" if i>1 else ""
68
+ bodies.append(f"<div class=\"{cls}\">{h[bs:be]}</div>"if cls else h[bs:be])
69
+ combined=f"""<!DOCTYPE html><html><head><meta charset="UTF-8">{style}<style>@page{{size:A4;margin:0;}}.page-break{{page-break-before:always;}}.c71{{padding-bottom:35pt;}}</style></head><body>{"".join(bodies)}</body></html>"""
70
+ pdf=HTML(string=combined,base_url=str(FRONTEND_DIR)).write_pdf()
71
+ return Response(content=pdf,media_type="application/pdf",headers={"Content-Disposition":f"attachment;filename=semester-{sem}.pdf"})
backend/app/main.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pathlib import Path
2
+
3
+ from fastapi import FastAPI
4
+ from fastapi.middleware.cors import CORSMiddleware
5
+ from fastapi.staticfiles import StaticFiles
6
+
7
+ from app.api import router
8
+
9
+ app = FastAPI(title="PESU Curriculum Automation")
10
+
11
+ app.add_middleware(
12
+ CORSMiddleware,
13
+ allow_origins=["*"],
14
+ allow_methods=["*"],
15
+ allow_headers=["*"],
16
+ )
17
+
18
+ app.include_router(router, prefix="/api")
19
+
20
+ if Path("../frontend").exists():
21
+ app.mount("/", StaticFiles(directory="../frontend", html=True), name="frontend")
backend/app/preview.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+
3
+
4
+ def build_course_preview(row: dict) -> dict:
5
+ content = json.loads(row.get("refined_content") or "{}")
6
+ return {
7
+ "course_code": str(content.get("course_code", "")),
8
+ "course_title": str(content.get("course_title", "")),
9
+ "program": str(content.get("program", "")),
10
+ "lecture_hours": str(content.get("lecture_hours", 0)),
11
+ "tutorial_hours": str(content.get("tutorial_hours", 0)),
12
+ "practical_hours": str(content.get("practical_hours", 0)),
13
+ "self_study": str(content.get("self_study", 0)),
14
+ "credits": str(content.get("credits", 0)),
15
+ "semester": str(content.get("semester", "")),
16
+ "course_type": str(content.get("course_type", "")),
17
+ "tools_languages": str(content.get("tools_languages", "")),
18
+ "desirable_knowledge": str(content.get("desirable_knowledge", "")),
19
+ "prelude": row.get("prelude") or content.get("prelude", ""),
20
+ "objectives": row.get("objectives") or content.get("objectives", []),
21
+ "units": content.get("units", []),
22
+ "lab_experiments": content.get("lab_experiments", []),
23
+ }
backend/app/supabase.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from os import environ
2
+ from supabase import create_client, ClientOptions
3
+ from dotenv import load_dotenv
4
+ import httpx
5
+
6
+ load_dotenv("../.env")
7
+
8
+ url=environ["SUPABASE_URL"]
9
+ key=environ["SUPABASE_KEY"]
10
+ supabase=create_client(
11
+ supabase_url=url,
12
+ supabase_key=key,
13
+ options=ClientOptions(
14
+ httpx_client=httpx.Client(http2=False),
15
+ ),
16
+ )
backend/app/templates/images/image1.png ADDED
backend/app/templates/images/image2.png ADDED
backend/app/templates/jinja_sample.html ADDED
@@ -0,0 +1,1456 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <html>
2
+ <head>
3
+ <meta content="text/html; charset=UTF-8" http-equiv="content-type" />
4
+ <style type="text/css">
5
+ .lst-kix_list_2-6 > li:before {
6
+ content: "\002022 ";
7
+ }
8
+ .lst-kix_list_2-7 > li:before {
9
+ content: "\002022 ";
10
+ }
11
+ ol.lst-kix_list_1-0 {
12
+ list-style-type: none;
13
+ }
14
+ .lst-kix_list_2-4 > li:before {
15
+ content: "\002022 ";
16
+ }
17
+ .lst-kix_list_2-5 > li:before {
18
+ content: "\002022 ";
19
+ }
20
+ .lst-kix_list_2-8 > li:before {
21
+ content: "\002022 ";
22
+ }
23
+ ul.lst-kix_list_2-8 {
24
+ list-style-type: none;
25
+ }
26
+ ul.lst-kix_list_1-3 {
27
+ list-style-type: none;
28
+ }
29
+ ul.lst-kix_list_2-2 {
30
+ list-style-type: none;
31
+ }
32
+ .lst-kix_list_1-0 > li:before {
33
+ content: "" counter(lst-ctn-kix_list_1-0, decimal) ". ";
34
+ }
35
+ ul.lst-kix_list_1-4 {
36
+ list-style-type: none;
37
+ }
38
+ ul.lst-kix_list_2-3 {
39
+ list-style-type: none;
40
+ }
41
+ ul.lst-kix_list_1-1 {
42
+ list-style-type: none;
43
+ }
44
+ ul.lst-kix_list_2-0 {
45
+ list-style-type: none;
46
+ }
47
+ ul.lst-kix_list_1-2 {
48
+ list-style-type: none;
49
+ }
50
+ ul.lst-kix_list_2-1 {
51
+ list-style-type: none;
52
+ }
53
+ ul.lst-kix_list_1-7 {
54
+ list-style-type: none;
55
+ }
56
+ ul.lst-kix_list_2-6 {
57
+ list-style-type: none;
58
+ }
59
+ .lst-kix_list_1-1 > li:before {
60
+ content: "\002022 ";
61
+ }
62
+ .lst-kix_list_1-2 > li:before {
63
+ content: "\002022 ";
64
+ }
65
+ ul.lst-kix_list_1-8 {
66
+ list-style-type: none;
67
+ }
68
+ ul.lst-kix_list_2-7 {
69
+ list-style-type: none;
70
+ }
71
+ ul.lst-kix_list_1-5 {
72
+ list-style-type: none;
73
+ }
74
+ ul.lst-kix_list_2-4 {
75
+ list-style-type: none;
76
+ }
77
+ ul.lst-kix_list_1-6 {
78
+ list-style-type: none;
79
+ }
80
+ ul.lst-kix_list_2-5 {
81
+ list-style-type: none;
82
+ }
83
+ .lst-kix_list_1-3 > li:before {
84
+ content: "\002022 ";
85
+ }
86
+ .lst-kix_list_1-4 > li:before {
87
+ content: "\002022 ";
88
+ }
89
+ ol.lst-kix_list_1-0.start {
90
+ counter-reset: lst-ctn-kix_list_1-0 0;
91
+ }
92
+ .lst-kix_list_1-0 > li {
93
+ counter-increment: lst-ctn-kix_list_1-0;
94
+ }
95
+ li.li-bullet-1:before {
96
+ margin-left: -36.1pt;
97
+ white-space: nowrap;
98
+ display: inline-block;
99
+ min-width: 36.1pt;
100
+ }
101
+ .lst-kix_list_1-7 > li:before {
102
+ content: "\002022 ";
103
+ }
104
+ .lst-kix_list_1-5 > li:before {
105
+ content: "\002022 ";
106
+ }
107
+ .lst-kix_list_1-6 > li:before {
108
+ content: "\002022 ";
109
+ }
110
+ li.li-bullet-0:before {
111
+ margin-left: -18pt;
112
+ white-space: nowrap;
113
+ display: inline-block;
114
+ min-width: 18pt;
115
+ }
116
+ .lst-kix_list_2-0 > li:before {
117
+ content: "\0025cf ";
118
+ }
119
+ .lst-kix_list_2-1 > li:before {
120
+ content: "\002022 ";
121
+ }
122
+ .lst-kix_list_1-8 > li:before {
123
+ content: "\002022 ";
124
+ }
125
+ .lst-kix_list_2-2 > li:before {
126
+ content: "\002022 ";
127
+ }
128
+ .lst-kix_list_2-3 > li:before {
129
+ content: "\002022 ";
130
+ }
131
+ ol {
132
+ margin: 0;
133
+ padding: 0;
134
+ }
135
+ table td,
136
+ table th {
137
+ padding: 0;
138
+ }
139
+ .c11 {
140
+ border-right-style: solid;
141
+ border-bottom-color: #000000;
142
+ border-top-width: 1pt;
143
+ border-right-width: 1pt;
144
+ border-left-color: #000000;
145
+ vertical-align: top;
146
+ border-right-color: #000000;
147
+ border-left-width: 1pt;
148
+ border-top-style: solid;
149
+ background-color: #000000;
150
+ border-left-style: solid;
151
+ border-bottom-width: 1pt;
152
+ width: 71pt;
153
+ border-top-color: #d9d9d9;
154
+ border-bottom-style: solid;
155
+ }
156
+ .c74 {
157
+ border-right-style: solid;
158
+ border-bottom-color: #000000;
159
+ border-top-width: 1pt;
160
+ border-right-width: 1pt;
161
+ border-left-color: #000000;
162
+ vertical-align: top;
163
+ border-right-color: #000000;
164
+ border-left-width: 1pt;
165
+ border-top-style: solid;
166
+ background-color: #000000;
167
+ border-left-style: solid;
168
+ border-bottom-width: 1pt;
169
+ width: 48.9pt;
170
+ border-top-color: #d9d9d9;
171
+ border-bottom-style: solid;
172
+ }
173
+ .c19 {
174
+ border-right-style: solid;
175
+ border-bottom-color: #000000;
176
+ border-top-width: 1pt;
177
+ border-right-width: 1pt;
178
+ border-left-color: #000000;
179
+ vertical-align: top;
180
+ border-right-color: #000000;
181
+ border-left-width: 1pt;
182
+ border-top-style: solid;
183
+ background-color: #000000;
184
+ border-left-style: solid;
185
+ border-bottom-width: 1pt;
186
+ width: 42.5pt;
187
+ border-top-color: #d9d9d9;
188
+ border-bottom-style: solid;
189
+ }
190
+ .c60 {
191
+ border-right-style: solid;
192
+ border-bottom-color: #000000;
193
+ border-top-width: 1pt;
194
+ border-right-width: 1pt;
195
+ border-left-color: #000000;
196
+ vertical-align: top;
197
+ border-right-color: #000000;
198
+ border-left-width: 1pt;
199
+ border-top-style: solid;
200
+ background-color: #000000;
201
+ border-left-style: solid;
202
+ border-bottom-width: 1pt;
203
+ width: 441.2pt;
204
+ border-top-color: #d9d9d9;
205
+ border-bottom-style: solid;
206
+ }
207
+ .c72 {
208
+ border-right-style: solid;
209
+ border-bottom-color: #000000;
210
+ border-top-width: 1pt;
211
+ border-right-width: 1pt;
212
+ border-left-color: #000000;
213
+ vertical-align: top;
214
+ border-right-color: #000000;
215
+ border-left-width: 1pt;
216
+ border-top-style: solid;
217
+ background-color: #000000;
218
+ border-left-style: solid;
219
+ border-bottom-width: 1pt;
220
+ width: 42.1pt;
221
+ border-top-color: #d9d9d9;
222
+ border-bottom-style: solid;
223
+ }
224
+ .c102 {
225
+ border-right-style: solid;
226
+ border-bottom-color: #000000;
227
+ border-top-width: 1pt;
228
+ border-right-width: 1pt;
229
+ border-left-color: #000000;
230
+ vertical-align: top;
231
+ border-right-color: #000000;
232
+ border-left-width: 1pt;
233
+ border-top-style: solid;
234
+ background-color: #000000;
235
+ border-left-style: solid;
236
+ border-bottom-width: 1pt;
237
+ width: 35.5pt;
238
+ border-top-color: #d9d9d9;
239
+ border-bottom-style: solid;
240
+ }
241
+ .c24 {
242
+ border-right-style: solid;
243
+ border-bottom-color: #000000;
244
+ border-top-width: 1pt;
245
+ border-right-width: 1pt;
246
+ border-left-color: #000000;
247
+ vertical-align: top;
248
+ border-right-color: #000000;
249
+ border-left-width: 1pt;
250
+ border-top-style: solid;
251
+ background-color: #000000;
252
+ border-left-style: solid;
253
+ border-bottom-width: 1pt;
254
+ width: 49.6pt;
255
+ border-top-color: #d9d9d9;
256
+ border-bottom-style: solid;
257
+ }
258
+ .c32 {
259
+ border-right-style: solid;
260
+ border-bottom-color: #d9d9d9;
261
+ border-top-width: 1pt;
262
+ border-right-width: 1pt;
263
+ border-left-color: #000000;
264
+ vertical-align: top;
265
+ border-right-color: #000000;
266
+ border-left-width: 1pt;
267
+ border-top-style: solid;
268
+ border-left-style: solid;
269
+ border-bottom-width: 1pt;
270
+ border-top-color: #000000;
271
+ border-bottom-style: solid;
272
+ }
273
+ .c61 {
274
+ border-right-style: solid;
275
+ border-bottom-color: #000000;
276
+ border-top-width: 1pt;
277
+ border-right-width: 0pt;
278
+ border-left-color: #000000;
279
+ vertical-align: top;
280
+ border-right-color: #000000;
281
+ border-left-width: 1pt;
282
+ border-top-style: solid;
283
+ border-left-style: solid;
284
+ border-bottom-width: 0pt;
285
+ width: 30.4pt;
286
+ border-top-color: #d9d9d9;
287
+ border-bottom-style: solid;
288
+ }
289
+ .c44 {
290
+ border-right-style: solid;
291
+ border-bottom-color: #000000;
292
+ border-top-width: 1pt;
293
+ border-right-width: 1pt;
294
+ border-left-color: #000000;
295
+ vertical-align: top;
296
+ border-right-color: #000000;
297
+ border-left-width: 1pt;
298
+ border-top-style: solid;
299
+ border-left-style: solid;
300
+ border-bottom-width: 1pt;
301
+ border-top-color: #000000;
302
+ border-bottom-style: solid;
303
+ }
304
+ .c15 {
305
+ border-right-style: solid;
306
+ border-bottom-color: #000000;
307
+ border-top-width: 1pt;
308
+ border-right-width: 1pt;
309
+ border-left-color: #000000;
310
+ vertical-align: top;
311
+ border-right-color: #000000;
312
+ border-left-width: 1pt;
313
+ border-top-style: solid;
314
+ border-left-style: solid;
315
+ border-bottom-width: 1pt;
316
+ width: 48.9pt;
317
+ border-top-color: #000000;
318
+ border-bottom-style: solid;
319
+ }
320
+ .c14 {
321
+ border-right-style: solid;
322
+ border-bottom-color: #000000;
323
+ border-top-width: 1pt;
324
+ border-right-width: 1pt;
325
+ border-left-color: #000000;
326
+ vertical-align: top;
327
+ border-right-color: #000000;
328
+ border-left-width: 1pt;
329
+ border-top-style: solid;
330
+ border-left-style: solid;
331
+ border-bottom-width: 1pt;
332
+ width: 49.6pt;
333
+ border-top-color: #000000;
334
+ border-bottom-style: solid;
335
+ }
336
+ .c49 {
337
+ border-right-style: solid;
338
+ border-bottom-color: #d9d9d9;
339
+ border-top-width: 0pt;
340
+ border-right-width: 1pt;
341
+ border-left-color: #000000;
342
+ vertical-align: top;
343
+ border-right-color: #000000;
344
+ border-left-width: 0pt;
345
+ border-top-style: solid;
346
+ border-left-style: solid;
347
+ border-bottom-width: 1pt;
348
+ width: 17.3pt;
349
+ border-top-color: #000000;
350
+ border-bottom-style: solid;
351
+ }
352
+ .c80 {
353
+ border-right-style: solid;
354
+ border-bottom-color: #d9d9d9;
355
+ border-top-width: 1pt;
356
+ border-right-width: 1pt;
357
+ border-left-color: #000000;
358
+ vertical-align: top;
359
+ border-right-color: #000000;
360
+ border-left-width: 1pt;
361
+ border-top-style: solid;
362
+ border-left-style: solid;
363
+ border-bottom-width: 1pt;
364
+ width: 48.9pt;
365
+ border-top-color: #000000;
366
+ border-bottom-style: solid;
367
+ }
368
+ .c63 {
369
+ border-right-style: solid;
370
+ border-bottom-color: #000000;
371
+ border-top-width: 1pt;
372
+ border-right-width: 1pt;
373
+ border-left-color: #000000;
374
+ vertical-align: top;
375
+ border-right-color: #000000;
376
+ border-left-width: 1pt;
377
+ border-top-style: solid;
378
+ border-left-style: solid;
379
+ border-bottom-width: 1pt;
380
+ width: 76pt;
381
+ border-top-color: #d9d9d9;
382
+ border-bottom-style: solid;
383
+ }
384
+ .c43 {
385
+ border-right-style: solid;
386
+ border-bottom-color: #000000;
387
+ border-top-width: 1pt;
388
+ border-right-width: 1pt;
389
+ border-left-color: #000000;
390
+ vertical-align: top;
391
+ border-right-color: #000000;
392
+ border-left-width: 1pt;
393
+ border-top-style: solid;
394
+ border-left-style: solid;
395
+ border-bottom-width: 1pt;
396
+ width: 42.5pt;
397
+ border-top-color: #000000;
398
+ border-bottom-style: solid;
399
+ }
400
+ .c46 {
401
+ border-right-style: solid;
402
+ border-bottom-color: #d9d9d9;
403
+ border-top-width: 1pt;
404
+ border-right-width: 1pt;
405
+ border-left-color: #000000;
406
+ vertical-align: top;
407
+ border-right-color: #000000;
408
+ border-left-width: 1pt;
409
+ border-top-style: solid;
410
+ border-left-style: solid;
411
+ border-bottom-width: 1pt;
412
+ width: 42.5pt;
413
+ border-top-color: #000000;
414
+ border-bottom-style: solid;
415
+ }
416
+ .c34 {
417
+ border-right-style: solid;
418
+ border-bottom-color: #d9d9d9;
419
+ border-top-width: 1pt;
420
+ border-right-width: 1pt;
421
+ border-left-color: #000000;
422
+ vertical-align: top;
423
+ border-right-color: #000000;
424
+ border-left-width: 1pt;
425
+ border-top-style: solid;
426
+ border-left-style: solid;
427
+ border-bottom-width: 1pt;
428
+ width: 35.5pt;
429
+ border-top-color: #000000;
430
+ border-bottom-style: solid;
431
+ }
432
+ .c52 {
433
+ border-right-style: solid;
434
+ border-bottom-color: #d9d9d9;
435
+ border-top-width: 1pt;
436
+ border-right-width: 1pt;
437
+ border-left-color: #000000;
438
+ vertical-align: top;
439
+ border-right-color: #000000;
440
+ border-left-width: 1pt;
441
+ border-top-style: solid;
442
+ border-left-style: solid;
443
+ border-bottom-width: 1pt;
444
+ width: 42.1pt;
445
+ border-top-color: #000000;
446
+ border-bottom-style: solid;
447
+ }
448
+ .c18 {
449
+ border-right-style: solid;
450
+ border-bottom-color: #000000;
451
+ border-top-width: 0pt;
452
+ border-right-width: 1pt;
453
+ border-left-color: #000000;
454
+ vertical-align: top;
455
+ border-right-color: #000000;
456
+ border-left-width: 0pt;
457
+ border-top-style: solid;
458
+ border-left-style: solid;
459
+ border-bottom-width: 0pt;
460
+ width: 17.3pt;
461
+ border-top-color: #000000;
462
+ border-bottom-style: solid;
463
+ }
464
+ .c30 {
465
+ border-right-style: solid;
466
+ border-bottom-color: #d9d9d9;
467
+ border-top-width: 1pt;
468
+ border-right-width: 1pt;
469
+ border-left-color: #000000;
470
+ vertical-align: top;
471
+ border-right-color: #000000;
472
+ border-left-width: 1pt;
473
+ border-top-style: solid;
474
+ border-left-style: solid;
475
+ border-bottom-width: 1pt;
476
+ width: 71pt;
477
+ border-top-color: #000000;
478
+ border-bottom-style: solid;
479
+ }
480
+ .c29 {
481
+ border-right-style: solid;
482
+ border-bottom-color: #000000;
483
+ border-top-width: 0pt;
484
+ border-right-width: 0pt;
485
+ border-left-color: #000000;
486
+ vertical-align: top;
487
+ border-right-color: #000000;
488
+ border-left-width: 1pt;
489
+ border-top-style: solid;
490
+ border-left-style: solid;
491
+ border-bottom-width: 0pt;
492
+ width: 30.4pt;
493
+ border-top-color: #000000;
494
+ border-bottom-style: solid;
495
+ }
496
+ .c31 {
497
+ border-right-style: solid;
498
+ border-bottom-color: #d9d9d9;
499
+ border-top-width: 1pt;
500
+ border-right-width: 1pt;
501
+ border-left-color: #000000;
502
+ vertical-align: top;
503
+ border-right-color: #000000;
504
+ border-left-width: 1pt;
505
+ border-top-style: solid;
506
+ border-left-style: solid;
507
+ border-bottom-width: 1pt;
508
+ width: 76pt;
509
+ border-top-color: #000000;
510
+ border-bottom-style: solid;
511
+ }
512
+ .c37 {
513
+ border-right-style: solid;
514
+ border-bottom-color: #000000;
515
+ border-top-width: 1pt;
516
+ border-right-width: 1pt;
517
+ border-left-color: #000000;
518
+ vertical-align: top;
519
+ border-right-color: #000000;
520
+ border-left-width: 0pt;
521
+ border-top-style: solid;
522
+ border-left-style: solid;
523
+ border-bottom-width: 0pt;
524
+ width: 17.3pt;
525
+ border-top-color: #d9d9d9;
526
+ border-bottom-style: solid;
527
+ }
528
+ .c5 {
529
+ border-right-style: solid;
530
+ border-bottom-color: #000000;
531
+ border-top-width: 1pt;
532
+ border-right-width: 1pt;
533
+ border-left-color: #000000;
534
+ vertical-align: top;
535
+ border-right-color: #000000;
536
+ border-left-width: 1pt;
537
+ border-top-style: solid;
538
+ border-left-style: solid;
539
+ border-bottom-width: 1pt;
540
+ width: 76pt;
541
+ border-top-color: #000000;
542
+ border-bottom-style: solid;
543
+ }
544
+ .c64 {
545
+ border-right-style: solid;
546
+ border-bottom-color: #000000;
547
+ border-top-width: 1pt;
548
+ border-right-width: 1pt;
549
+ border-left-color: #000000;
550
+ vertical-align: top;
551
+ border-right-color: #000000;
552
+ border-left-width: 1pt;
553
+ border-top-style: solid;
554
+ border-left-style: solid;
555
+ border-bottom-width: 1pt;
556
+ border-top-color: #000000;
557
+ border-bottom-style: solid;
558
+ }
559
+ .c10 {
560
+ border-right-style: solid;
561
+ border-bottom-color: #d9d9d9;
562
+ border-top-width: 1pt;
563
+ border-right-width: 1pt;
564
+ border-left-color: #000000;
565
+ vertical-align: top;
566
+ border-right-color: #000000;
567
+ border-left-width: 1pt;
568
+ border-top-style: solid;
569
+ border-left-style: solid;
570
+ border-bottom-width: 1pt;
571
+ width: 49.6pt;
572
+ border-top-color: #000000;
573
+ border-bottom-style: solid;
574
+ }
575
+ .c59 {
576
+ border-right-style: solid;
577
+ border-bottom-color: #000000;
578
+ border-top-width: 1pt;
579
+ border-right-width: 1pt;
580
+ border-left-color: #000000;
581
+ vertical-align: top;
582
+ border-right-color: #000000;
583
+ border-left-width: 1pt;
584
+ border-top-style: solid;
585
+ border-left-style: solid;
586
+ border-bottom-width: 1pt;
587
+ width: 42.1pt;
588
+ border-top-color: #000000;
589
+ border-bottom-style: solid;
590
+ }
591
+ .c99 {
592
+ border-right-style: solid;
593
+ border-bottom-color: #d9d9d9;
594
+ border-top-width: 0pt;
595
+ border-right-width: 0pt;
596
+ border-left-color: #000000;
597
+ vertical-align: top;
598
+ border-right-color: #000000;
599
+ border-left-width: 1pt;
600
+ border-top-style: solid;
601
+ border-left-style: solid;
602
+ border-bottom-width: 1pt;
603
+ width: 30.4pt;
604
+ border-top-color: #000000;
605
+ border-bottom-style: solid;
606
+ }
607
+ .c23 {
608
+ border-right-style: solid;
609
+ border-bottom-color: #000000;
610
+ border-top-width: 1pt;
611
+ border-right-width: 1pt;
612
+ border-left-color: #000000;
613
+ vertical-align: top;
614
+ border-right-color: #000000;
615
+ border-left-width: 1pt;
616
+ border-top-style: solid;
617
+ border-left-style: solid;
618
+ border-bottom-width: 1pt;
619
+ width: 71pt;
620
+ border-top-color: #000000;
621
+ border-bottom-style: solid;
622
+ }
623
+ .c22 {
624
+ border-right-style: solid;
625
+ border-bottom-color: #000000;
626
+ border-top-width: 1pt;
627
+ border-right-width: 1pt;
628
+ border-left-color: #000000;
629
+ vertical-align: top;
630
+ border-right-color: #000000;
631
+ border-left-width: 1pt;
632
+ border-top-style: solid;
633
+ border-left-style: solid;
634
+ border-bottom-width: 1pt;
635
+ width: 35.5pt;
636
+ border-top-color: #000000;
637
+ border-bottom-style: solid;
638
+ }
639
+ .c20 {
640
+ border-right-style: solid;
641
+ border-bottom-color: #000000;
642
+ border-top-width: 1pt;
643
+ border-right-width: 1pt;
644
+ border-left-color: #000000;
645
+ vertical-align: top;
646
+ border-right-color: #000000;
647
+ border-left-width: 1pt;
648
+ border-top-style: solid;
649
+ border-left-style: solid;
650
+ border-bottom-width: 1pt;
651
+ width: 151.5pt;
652
+ border-top-color: #000000;
653
+ border-bottom-style: solid;
654
+ }
655
+ .c16 {
656
+ color: #000000;
657
+ font-weight: 700;
658
+ text-decoration: none;
659
+ vertical-align: baseline;
660
+ font-size: 12pt;
661
+ font-family: "Calibri";
662
+ font-style: normal;
663
+ }
664
+ .c40 {
665
+ margin-left: 4.8pt;
666
+ padding-top: 5.3pt;
667
+ text-indent: -0.2pt;
668
+ padding-bottom: 0pt;
669
+ line-height: 1.0374999999999999;
670
+ text-align: left;
671
+ margin-right: 32.5pt;
672
+ }
673
+ .c1 {
674
+ color: #000000;
675
+ font-weight: 400;
676
+ text-decoration: none;
677
+ vertical-align: baseline;
678
+ font-size: 10pt;
679
+ font-family: "Calibri";
680
+ font-style: normal;
681
+ }
682
+ .c67 {
683
+ color: #000000;
684
+ font-weight: 700;
685
+ text-decoration: none;
686
+ vertical-align: baseline;
687
+ font-size: 10pt;
688
+ font-family: "Arial";
689
+ font-style: normal;
690
+ }
691
+ .c62 {
692
+ margin-left: 40.2pt;
693
+ padding-top: 0.5pt;
694
+ padding-left: 0pt;
695
+ padding-bottom: 0pt;
696
+ line-height: 1.0374999999999999;
697
+ text-align: left;
698
+ margin-right: 19pt;
699
+ }
700
+ .c86 {
701
+ color: #000000;
702
+ font-weight: 400;
703
+ text-decoration: none;
704
+ vertical-align: baseline;
705
+ font-size: 10pt;
706
+ font-family: "Verdana";
707
+ font-style: normal;
708
+ }
709
+ .c51 {
710
+ margin-left: 4.3pt;
711
+ padding-top: 0.4pt;
712
+ text-indent: -0.2pt;
713
+ padding-bottom: 0pt;
714
+ line-height: 1.0374999999999999;
715
+ text-align: justify;
716
+ margin-right: 4.7pt;
717
+ }
718
+ .c76 {
719
+ margin-left: 4.3pt;
720
+ padding-top: 0.5pt;
721
+ text-indent: -0.2pt;
722
+ padding-bottom: 0pt;
723
+ line-height: 1.0374999999999999;
724
+ text-align: justify;
725
+ margin-right: 4.5pt;
726
+ }
727
+ .c48 {
728
+ color: #000000;
729
+ font-weight: 400;
730
+ text-decoration: none;
731
+ vertical-align: baseline;
732
+ font-size: 7pt;
733
+ font-family: "Times New Roman";
734
+ font-style: normal;
735
+ }
736
+ .c25 {
737
+ margin-left: 4.3pt;
738
+ padding-top: 0.6pt;
739
+ text-indent: -0.2pt;
740
+ padding-bottom: 0pt;
741
+ line-height: 1.0374999999999999;
742
+ text-align: justify;
743
+ margin-right: 4.9pt;
744
+ }
745
+ .c101 {
746
+ color: #ffffff;
747
+ font-weight: 700;
748
+ text-decoration: none;
749
+ vertical-align: baseline;
750
+ font-size: 10pt;
751
+ font-family: "Arial";
752
+ font-style: normal;
753
+ }
754
+ .c2 {
755
+ color: #000000;
756
+ font-weight: 400;
757
+ text-decoration: none;
758
+ vertical-align: baseline;
759
+ font-size: 12pt;
760
+ font-family: "Times New Roman";
761
+ font-style: normal;
762
+ }
763
+ .c3 {
764
+ color: #000000;
765
+ font-weight: 700;
766
+ text-decoration: none;
767
+ vertical-align: baseline;
768
+ font-size: 10pt;
769
+ font-family: "Calibri";
770
+ font-style: normal;
771
+ }
772
+ .c96 {
773
+ margin-left: 4.3pt;
774
+ padding-top: 0.6pt;
775
+ text-indent: -0.2pt;
776
+ padding-bottom: 0pt;
777
+ line-height: 1.0374999999999999;
778
+ text-align: justify;
779
+ margin-right: 5.2pt;
780
+ }
781
+ .c9 {
782
+ color: #000000;
783
+ font-weight: 400;
784
+ text-decoration: none;
785
+ vertical-align: baseline;
786
+ font-size: 9pt;
787
+ font-family: "Times New Roman";
788
+ font-style: normal;
789
+ }
790
+ .c12 {
791
+ margin-left: 22.2pt;
792
+ padding-top: 0.5pt;
793
+ padding-bottom: 0pt;
794
+ line-height: 1;
795
+ padding-left: 18.1pt;
796
+ text-align: left;
797
+ }
798
+ .c47 {
799
+ margin-left: 10.3pt;
800
+ padding-top: 5.3pt;
801
+ padding-bottom: 0pt;
802
+ line-height: 1.0374999999999999;
803
+ text-align: center;
804
+ margin-right: 11.1pt;
805
+ }
806
+ .c17 {
807
+ margin-left: 40.2pt;
808
+ padding-top: 0.5pt;
809
+ padding-bottom: 0pt;
810
+ line-height: 1;
811
+ padding-left: 0pt;
812
+ text-align: left;
813
+ }
814
+ .c35 {
815
+ margin-left: 22.2pt;
816
+ padding-top: 5.2pt;
817
+ padding-bottom: 0pt;
818
+ line-height: 1;
819
+ padding-left: 18.1pt;
820
+ text-align: left;
821
+ }
822
+ .c28 {
823
+ margin-left: 40.2pt;
824
+ padding-top: 5.2pt;
825
+ padding-bottom: 0pt;
826
+ line-height: 1;
827
+ padding-left: 0pt;
828
+ text-align: left;
829
+ }
830
+ .c97 {
831
+ margin-left: 22.2pt;
832
+ padding-top: 0.6pt;
833
+ padding-bottom: 0pt;
834
+ line-height: 1;
835
+ padding-left: 18.1pt;
836
+ text-align: left;
837
+ }
838
+ .c13 {
839
+ margin-left: 4.3pt;
840
+ padding-top: 5.3pt;
841
+ padding-bottom: 0pt;
842
+ line-height: 1.0374999999999999;
843
+ text-indent: -0.2pt;
844
+ text-align: left;
845
+ }
846
+ .c91 {
847
+ margin-left: 40.2pt;
848
+ padding-top: 0.3pt;
849
+ padding-bottom: 0pt;
850
+ line-height: 1;
851
+ padding-left: 0pt;
852
+ text-align: left;
853
+ }
854
+ .c65 {
855
+ margin-left: 4.8pt;
856
+ padding-top: 5.3pt;
857
+ padding-bottom: 0pt;
858
+ line-height: 1.0291666666666666;
859
+ text-indent: -0.2pt;
860
+ text-align: left;
861
+ }
862
+ .c90 {
863
+ margin-left: 16pt;
864
+ padding-top: 1.1pt;
865
+ padding-bottom: 0pt;
866
+ line-height: 0.6958333333333333;
867
+ text-align: left;
868
+ margin-right: -2.2pt;
869
+ }
870
+ .c57 {
871
+ margin-left: 0.6pt;
872
+ padding-top: 1.1pt;
873
+ padding-bottom: 0pt;
874
+ line-height: 0.7000000000000001;
875
+ text-align: left;
876
+ margin-right: -2.9pt;
877
+ }
878
+ .c36 {
879
+ margin-left: 4.2pt;
880
+ padding-top: 0.1pt;
881
+ padding-bottom: 0pt;
882
+ line-height: 1;
883
+ text-align: left;
884
+ }
885
+ .c92 {
886
+ margin-left: 4.8pt;
887
+ padding-top: 5.2pt;
888
+ padding-bottom: 0pt;
889
+ line-height: 1;
890
+ text-align: left;
891
+ }
892
+ .c69 {
893
+ margin-left: 19.5pt;
894
+ padding-top: 11.3pt;
895
+ padding-bottom: 0pt;
896
+ line-height: 1;
897
+ text-align: left;
898
+ }
899
+ .c83 {
900
+ margin-left: 399.5pt;
901
+ padding-top: 0.1pt;
902
+ padding-bottom: 0pt;
903
+ line-height: 1;
904
+ text-align: justify;
905
+ }
906
+ .c45 {
907
+ margin-left: 398.5pt;
908
+ padding-top: 0.1pt;
909
+ padding-bottom: 0pt;
910
+ line-height: 1;
911
+ text-align: justify;
912
+ }
913
+ .c55 {
914
+ padding-top: 5.3pt;
915
+ padding-bottom: 0pt;
916
+ line-height: 1;
917
+ text-align: center;
918
+ margin-right: 0.6pt;
919
+ }
920
+ .c103 {
921
+ margin-left: 4.2pt;
922
+ padding-top: 5.3pt;
923
+ padding-bottom: 0pt;
924
+ line-height: 1;
925
+ text-align: left;
926
+ }
927
+ .c21 {
928
+ margin-left: 4.2pt;
929
+ padding-top: 0.5pt;
930
+ padding-bottom: 0pt;
931
+ line-height: 1;
932
+ text-align: justify;
933
+ }
934
+ .c6 {
935
+ padding-top: 5.3pt;
936
+ padding-bottom: 0pt;
937
+ line-height: 1;
938
+ text-align: center;
939
+ margin-right: 0.3pt;
940
+ }
941
+ .c33 {
942
+ padding-top: 5.3pt;
943
+ padding-bottom: 0pt;
944
+ line-height: 1;
945
+ text-align: center;
946
+ margin-right: 0.4pt;
947
+ }
948
+ .c4 {
949
+ padding-top: 0pt;
950
+ padding-bottom: 0pt;
951
+ line-height: 1;
952
+ text-align: left;
953
+ height: 11pt;
954
+ }
955
+ .c77 {
956
+ padding-top: 5.3pt;
957
+ padding-bottom: 0pt;
958
+ line-height: 1;
959
+ text-align: center;
960
+ margin-right: 0.7pt;
961
+ }
962
+ .c7 {
963
+ margin-left: 398.5pt;
964
+ padding-top: 0pt;
965
+ padding-bottom: 0pt;
966
+ line-height: 1;
967
+ text-align: justify;
968
+ }
969
+ .c89 {
970
+ margin-left: 398.5pt;
971
+ padding-top: 0pt;
972
+ padding-bottom: 0pt;
973
+ line-height: 1.0125;
974
+ text-align: justify;
975
+ }
976
+ .c75 {
977
+ margin-left: 4.8pt;
978
+ padding-top: 5.3pt;
979
+ padding-bottom: 0pt;
980
+ line-height: 1;
981
+ text-align: left;
982
+ }
983
+ .c0 {
984
+ margin-left: 4.5pt;
985
+ padding-top: 0.6pt;
986
+ padding-bottom: 0pt;
987
+ line-height: 1.0374999999999999;
988
+ text-align: left;
989
+ }
990
+ .c95 {
991
+ margin-left: 4.3pt;
992
+ padding-top: 5.3pt;
993
+ padding-bottom: 0pt;
994
+ line-height: 1;
995
+ text-align: left;
996
+ }
997
+ .c39 {
998
+ margin-left: 4.5pt;
999
+ padding-top: 5.3pt;
1000
+ padding-bottom: 0pt;
1001
+ line-height: 1;
1002
+ text-align: left;
1003
+ }
1004
+ .c87 {
1005
+ padding-top: 5.3pt;
1006
+ padding-bottom: 0pt;
1007
+ line-height: 1;
1008
+ text-align: center;
1009
+ margin-right: 0.2pt;
1010
+ }
1011
+ .c88 {
1012
+ margin-left: 4.2pt;
1013
+ padding-top: 5.3pt;
1014
+ padding-bottom: 0pt;
1015
+ line-height: 1;
1016
+ text-align: justify;
1017
+ }
1018
+ .c93 {
1019
+ margin-left: 48.5pt;
1020
+ padding-top: 5.3pt;
1021
+ padding-bottom: 0pt;
1022
+ line-height: 1;
1023
+ text-align: left;
1024
+ }
1025
+ .c81 {
1026
+ margin-left: 10.1pt;
1027
+ padding-top: 5.3pt;
1028
+ padding-bottom: 0pt;
1029
+ line-height: 1;
1030
+ text-align: left;
1031
+ }
1032
+ .c53 {
1033
+ margin-left: 18.9pt;
1034
+ padding-top: 5.3pt;
1035
+ padding-bottom: 0pt;
1036
+ line-height: 1;
1037
+ text-align: left;
1038
+ }
1039
+ .c58 {
1040
+ margin-left: 11.3pt;
1041
+ padding-top: 5.3pt;
1042
+ padding-bottom: 0pt;
1043
+ line-height: 1;
1044
+ text-align: left;
1045
+ }
1046
+ .c8 {
1047
+ padding-top: 0pt;
1048
+ padding-bottom: 0pt;
1049
+ line-height: 1.15;
1050
+ text-align: left;
1051
+ height: 11pt;
1052
+ }
1053
+ .c42 {/*logo*/
1054
+ text-align: center;
1055
+ padding: 0 0 0 40px;
1056
+ margin-right: 5px;
1057
+ overflow: hidden;
1058
+ }
1059
+ .c82 {
1060
+ padding-top: 12.9pt;
1061
+ padding-bottom: 0pt;
1062
+ line-height: 1;
1063
+ text-align: left;
1064
+ }
1065
+ .c38 {
1066
+ margin-left: 15px;
1067
+ border-spacing: 0;
1068
+ border-collapse: collapse;
1069
+ margin-right: auto;
1070
+ }
1071
+ .c79 {
1072
+ color: #7e7e7e;
1073
+ font-size: 12pt;
1074
+ font-weight: 700;
1075
+ }
1076
+ .c71 {
1077
+ background-color: #ffffff;
1078
+ max-width: 576pt;
1079
+ padding: 65pt 18pt 14pt 18pt;
1080
+ }
1081
+ .c70 {
1082
+ padding: 0;
1083
+ margin: 0;
1084
+ }
1085
+ .c41 {
1086
+ height: 81pt;
1087
+ }
1088
+ .c56 {
1089
+ margin-right: 19.3pt;
1090
+ }
1091
+ .c50 {
1092
+ height: 38pt;
1093
+ }
1094
+ .c68 {
1095
+ height: 35.6pt;
1096
+ }
1097
+ .c94 {
1098
+ height: 282.2pt;
1099
+ }
1100
+ .c98 {
1101
+ height: 10.5pt;
1102
+ }
1103
+ .c78 {
1104
+ height: 24.3pt;
1105
+ }
1106
+ .c85 {
1107
+ height: 66.1pt;
1108
+ }
1109
+ .c66 {
1110
+ margin-left: 0.1pt;
1111
+ }
1112
+ .c84 {
1113
+ height: 24.2pt;
1114
+ }
1115
+ .c73 {
1116
+ height: 50.2pt;
1117
+ }
1118
+ .c54 {
1119
+ margin-right: 34.5pt;
1120
+ }
1121
+ .c26 {
1122
+ margin-right: 3.8pt;
1123
+ }
1124
+ .c100 {
1125
+ height: 62.5pt;
1126
+ }
1127
+ .title {
1128
+ padding-top: 24pt;
1129
+ color: #000000;
1130
+ font-weight: 700;
1131
+ font-size: 36pt;
1132
+ padding-bottom: 6pt;
1133
+ font-family: "Calibri";
1134
+ line-height: 1;
1135
+ page-break-after: avoid;
1136
+ text-align: left;
1137
+ }
1138
+ .subtitle {
1139
+ padding-top: 18pt;
1140
+ color: #666666;
1141
+ font-size: 24pt;
1142
+ padding-bottom: 4pt;
1143
+ font-family: "Georgia";
1144
+ line-height: 1;
1145
+ page-break-after: avoid;
1146
+ font-style: italic;
1147
+ text-align: left;
1148
+ }
1149
+ li {
1150
+ color: #000000;
1151
+ font-size: 11pt;
1152
+ font-family: "Calibri";
1153
+ }
1154
+ p {
1155
+ margin: 0;
1156
+ color: #000000;
1157
+ font-size: 11pt;
1158
+ font-family: "Calibri";
1159
+ }
1160
+ h1 {
1161
+ padding-top: 24pt;
1162
+ color: #000000;
1163
+ font-weight: 700;
1164
+ font-size: 24pt;
1165
+ padding-bottom: 6pt;
1166
+ font-family: "Calibri";
1167
+ line-height: 1;
1168
+ page-break-after: avoid;
1169
+ text-align: left;
1170
+ }
1171
+ h2 {
1172
+ padding-top: 18pt;
1173
+ color: #000000;
1174
+ font-weight: 700;
1175
+ font-size: 18pt;
1176
+ padding-bottom: 4pt;
1177
+ font-family: "Calibri";
1178
+ line-height: 1;
1179
+ page-break-after: avoid;
1180
+ text-align: left;
1181
+ }
1182
+ h3 {
1183
+ padding-top: 14pt;
1184
+ color: #000000;
1185
+ font-weight: 700;
1186
+ font-size: 14pt;
1187
+ padding-bottom: 4pt;
1188
+ font-family: "Calibri";
1189
+ line-height: 1;
1190
+ page-break-after: avoid;
1191
+ text-align: left;
1192
+ }
1193
+ h4 {
1194
+ padding-top: 12pt;
1195
+ color: #000000;
1196
+ font-weight: 700;
1197
+ font-size: 12pt;
1198
+ padding-bottom: 2pt;
1199
+ font-family: "Calibri";
1200
+ line-height: 1;
1201
+ page-break-after: avoid;
1202
+ text-align: left;
1203
+ }
1204
+ h5 {
1205
+ padding-top: 11pt;
1206
+ color: #000000;
1207
+ font-weight: 700;
1208
+ font-size: 11pt;
1209
+ padding-bottom: 2pt;
1210
+ font-family: "Calibri";
1211
+ line-height: 1;
1212
+ page-break-after: avoid;
1213
+ text-align: left;
1214
+ }
1215
+ h6 {
1216
+ padding-top: 10pt;
1217
+ color: #000000;
1218
+ font-weight: 700;
1219
+ font-size: 10pt;
1220
+ padding-bottom: 2pt;
1221
+ font-family: "Calibri";
1222
+ line-height: 1;
1223
+ page-break-after: avoid;
1224
+ text-align: left;
1225
+ }
1226
+ </style>
1227
+ <style>
1228
+ .page-footer {
1229
+ background: #000;
1230
+ display: flex;
1231
+ align-items: center;
1232
+ padding: 4pt 16pt;
1233
+ }
1234
+ .footer-text {
1235
+ color: #fff;
1236
+ font-weight: 700;
1237
+ font-size: 10pt;
1238
+ font-family: Arial, sans-serif;
1239
+ white-space: nowrap;
1240
+ }
1241
+ </style>
1242
+ </head>
1243
+ <body class="c71 doc-content">
1244
+ <div>
1245
+ <p class="c42">
1246
+ <span
1247
+ style="
1248
+ overflow: hidden;
1249
+ display: inline-block;
1250
+ margin: 0px 0px;
1251
+ border: 0px solid #000000;
1252
+ transform: rotate(0rad) translateZ(0px);
1253
+ -webkit-transform: rotate(0rad) translateZ(0px);
1254
+ width: 41.07px;
1255
+ height: 49.96px;
1256
+ float: left;
1257
+ "
1258
+ ><img
1259
+ alt
1260
+ src="images/image2.png"
1261
+ style="
1262
+ width: 41.07px;
1263
+ height: 49.96px;
1264
+ margin-left: 0px;
1265
+ margin-top: 0px;
1266
+ transform: rotate(0rad) translateZ(0px);
1267
+ -webkit-transform: rotate(0rad) translateZ(0px);
1268
+ "
1269
+ title /></span
1270
+ ><span
1271
+ style="
1272
+ overflow: hidden;
1273
+ display: inline-block;
1274
+ margin: 25px 0px 0px -75px;
1275
+ border: 0px solid #000000;
1276
+ transform: rotate(0rad) translateZ(0px);
1277
+ -webkit-transform: rotate(0rad) translateZ(0px);
1278
+ width: 264.73px;
1279
+ height: 19.87px;
1280
+ "
1281
+ ><img
1282
+ alt
1283
+ src="images/image1.png"
1284
+ style="
1285
+ width: 264.73px;
1286
+ height: 19.87px;
1287
+ margin-left: 0px;
1288
+ margin-top: 0px;
1289
+ transform: rotate(0rad) translateZ(0px);
1290
+ -webkit-transform: rotate(0rad) translateZ(0px);
1291
+ "
1292
+ title
1293
+ /></span>
1294
+ </p>
1295
+ </div>
1296
+ <p class="c4"><span class="c2"></span></p>
1297
+ <table class="c38">
1298
+ <tr class="c78">
1299
+ <td class="c18" colspan="1" rowspan="9">
1300
+ <p class="c4"><span class="c9"></span></p>
1301
+ </td>
1302
+ <td class="c5" colspan="1" rowspan="1">
1303
+ <p class="c58"><span class="c3">Course Code</span></p>
1304
+ </td>
1305
+ <td class="c20" colspan="1" rowspan="1">
1306
+ <p class="c93"><span class="c3">{{ course.course_code }}</span></p>
1307
+ </td>
1308
+ <td class="c23" colspan="1" rowspan="1">
1309
+ <p class="c81"><span class="c3">Course Title</span></p>
1310
+ </td>
1311
+ <td class="c64" colspan="5" rowspan="1">
1312
+ <p class="c53">
1313
+ <span class="c3">{{ course.course_title }}</span>
1314
+ </p>
1315
+ </td>
1316
+ <td class="c29" colspan="1" rowspan="9">
1317
+ <p class="c4"><span class="c9"></span></p>
1318
+ </td>
1319
+ </tr>
1320
+ <tr class="c84">
1321
+ <td class="c5" colspan="1" rowspan="2">
1322
+ <p class="c69"><span class="c3">Program</span></p>
1323
+ </td>
1324
+ <td class="c20" colspan="1" rowspan="2">
1325
+ <p class="c77"><span class="c1">{{ course.program }}</span></p>
1326
+ </td>
1327
+ <td class="c23" colspan="1" rowspan="2">
1328
+ <p class="c47">
1329
+ <span class="c3">Hours per week/ Credit Assigned</span>
1330
+ </p>
1331
+ </td>
1332
+ <td class="c59" colspan="1" rowspan="1">
1333
+ <p class="c55 c66"><span class="c3">L</span></p>
1334
+ </td>
1335
+ <td class="c15" colspan="1" rowspan="1">
1336
+ <p class="c6"><span class="c3">T</span></p>
1337
+ </td>
1338
+ <td class="c14" colspan="1" rowspan="1">
1339
+ <p class="c87 c66"><span class="c3">P</span></p>
1340
+ </td>
1341
+ <td class="c22" colspan="1" rowspan="1">
1342
+ <p class="c6 c66"><span class="c3">S</span></p>
1343
+ </td>
1344
+ <td class="c43" colspan="1" rowspan="1">
1345
+ <p class="c33"><span class="c3">C</span></p>
1346
+ </td>
1347
+ </tr>
1348
+ <tr class="c68">
1349
+ <td class="c59" colspan="1" rowspan="1">
1350
+ <p class="c55"><span class="c3">{{ course.lecture_hours }}</span></p>
1351
+ </td>
1352
+ <td class="c15" colspan="1" rowspan="1">
1353
+ <p class="c6 c66"><span class="c3">{{ course.tutorial_hours }}</span></p>
1354
+ </td>
1355
+ <td class="c14" colspan="1" rowspan="1">
1356
+ <p class="c87"><span class="c3">{{ course.practical_hours }}</span></p>
1357
+ </td>
1358
+ <td class="c22" colspan="1" rowspan="1">
1359
+ <p class="c6"><span class="c3">{{ course.self_study }}</span></p>
1360
+ </td>
1361
+ <td class="c43" colspan="1" rowspan="1">
1362
+ <p class="c33"><span class="c3">{{ course.credits }}</span></p>
1363
+ </td>
1364
+ </tr>
1365
+ <tr class="c50">
1366
+ <td class="c5" colspan="1" rowspan="1">
1367
+ <p class="c95"><span class="c3">Semester</span></p>
1368
+ </td>
1369
+ <td class="c20" colspan="1" rowspan="1">
1370
+ <p class="c103"><span class="c1">{{ course.semester }}</span></p>
1371
+ </td>
1372
+ <td class="c23" colspan="1" rowspan="1">
1373
+ <p class="c13 c54"><span class="c3">Type of Course</span></p>
1374
+ </td>
1375
+ <td class="c64" colspan="5" rowspan="1">
1376
+ <p class="c39"><span class="c1">{{ course.course_type }}</span></p>
1377
+ </td>
1378
+ </tr>
1379
+ <tr class="c73">
1380
+ <td class="c5" colspan="1" rowspan="1">
1381
+ <p class="c95"><span class="c3">AI Tools</span></p>
1382
+ <p class="c0"><span class="c3">/Tools/Languag es</span></p>
1383
+ </td>
1384
+ <td class="c20" colspan="1" rowspan="1">
1385
+ <p class="c13">
1386
+ <span class="c1">{{ course.tools_languages }}</span>
1387
+ </p>
1388
+ </td>
1389
+ <td class="c23" colspan="1" rowspan="1">
1390
+ <p class="c13 c56"><span class="c3">Desirable Knowledge</span></p>
1391
+ </td>
1392
+ <td class="c64" colspan="5" rowspan="1">
1393
+ <p class="c39"><span class="c1">{{ course.desirable_knowledge }}</span></p>
1394
+ </td>
1395
+ </tr>
1396
+ <tr class="c85">
1397
+ <td class="c5" colspan="1" rowspan="1">
1398
+ <p class="c75"><span class="c3">Prelude</span></p>
1399
+ </td>
1400
+ <td class="c44" colspan="7" rowspan="1">
1401
+ <p class="c13 c26">
1402
+ <span class="c1">{{ course.prelude }}</span>
1403
+ </p>
1404
+ </td>
1405
+ </tr>
1406
+ <tr class="c41">
1407
+ <td class="c5" colspan="1" rowspan="1">
1408
+ <p class="c65"><span class="c3">Course Objectives:</span></p>
1409
+ </td>
1410
+ <td class="c44" colspan="7" rowspan="1">
1411
+ <ul class="c70 lst-kix_list_2-0 start">
1412
+ {% for obj in course.objectives %}
1413
+ <li class="c28 li-bullet-0">
1414
+ <span class="c1">{{ obj }}</span>
1415
+ </li>
1416
+ {% endfor %}
1417
+ </ul>
1418
+ </td>
1419
+ </tr>
1420
+ <tr class="c94">
1421
+ <td class="c5" colspan="1" rowspan="1">
1422
+ <p class="c40"><span class="c3">Course Contents</span></p>
1423
+ </td>
1424
+ <td class="c44" colspan="7" rowspan="1">
1425
+ {% for unit in course.units %}
1426
+ <p class="c88"><span class="c3">{{ unit.title }}</span></p>
1427
+ <p class="c25">
1428
+ <span class="c1">{{ unit.content }}</span>
1429
+ </p>
1430
+ <p class="c7"><span class="c3">{{ unit.hours }} Hours</span></p>
1431
+ {% endfor %}
1432
+ </td>
1433
+ </tr>
1434
+ <tr class="c100">
1435
+ <td class="c31" colspan="1" rowspan="1">
1436
+ <p class="c92"><span class="c3">Laboratory</span></p>
1437
+ </td>
1438
+ <td class="c32" colspan="7" rowspan="1">
1439
+ <ol class="c70 lst-kix_list_1-0 start">
1440
+ {% for exp in course.lab_experiments %}
1441
+ <li class="c35 li-bullet-1">
1442
+ <span class="c1">{{ exp }}</span>
1443
+ </li>
1444
+ {% endfor %}
1445
+ </ol>
1446
+ </td>
1447
+ </tr>
1448
+ </table>
1449
+
1450
+ <div class="page-footer">
1451
+ <span class="footer-text">P.E.S. University                                                  Curriculum :- 2025-2026</span>
1452
+ <span class="footer-text" style="margin-left: auto">{{ page_number }}</span>
1453
+ </div>
1454
+ </body>
1455
+ </html>
1456
+
frontend/images/image1.png ADDED
frontend/images/image2.png ADDED
frontend/index.html ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Course Submission — PESU</title>
7
+ <link rel="stylesheet" href="styles.css" />
8
+ <script src="script.js" defer></script>
9
+ </head>
10
+ <body>
11
+ <div class="container">
12
+ <div class="card">
13
+ <h1>Course Submission</h1>
14
+ <p class="subtitle">Fill in the course details below.</p>
15
+
16
+ <form id="course-form">
17
+ <fieldset>
18
+ <legend>Faculty Details</legend>
19
+
20
+ <label for="faculty_email">Email</label>
21
+ <input type="email" id="faculty_email" name="faculty_email" required />
22
+
23
+ <label for="offering_department">Offering Department</label>
24
+
25
+ <select id="offering_department" name="offering_department" required>
26
+ <option value="">Select offering department</option>
27
+ <option value="MA">Mathematics (MA)</option>
28
+ <option value="CS">Computer Science (CS)</option>
29
+ <option value="UZ">(UZ)</option>
30
+ </select>
31
+
32
+ <span class="hint">e.g. Mathematics, Computer Science (MA, CS)</span>
33
+
34
+ </fieldset>
35
+
36
+ <fieldset>
37
+ <legend>Course Details</legend>
38
+
39
+ <label for="target_department">Target Department / Program</label>
40
+ <select id="target_department" name="target_department" required>
41
+ <option value="">Select target department</option>
42
+ <option value="CSE">Computer Science and Engineering (CSE)</option>
43
+ <option value="AIML">Artificial Intelligence and Machine Learning (AIML)</option>
44
+ <option value="ECE">Electronics and Communication Engineering (ECE)</option>
45
+ <option value="ME">Mechanical Engineering (ME)</option>
46
+ <option value="EEE">Electronics and Electrical Engineering (EEE)</option>
47
+ <option value="BT">Biotechnology (BT)</option>
48
+ </select>
49
+
50
+ <label for="semester">Semester</label>
51
+ <select id="semester" name="semester" required>
52
+ <option value="">Select semester</option>
53
+ <option value="1">Semester 1</option>
54
+ <option value="2">Semester 2</option>
55
+ <option value="3">Semester 3</option>
56
+ <option value="4">Semester 4</option>
57
+ <option value="5">Semester 5</option>
58
+ <option value="6">Semester 6</option>
59
+ <option value="7">Semester 7</option>
60
+ <option value="8">Semester 8</option>
61
+ </select>
62
+
63
+ <label for="course_title">Course Title</label>
64
+ <input type="text" id="course_title" name="course_title" required />
65
+
66
+ <label for="credit_category">Credit Category</label>
67
+ <select id="credit_category" name="credit_category" required>
68
+ <option value="">Select credit category</option>
69
+ <option value="0">0 Credits</option>
70
+ <option value="2">2 Credits</option>
71
+ <option value="4">4 Credits</option>
72
+ <option value="5">5 Credits</option>
73
+ </select>
74
+ </fieldset>
75
+
76
+ <fieldset>
77
+ <legend>Academic Content</legend>
78
+ <label for="raw_course_content">Course Content</label>
79
+ <textarea id="raw_course_content" name="raw_course_content" rows="8" required></textarea>
80
+ <span class="hint">Topics, units, or rough syllabus.</span>
81
+
82
+ <label for="text_books">Textbook References</label>
83
+ <textarea id="text_books" name="text_books" rows="4" required></textarea>
84
+
85
+ <label for="reference_books">Other Suggested Reference Books <span class="optional">(optional)</span></label>
86
+ <textarea id="reference_books" name="reference_books" rows="4"></textarea>
87
+
88
+ <label for="preferred_tools">Preferred Tools / Languages <span class="optional">(optional)</span></label>
89
+ <textarea id="preferred_tools" name="preferred_tools" rows="3"></textarea>
90
+ </fieldset>
91
+
92
+ <button type="submit" id="submit-btn">Submit Course</button>
93
+ <a href="preview.html?sem=1" style="display:block;text-align:center;margin-top:8px;color:#00377b;font-size:13px">View Preview (test)</a>
94
+ </form>
95
+
96
+ <div id="result" class="hidden"></div>
97
+ </div>
98
+ </div>
99
+ </body>
100
+ </html>
frontend/preview.html ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width,initial-scale=1.0">
6
+ <title>Curriculum Preview</title>
7
+ <style>
8
+ body{margin:0;background:#525659}
9
+ iframe{width:100%;height:100vh;border:none}
10
+ </style>
11
+ </head>
12
+ <body>
13
+ <iframe src="/api/preview/semester/1/pdf"></iframe>
14
+ <script>
15
+ const sem=new URLSearchParams(location.search).get("sem")||"1";
16
+ document.querySelector("iframe").src="/api/preview/semester/"+sem+"/pdf";
17
+ </script>
18
+ </body>
19
+ </html>
frontend/script.js ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ document.addEventListener("DOMContentLoaded", () => {
2
+ const form = document.getElementById("course-form");
3
+ const result = document.getElementById("result");
4
+ const btn = document.getElementById("submit-btn");
5
+
6
+ form.addEventListener("submit", async (e) => {
7
+ e.preventDefault();
8
+ result.className = "hidden";
9
+
10
+ const data = Object.fromEntries(new FormData(form));
11
+
12
+ btn.disabled = true;
13
+ btn.textContent = "Submitting...";
14
+
15
+ try {
16
+ const res = await fetch("/api/submissions", {
17
+ method: "POST",
18
+ headers: { "Content-Type": "application/json" },
19
+ body: JSON.stringify(data),
20
+ });
21
+
22
+ const body = await res.json();
23
+
24
+ if (!res.ok) {
25
+ const msgs = body.detail?.map(e => e.msg) ?? [];
26
+ result.textContent = msgs.join("\n");
27
+ result.className = "error";
28
+ } else {
29
+ result.textContent = "Submission received.";
30
+ result.className = "success";
31
+ }
32
+ } catch {
33
+ result.textContent = "Network error. Check if the backend is running.";
34
+ result.className = "error";
35
+ } finally {
36
+ btn.disabled = false;
37
+ btn.textContent = "Submit Course";
38
+ }
39
+ });
40
+ });
frontend/styles.css ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *, *::before, *::after {
2
+ box-sizing: border-box;
3
+ margin: 0;
4
+ padding: 0;
5
+ }
6
+
7
+ :root {
8
+ --bg: #f0f2f5;
9
+ --surface: #ffffff;
10
+ --border: #d4d8dd;
11
+ --text: #00377b;
12
+ --text-secondary: #5a6b8a;
13
+ --accent: #ff6c00;
14
+ --accent-hover: #e05e00;
15
+ --optional: #8a9bb5;
16
+ --success: #166534;
17
+ --success-bg: #f0fdf4;
18
+ --error: #991b1b;
19
+ --error-bg: #fef2f2;
20
+ }
21
+
22
+ body {
23
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
24
+ background: var(--bg);
25
+ color: var(--text);
26
+ line-height: 1.6;
27
+ min-height: 100dvh;
28
+ display: flex;
29
+ align-items: center;
30
+ justify-content: center;
31
+ padding: 1rem;
32
+ }
33
+
34
+ .container {
35
+ width: 100%;
36
+ max-width: 640px;
37
+ }
38
+
39
+ .card {
40
+ background: var(--surface);
41
+ border: 1px solid var(--border);
42
+ border-radius: 12px;
43
+ padding: 2rem;
44
+ }
45
+
46
+ h1 {
47
+ font-size: 1.5rem;
48
+ font-weight: 700;
49
+ margin-bottom: 0.25rem;
50
+ }
51
+
52
+ .subtitle {
53
+ color: var(--text-secondary);
54
+ font-size: 0.875rem;
55
+ margin-bottom: 1.5rem;
56
+ }
57
+
58
+ fieldset {
59
+ border: none;
60
+ margin-bottom: 1.5rem;
61
+ }
62
+
63
+ legend {
64
+ font-weight: 600;
65
+ font-size: 1.125rem;
66
+ margin-bottom: 1rem;
67
+ padding-bottom: 0.5rem;
68
+ border-bottom: 1px solid var(--border);
69
+ width: 100%;
70
+ }
71
+
72
+ label {
73
+ display: block;
74
+ font-size: 0.875rem;
75
+ font-weight: 500;
76
+ margin-top: 1rem;
77
+ margin-bottom: 0.25rem;
78
+ }
79
+
80
+ input, select, textarea {
81
+ width: 100%;
82
+ padding: 0.5rem 0.75rem;
83
+ border: 1px solid var(--border);
84
+ border-radius: 6px;
85
+ font-size: 0.875rem;
86
+ font-family: inherit;
87
+ background: var(--surface);
88
+ color: var(--text);
89
+ transition: border-color 0.15s;
90
+ }
91
+
92
+ input:focus, select:focus, textarea:focus {
93
+ outline: none;
94
+ border-color: var(--accent);
95
+ }
96
+
97
+ textarea {
98
+ resize: vertical;
99
+ }
100
+
101
+ .hint {
102
+ display: block;
103
+ font-size: 0.75rem;
104
+ color: var(--text-secondary);
105
+ margin-top: 0.25rem;
106
+ }
107
+
108
+ .optional {
109
+ color: var(--optional);
110
+ font-weight: 400;
111
+ font-size: 0.75rem;
112
+ }
113
+
114
+ button {
115
+ width: 100%;
116
+ padding: 0.625rem;
117
+ border: none;
118
+ border-radius: 6px;
119
+ background: var(--accent);
120
+ color: var(--bg);
121
+ font-size: 0.875rem;
122
+ font-weight: 600;
123
+ cursor: pointer;
124
+ margin-top: 1rem;
125
+ transition: background 0.15s;
126
+ }
127
+
128
+ button:hover {
129
+ background: var(--accent-hover);
130
+ }
131
+
132
+ button:disabled {
133
+ opacity: 0.5;
134
+ cursor: not-allowed;
135
+ }
136
+
137
+ #result {
138
+ margin-top: 1rem;
139
+ padding: 1rem;
140
+ border-radius: 6px;
141
+ font-size: 0.875rem;
142
+ white-space: pre-wrap;
143
+ }
144
+
145
+ #result.success {
146
+ background: var(--success-bg);
147
+ color: var(--success);
148
+ border: 1px solid var(--success);
149
+ }
150
+
151
+ #result.error {
152
+ background: var(--error-bg);
153
+ color: var(--error);
154
+ border: 1px solid var(--error);
155
+ }
156
+
157
+ .hidden {
158
+ display: none;
159
+ }
frontend/vercel.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "rewrites":[
3
+ {
4
+ "source": "/api/(.*)",
5
+ "destination": "https://lonelyguyse1-curriculum-backend.hf.space/api/$1"
6
+ }
7
+ ]
8
+ }
requirements.txt ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ annotated-doc==0.0.4
2
+ annotated-types==0.7.0
3
+ anyio==4.14.1
4
+ certifi==2026.6.17
5
+ cffi==2.0.0
6
+ click==8.4.2
7
+ cryptography==49.0.0
8
+ deprecation==2.1.0
9
+ detect-installer==0.1.0
10
+ dnspython==2.8.0
11
+ email-validator==2.3.0
12
+ fastapi==0.138.0
13
+ fastapi-cli==0.0.27
14
+ fastapi-cloud-cli==0.21.0
15
+ fastar==0.11.0
16
+ h11==0.16.0
17
+ h2==4.3.0
18
+ hpack==4.2.0
19
+ httpcore==1.0.9
20
+ httptools==0.8.0
21
+ httpx==0.28.1
22
+ hyperframe==6.1.0
23
+ idna==3.18
24
+ iniconfig==2.3.0
25
+ Jinja2==3.1.6
26
+ markdown-it-py==4.2.0
27
+ MarkupSafe==3.0.3
28
+ mdurl==0.1.2
29
+ multidict==6.7.1
30
+ packaging==26.2
31
+ pluggy==1.6.0
32
+ postgrest==2.31.0
33
+ propcache==0.5.2
34
+ pycparser==3.0
35
+ pydantic==2.13.4
36
+ pydantic-extra-types==2.11.1
37
+ pydantic-settings==2.14.2
38
+ pydantic_core==2.46.4
39
+ Pygments==2.20.0
40
+ PyJWT==2.13.0
41
+ pytest==9.1.1
42
+ python-dotenv==1.2.2
43
+ python-multipart==0.0.32
44
+ PyYAML==6.0.3
45
+ realtime==2.31.0
46
+ rich==15.0.0
47
+ rich-toolkit==0.20.1
48
+ rignore==0.7.6
49
+ ruff==0.15.19
50
+ sentry-sdk==2.63.0
51
+ shellingham==1.5.4
52
+ starlette==1.3.1
53
+ storage3==2.31.0
54
+ StrEnum==0.4.15
55
+ supabase==2.31.0
56
+ supabase-auth==2.31.0
57
+ supabase-functions==2.31.0
58
+ typer==0.26.7
59
+ typing-inspection==0.4.2
60
+ typing_extensions==4.15.0
61
+ urllib3==2.7.0
62
+ uvicorn==0.49.0
63
+ uvloop==0.22.1
64
+ watchfiles==1.2.0
65
+ websockets==15.0.1
66
+ yarl==1.24.2