Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

101 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AI V&V Lab Website

CI codecov

Lab website for the AI Verification & Validation Lab at ai-vnv.kfupm.io.

Built with Jekyll. Hosted on GitHub Pages.

Local Development

bundle install
bundle exec jekyll serve
# Open http://localhost:4000

Structure

_config.yml          # Jekyll configuration
_data/               # YAML data files (publications, research areas, team, news)
_includes/           # HTML partials (head, nav, footer, seo)
_layouts/            # Page layouts (default, page)
_tikz/               # TikZ .tex source files for figures
_julia/              # Julia scripts for generated SVG/PDF figures
_scripts/            # Build scripts (build-tikz.sh, build-julia.sh)
assets/css/          # Stylesheets (main.css, apply.css, deadlines.css, review.css, post.css)
assets/js/           # JavaScript (main.js, apply.js, apply-i18n.js, deadlines.js, review.js)
assets/img/          # Images and generated SVG patterns
pdfs/                # Talk slides and paper PDFs
index.html           # Home page
research.html        # Research areas
team.html            # Team members
publications.html    # Publications
apply.html           # Application form
deadlines.html       # AI deadlines calendar with submission form
review.html          # Candidate review dashboard (login-gated)
contact.html         # Contact info
blog.html            # Blog index
resources.html       # Interactive notebooks and tools
CNAME                # Custom domain

Building TikZ Figures

TikZ source files live in _tikz/. To compile them into PDF, PNG, and SVG:

# Build all figures
./_scripts/build-tikz.sh

# Build a specific figure (name without .tex extension)
./_scripts/build-tikz.sh research-overview

Outputs:

  • _tikz/<name>.pdf -- vector PDF (source of truth)
  • assets/img/<name>.png -- 300 DPI raster for web
  • assets/img/<name>.svg -- scalable vector for web

Requires: pdflatex, pdftoppm, pdftocairo (from poppler).

Building Julia Figures

Julia scripts live in _julia/ (with its own Project.toml). Some use GMT.jl for map figures, others generate SVG directly.

# Build all Julia/GMT figures (PDF -> PNG/SVG pipeline)
./_scripts/build-julia.sh

# Build a specific GMT figure (name without .jl extension)
./_scripts/build-julia.sh supply_chain_network

Scripts that output SVG directly (no PDF intermediate):

cd _julia && julia --project=. surface_terrain.jl
cp _julia/surface_terrain.svg assets/img/surface-terrain.svg

cd _julia && julia --project=. pattern_desert.jl
cp _julia/pattern_desert.svg assets/img/pattern-desert.svg

cd _julia && julia --project=. pattern_footer.jl
cp _julia/pattern_footer.svg assets/img/pattern-footer.svg

Current Julia figures:

  • supply_chain_network.jl -- critical mineral supply chain map (GMT.jl)
  • surface_terrain.jl -- 3D wireframe terrain with path selection and robot agents
  • pattern_desert.jl -- desert terrain background pattern for hero section
  • pattern_footer.jl -- terrain background pattern for footer

Requires: julia, and pdftoppm/pdftocairo (from poppler) for GMT figures.

AI Deadlines Calendar

Public deadline tracker at /deadlines showing upcoming AI conference, workshop, grant, and journal deadlines. Features:

  • Card grid with countdown timers, category filters, and text search
  • Calendar export: download .ics files or add individual events to Google Calendar
  • Community submissions: anyone can submit a deadline via the form; submissions require admin email approval (click-to-approve/reject links)
  • Backend: reuses the same FastAPI backend and Google Sheet (separate "Deadlines" tab) as the application form

Backend Endpoints (Deadlines)

Method Path Auth Description
GET /api/deadlines Public List all approved deadlines
POST /api/deadlines/submit CAPTCHA Submit a new deadline (pending approval)
POST /api/deadlines/subscribe Public Subscribe to email reminder for a deadline
GET /api/deadlines/approve/{id}?token= HMAC Approve via email link
GET /api/deadlines/reject/{id}?token= HMAC Reject via email link
GET /api/deadlines/ics?id= Public Download .ics (single or all)
GET /api/deadlines/gcal?id= Public Redirect to Google Calendar add-event
POST /api/admin/deadlines/seed Admin Bulk-seed deadlines (auto-approved)

Updating Calendar from Google Spreadsheet

To refresh the static deadlines JSON with the latest approved entries from the Google Sheet:

cd apply-backend
python3 scripts/export_deadlines.py

This reads all approved deadlines from the Google Sheet, matches DROC conference ratings, and exports to assets/data/deadlines.json. The frontend loads this file for instant rendering, falling back to the live API for real-time updates.

To also refresh the DROC cache:

cd apply-backend
./scripts/refresh_site_data.sh

After exporting, commit the updated JSON to publish the changes:

git add assets/data/deadlines.json assets/data/deadlines.pretty.json
git commit -m "Update deadlines.json from Google Spreadsheet"
git push

Setup

  1. Create "Deadlines" and "Subscriptions" tabs in the existing Google Sheet
  2. Set APPROVAL_SECRET_KEY env var in Cloud Run (random 32+ char string)
  3. Deploy backend; sheet header rows are auto-created on first use
  4. Seed initial data: curl -X POST .../api/admin/deadlines/seed -H "x-admin-key: ..." -H "Content-Type: application/json" -d '[...]'

Candidate Review Dashboard

Secure, login-gated review interface at /review for admin, faculty, and reviewers to browse and annotate candidate applications. Not linked in the main nav — reviewers receive the URL via invitation email.

Features

  • Role-based access: Admin (full control + decisions), Faculty & Reviewer (view + annotate)
  • JWT authentication with bcrypt-hashed passwords and magic link sign-in
  • Candidate browsing with filters (position type, status) and search
  • PDF.js document viewer with page navigation and page tracking
  • Collaborative notes with three types: General (candidate-level), Document (per-document with page reference), Field (per-field annotations)
  • Admin decision workflow: accept/reject/waitlist/interview with email notifications
  • User management: admin can invite reviewers via email

Backend Endpoints (Review)

Method Path Auth Description
POST /api/review/login Public Authenticate, returns JWT
POST /api/review/magic-link Public Send magic link email
POST /api/review/magic-link/verify Token Verify magic link
POST /api/review/set-password Token First-time password setup
POST /api/review/invite Admin JWT Invite new reviewer
GET /api/review/users Admin JWT List all reviewers
GET /api/review/candidates JWT List candidates (filterable)
GET /api/review/candidates/{id} JWT Full candidate detail
GET /api/review/candidates/{id}/notes JWT All notes for a candidate
POST /api/review/candidates/{id}/notes JWT Add a note
PUT /api/review/notes/{id} JWT Edit own note
DELETE /api/review/notes/{id} JWT Delete own note
POST /api/review/candidates/{id}/decide Admin JWT Set decision

Setup

  1. Add JWT_SECRET_KEY env var in Cloud Run (random 32+ char string)
  2. Deploy backend — on first startup, admin user auto-seeded from ADMIN_EMAIL and magic link sent
  3. Click the magic link, set password, then invite other reviewers from the dashboard

Data Storage

Uses two new Google Sheet tabs in the existing spreadsheet:

  • ReviewUsers: user accounts (email, name, role, bcrypt hash, verified status)
  • Reviews: annotations (review ID, application ID, reviewer, type, target, content, page ref)

Critical Mineral Supply Chain Visualizer

Interactive Leaflet.js map at /minerals-viz/ showing global critical mineral flows (lithium, copper, cobalt, nickel, rare earths) with:

  • Maritime-routed arcs color-coded by supply chain stage (raw materials, processed metals, finished goods)
  • Animated material flow icons (rocks, alloy ingots, boxes)
  • Information and money flow overlays with animated dotted arcs
  • Major port and strait/canal markers
  • Mineral filter pills, speed slider, dark/light theme toggle
  • All legend items are clickable toggles

Data sources: USGS Mineral Commodity Summaries 2025, IEA, company reports. Data files in _data/minerals/.

Adding a New Blog Post

  1. Create the post in _posts/ with the naming convention YYYY-MM-DD-slug.md.

  2. Add frontmatter with required fields:

    ---
    layout: post
    title: "Post Title"
    subtitle: "One-line description"
    author: "AI V&V Lab"
    date: YYYY-MM-DD
    reading_time: 10
    category: "Talk Summary"    # or "Deep Dive", "AI Safety", etc.
    tags: [tag1, tag2]
    excerpt: "Short excerpt for blog list and SEO."
    image: /assets/img/<name>-og.png           # social preview (1200x630, white bg)
    thumbnail: /assets/img/<name>-thumb.png     # blog list card (480px, transparent)
    hero_image: /assets/img/<name>.png          # post header (full size, transparent)
    hero_alt: "Description of the image"
    math: true                  # optional, enables KaTeX
    youtube: VIDEO_ID           # optional, adds video player
    ---
  3. Prepare the feature image (transparent PNG recommended). Each source image produces three variants:

    File Purpose Spec
    <name>.png Post header (hero_image) Full size, transparent
    <name>-thumb.png Blog list card (thumbnail) 480px max, transparent
    <name>-og.png Social sharing (image) 1200x630, white background
    # Place full-size image
    cp my-illustration.png assets/img/<name>.png
    
    # Generate 480px thumbnail (preserves transparency)
    sips -Z 480 assets/img/<name>.png --out assets/img/<name>-thumb.png
    
    # Generate OG social preview (1200x630, white background, centered)
    python3 -c "
    from PIL import Image
    img = Image.open('assets/img/<name>.png').convert('RGBA')
    canvas = Image.new('RGBA', (1200, 630), (255, 255, 255, 255))
    iw, ih = img.size
    scale = min(1000/iw, 500/ih)
    nw, nh = int(iw*scale), int(ih*scale)
    img = img.resize((nw, nh), Image.LANCZOS)
    x, y = (1200 - nw) // 2, (630 - nh) // 2
    canvas.paste(img, (x, y), img)
    canvas.convert('RGB').save('assets/img/<name>-og.png', quality=90)
    "
  4. To embed a PDF viewer with download button, use the include:

    {% include pdf-viewer.html src="/pdfs/my-slides.pdf" %}
    {% include pdf-viewer.html src="/pdfs/my-slides.pdf" label="Download Paper (PDF)" %}
  5. Add a news entry in _data/news.yml if applicable.

  6. Build and verify:

    bundle exec jekyll serve
    # Check http://localhost:4000/blog/

License

Content and data are copyright AI V&V Lab. The site template is open for reference.