Spaces:
Sleeping
Sleeping
Commit
·
412cffc
1
Parent(s):
53f192f
Upd README
Browse files- .DS_Store +0 -0
- README.md +45 -230
- report.pdf +187 -0
.DS_Store
CHANGED
|
Binary files a/.DS_Store and b/.DS_Store differ
|
|
|
README.md
CHANGED
|
@@ -12,22 +12,22 @@ short_description: Ed-Assistant summary your learning journey with Agentic RAG
|
|
| 12 |
|
| 13 |
### StudyBuddy (EdSummariser)
|
| 14 |
[Live demo](https://binkhoale1812-edsummariser.hf.space)
|
| 15 |
-
StudyBuddy is an end-to-end Retrieval-Augmented Generation (RAG) app for learning from your own documents. Upload PDF/DOCX files; the app extracts text and images, captions images, chunks content into semantic “cards,” embeds them in MongoDB, and serves a chat endpoint that answers strictly from your uploaded materials. It includes a lightweight chat-memory feature, cost-aware model routing, NVIDIA/Gemini integration, and robust key rotation/retries.
|
| 16 |
|
| 17 |
-
|
| 18 |
|
| 19 |
-
-
|
| 20 |
-
-
|
| 21 |
-
-
|
| 22 |
-
- **Vector search**: MongoDB Atlas Vector Search (optional) or local cosine fallback
|
| 23 |
-
- **RAG chat**: cost-aware routing between NVIDIA and Gemini endpoints
|
| 24 |
-
- **Filename-aware questions**: detects filenames in questions (e.g., `JADE.pdf`) and prioritizes them
|
| 25 |
-
- **Classifier + fallbacks**: NVIDIA classifies file relevance; if retrieval is empty, the app retries (mentions-only, then all files) and finally falls back to file-level summaries
|
| 26 |
-
- **Chat memory**: per-user LRU of QA summaries; history relevance + semantic retrieval
|
| 27 |
-
- **Logging**: tagged logs per module, e.g., [APP], [RAG], [EMBED], [ROUTER]
|
| 28 |
-
- **Simple UI**: static frontend under `static/`
|
| 29 |
|
| 30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
|
| 32 |
High level flow:
|
| 33 |
1) Upload PDF/DOCX → parse pages → extract images → BLIP captions → merge → chunk into cards → embed → store.
|
|
@@ -39,30 +39,20 @@ High level flow:
|
|
| 39 |
## Project Structure
|
| 40 |
|
| 41 |
```text
|
| 42 |
-
app.py
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
utils/
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
memo/memory.py # per-user LRU memory store
|
| 54 |
-
memo/history.py # history relevance + semantic helpers
|
| 55 |
-
static/ # minimal frontend (index.html, script.js, styles.css)
|
| 56 |
-
Dockerfile # container image
|
| 57 |
-
requirements.txt # Python dependencies
|
| 58 |
```
|
| 59 |
|
| 60 |
-
|
| 61 |
-
- Python 3.10+
|
| 62 |
-
- MongoDB (local or Atlas). Collections are created automatically
|
| 63 |
-
- Optional: NVIDIA and/or Gemini API keys
|
| 64 |
-
|
| 65 |
-
## Setup (local)
|
| 66 |
|
| 67 |
```bash
|
| 68 |
python -m venv .venv && source .venv/bin/activate
|
|
@@ -71,211 +61,36 @@ export MONGO_URI="mongodb://localhost:27017"
|
|
| 71 |
uvicorn app:app --reload --host 0.0.0.0 --port 8000
|
| 72 |
```
|
| 73 |
|
| 74 |
-
Open
|
| 75 |
-
|
| 76 |
-
Health check: `http://localhost:8000/healthz`
|
| 77 |
-
|
| 78 |
-
## Configuration
|
| 79 |
-
|
| 80 |
-
Environment variables:
|
| 81 |
-
|
| 82 |
-
- **MONGO_URI**: MongoDB connection string (required)
|
| 83 |
-
- **MONGO_DB**: MongoDB database name (default: studybuddy)
|
| 84 |
-
- **ATLAS_VECTOR**: set to "1" to enable Atlas Vector Search, else local cosine (default: 0)
|
| 85 |
-
- **MONGO_VECTOR_INDEX**: Atlas Search index name for vectors (default: vector_index)
|
| 86 |
-
- **EMBED_MODEL**: sentence-transformers model name (default: sentence-transformers/all-MiniLM-L6-v2)
|
| 87 |
-
- **GEMINI_API_1..5**: Gemini API keys for rotation
|
| 88 |
-
- **NVIDIA_API_1..5**: NVIDIA API keys for rotation
|
| 89 |
-
- **GEMINI_SMALL, GEMINI_MED, GEMINI_PRO**: override default Gemini models
|
| 90 |
-
- **NVIDIA_SMALL**: override default NVIDIA small model
|
| 91 |
-
- Optional logging controls: use process env like `PYTHONWARNINGS=ignore` and manage verbosity per logger if needed
|
| 92 |
-
|
| 93 |
-
Logs are emitted at INFO level to stdout with module tags. See `utils/logger.py`.
|
| 94 |
-
|
| 95 |
-
## Running (Local)
|
| 96 |
-
|
| 97 |
-
```bash
|
| 98 |
-
export MONGO_URI="mongodb://localhost:27017" # or Atlas URI
|
| 99 |
-
uvicorn app:app --reload --workers 1 --host 0.0.0.0 --port 8000
|
| 100 |
-
```
|
| 101 |
-
|
| 102 |
-
Open the UI: `http://localhost:8000/static/`
|
| 103 |
-
|
| 104 |
-
Health check: `http://localhost:8000/healthz`
|
| 105 |
-
|
| 106 |
-
## Running (Docker)
|
| 107 |
-
|
| 108 |
-
Build and run:
|
| 109 |
-
|
| 110 |
-
```bash
|
| 111 |
-
docker build -t studybuddy-rag .
|
| 112 |
-
docker run --rm -p 8000:8000 \
|
| 113 |
-
-e MONGO_URI="<your-mongo-uri>" \
|
| 114 |
-
-e MONGO_DB="studybuddy" \
|
| 115 |
-
-e NVIDIA_API_1="<nvidia-key>" \
|
| 116 |
-
-e GEMINI_API_1="<gemini-key>" \
|
| 117 |
-
studybuddy-rag
|
| 118 |
-
```
|
| 119 |
-
|
| 120 |
-
For production, consider `--restart unless-stopped` and setting `--env ATLAS_VECTOR=1` if using Atlas Vector Search.
|
| 121 |
-
|
| 122 |
-
## Usage
|
| 123 |
-
UI:
|
| 124 |
-
- Open `http://localhost:8000/static/`
|
| 125 |
-
- Upload PDF/DOCX
|
| 126 |
-
- Ask questions. You can reference filenames, e.g., “Give me a summary on `JADE.pdf` …
|
| 127 |
-
API:
|
| 128 |
-
- `GET /` → serves `static/index.html`
|
| 129 |
-
- `POST /upload` (multipart form-data)
|
| 130 |
-
- fields: `user_id` (str), `project_id` (str), `files` (one or more PDF/DOCX)
|
| 131 |
-
- response: `{ job_id, status: "processing", total_files }`; background ingestion continues
|
| 132 |
-
- `GET /upload/status?job_id=...` → progress
|
| 133 |
-
- `GET /files?user_id=&project_id=` → filenames + summaries
|
| 134 |
-
- `GET /file-summary?user_id=&project_id=&filename=` → `{ filename, summary }`
|
| 135 |
-
- `POST /chat` (form)
|
| 136 |
-
- fields: `user_id`, `project_id`, `question`, `k` (default 6)
|
| 137 |
-
- behavior:
|
| 138 |
-
- If the question directly asks for a summary/about of a single mentioned file, returns that file’s stored summary.
|
| 139 |
-
- Otherwise: NVIDIA relevance classification → vector search (restricted) → retries → summary fallback when needed.
|
| 140 |
-
- returns `{ answer, sources, relevant_files }`
|
| 141 |
-
|
| 142 |
-
Example chat cURL:
|
| 143 |
-
|
| 144 |
-
```bash
|
| 145 |
-
curl -X POST http://localhost:8000/chat \
|
| 146 |
-
-H 'Content-Type: application/x-www-form-urlencoded' \
|
| 147 |
-
-d 'user_id=user1' \
|
| 148 |
-
-d 'project_id=demo' \
|
| 149 |
-
--data-urlencode 'question=Give me a summary on JADE.pdf and setup steps'
|
| 150 |
-
```
|
| 151 |
-
|
| 152 |
-
Upload example:
|
| 153 |
-
|
| 154 |
-
```bash
|
| 155 |
-
curl -X POST http://localhost:8000/upload \
|
| 156 |
-
-H 'Content-Type: multipart/form-data' \
|
| 157 |
-
-F 'user_id=user1' \
|
| 158 |
-
-F 'project_id=demo' \
|
| 159 |
-
-F 'files=@/path/to/file1.pdf' \
|
| 160 |
-
-F 'files=@/path/to/file2.docx'
|
| 161 |
-
```
|
| 162 |
-
|
| 163 |
-
## Data Model
|
| 164 |
-
|
| 165 |
-
- Collection `chunks` (per card):
|
| 166 |
-
- `user_id`, `project_id`, `filename`, `topic_name`, `summary`, `content`, `page_span`, `card_id`, `embedding[384]`
|
| 167 |
-
- Collection `files` (per file):
|
| 168 |
-
- `user_id`, `project_id`, `filename`, `summary`
|
| 169 |
-
|
| 170 |
-
### Atlas Vector Index (optional)
|
| 171 |
-
|
| 172 |
-
If using Atlas Vector Search, create an index similar to:
|
| 173 |
-
|
| 174 |
-
```json
|
| 175 |
-
{
|
| 176 |
-
"mappings": {
|
| 177 |
-
"dynamic": false,
|
| 178 |
-
"fields": {
|
| 179 |
-
"embedding": {
|
| 180 |
-
"type": "knnVector",
|
| 181 |
-
"dimensions": 384,
|
| 182 |
-
"similarity": "cosine"
|
| 183 |
-
}
|
| 184 |
-
}
|
| 185 |
-
}
|
| 186 |
-
}
|
| 187 |
-
```
|
| 188 |
-
|
| 189 |
-
Set `ATLAS_VECTOR=1` and configure `MONGO_VECTOR_INDEX`.
|
| 190 |
|
| 191 |
-
###
|
| 192 |
|
| 193 |
-
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
- `embedding` (float[384])
|
| 198 |
-
- Collection `files` (per file):
|
| 199 |
-
- `user_id` (str), `filename` (str), `summary` (str)
|
| 200 |
|
| 201 |
-
|
| 202 |
|
| 203 |
-
|
| 204 |
-
|
|
|
|
|
|
|
| 205 |
|
| 206 |
-
###
|
| 207 |
|
| 208 |
-
-
|
| 209 |
-
|
| 210 |
-
- [RAG] storage, vector search
|
| 211 |
-
- [EMBED] embedding model loads and fallbacks
|
| 212 |
-
- [CAPTION] BLIP model loads and captioning
|
| 213 |
-
- [ROUTER]/[ROTATOR] model routing and retry/rotation events
|
| 214 |
-
- [CHUNKER]/[SUM]/[COMMON]/[PARSER] module-specific messages
|
| 215 |
-
- Change verbosity by setting the root logger level in code if needed
|
| 216 |
|
| 217 |
-
###
|
| 218 |
|
| 219 |
-
|
| 220 |
-
- Use smaller `k` in `/chat` for fewer chunks
|
| 221 |
-
- Prefer NVIDIA_SMALL for simple questions (already default via router)
|
| 222 |
-
- If Atlas Vector is unavailable, local cosine search samples up to 2000 docs; tune in `utils/rag.py`
|
| 223 |
-
- Run with `--workers` and consider a process manager for production
|
| 224 |
|
| 225 |
-
|
| 226 |
|
| 227 |
-
|
| 228 |
-
- Relevance: NVIDIA classifies files by relevance to the question; any explicitly mentioned filenames are force-included.
|
| 229 |
-
- Retrieval: vector search is run over relevant files; on empty hits, it retries with mentions-only, then with all files.
|
| 230 |
-
- Fallback: if retrieval yields no chunks but file summaries exist, the app returns a composed summary response.
|
| 231 |
-
- Guardrails: responses are instructed to answer only from provided context and to admit when unknown.
|
| 232 |
-
- “I don’t know…” often means no chunks were retrieved:
|
| 233 |
-
- Verify ingestion finished: `GET /upload/status`
|
| 234 |
-
- Confirm files exist: `GET /files`
|
| 235 |
-
- Try `GET /file-summary` to ensure summaries exist
|
| 236 |
-
- Check logs around `[APP] [CHAT]` for relevance, retries, and fallbacks
|
| 237 |
-
- NVIDIA/Gemini API: ensure keys are set (`NVIDIA_API_1..`, `GEMINI_API_1..`). See `[ROUTER]`/`[ROTATOR]` logs.
|
| 238 |
-
- Atlas Vector: set `ATLAS_VECTOR=1` and ensure the index exists; otherwise local cosine fallback is used.
|
| 239 |
-
- Performance: disable BLIP captions in `utils/caption.py` if CPU-bound; reduce `k` in `/chat`.
|
| 240 |
-
|
| 241 |
-
## Security Notes
|
| 242 |
-
|
| 243 |
-
- CORS is currently open (`allow_origins=["*"]`) for simplicity. Restrict in production
|
| 244 |
-
- Validate and limit upload sizes at the reverse proxy (e.g., nginx) or add checks in `/upload`
|
| 245 |
-
- Secrets are passed via environment; avoid committing them
|
| 246 |
-
|
| 247 |
-
|
| 248 |
-
## Troubleshooting
|
| 249 |
-
|
| 250 |
-
- Missing Python packages: install via `pip install -r requirements.txt`.
|
| 251 |
-
- Ingestion stalls: check `[APP]` logs; large files and image captioning (BLIP) can be slow on CPU.
|
| 252 |
-
- No vector hits:
|
| 253 |
-
- Ensure documents were embedded and stored (see `[RAG] Inserted ... cards` logs)
|
| 254 |
-
- Verify `MONGO_URI` and collection contents
|
| 255 |
-
- If Atlas Vector is on, confirm index exists and `ATLAS_VECTOR=1`
|
| 256 |
-
- NVIDIA/Gemini errors: see `[ROUTER]`/`[ROTATOR]` logs; key rotation retries transient errors.
|
| 257 |
-
- PIL/transformers/torch issues on ARM Macs: ensure correct torch build or disable captioning
|
| 258 |
-
- PyMuPDF font warnings: generally safe to ignore; upgrade PyMuPDF if needed
|
| 259 |
-
|
| 260 |
-
## Development
|
| 261 |
-
|
| 262 |
-
- Code style: straightforward, explicit names, tagged logging
|
| 263 |
-
- Frontend: simple static site in `static/`
|
| 264 |
-
- Extend chunking/embeddings or swap providers by editing modules in `utils/`
|
| 265 |
-
- Optional Makefile targets you can add:
|
| 266 |
-
|
| 267 |
-
```Makefile
|
| 268 |
-
run:
|
| 269 |
-
uvicorn app:app --reload
|
| 270 |
-
|
| 271 |
-
docker-build:
|
| 272 |
-
docker build -t studybuddy-rag .
|
| 273 |
-
|
| 274 |
-
docker-run:
|
| 275 |
-
docker run --rm -p 8000:8000 -e MONGO_URI="mongodb://host.docker.internal:27017" studybuddy-rag
|
| 276 |
-
```
|
| 277 |
|
| 278 |
-
## License
|
| 279 |
|
| 280 |
-
|
| 281 |
|
|
|
|
|
|
| 12 |
|
| 13 |
### StudyBuddy (EdSummariser)
|
| 14 |
[Live demo](https://binkhoale1812-edsummariser.hf.space)
|
|
|
|
| 15 |
|
| 16 |
+
StudyBuddy is an end-to-end Retrieval-Augmented Generation (RAG) app for learning from your own documents.
|
| 17 |
|
| 18 |
+
- Ingestion: PDF/DOCX parse → optional image captions → chunk to cards → embed → store.
|
| 19 |
+
- Retrieval: filename detection → per-file relevance classification (NVIDIA) → vector search (Mongo Atlas or local cosine) with retries and summary fallbacks.
|
| 20 |
+
- Reasoning: context-only answering; per-user recent-memory mixing (classification + semantic); key rotation and robust HTTP for LLMs.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
|
| 22 |
+
### Key Endpoints (FastAPI)
|
| 23 |
+
|
| 24 |
+
- Auth: `POST /auth/signup`, `POST /auth/login`
|
| 25 |
+
- Projects: `POST /projects/create`, `GET /projects`, `GET /projects/{id}`, `DELETE /projects/{id}`
|
| 26 |
+
- Upload: `POST /upload`, `GET /upload/status`
|
| 27 |
+
- Data: `GET /files`, `GET /file-summary`, `GET /cards`
|
| 28 |
+
- Chat: `POST /chat` → `{ answer, sources, relevant_files }`
|
| 29 |
+
- Report: `POST /report` (Gemini CoT filter + write), `POST /report/pdf`
|
| 30 |
+
- Health: `GET /healthz`, `GET /rag-status`, `GET /test-db`
|
| 31 |
|
| 32 |
High level flow:
|
| 33 |
1) Upload PDF/DOCX → parse pages → extract images → BLIP captions → merge → chunk into cards → embed → store.
|
|
|
|
| 39 |
## Project Structure
|
| 40 |
|
| 41 |
```text
|
| 42 |
+
app.py # FastAPI app, routes, chat/report flows, ingestion orchestration
|
| 43 |
+
static/ # Minimal UI (index.html, styles, scripts)
|
| 44 |
+
memo/ # Memory system (LRU + helpers)
|
| 45 |
+
utils/
|
| 46 |
+
api/ # Model router, key rotator
|
| 47 |
+
ingestion/ # Parsing, captioning, chunking
|
| 48 |
+
rag/ # Embeddings + RAG store (Mongo + vector search)
|
| 49 |
+
service/ # Summarizer, PDF generation (dark IDE-like code blocks)
|
| 50 |
+
logger.py # Tagged logging
|
| 51 |
+
Dockerfile
|
| 52 |
+
requirements.txt
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 53 |
```
|
| 54 |
|
| 55 |
+
### Quick Start
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
|
| 57 |
```bash
|
| 58 |
python -m venv .venv && source .venv/bin/activate
|
|
|
|
| 61 |
uvicorn app:app --reload --host 0.0.0.0 --port 8000
|
| 62 |
```
|
| 63 |
|
| 64 |
+
Open: `http://localhost:8000/static/` • Health: `GET /healthz`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
|
| 66 |
+
### Configuration
|
| 67 |
|
| 68 |
+
- MONGO_URI (required), MONGO_DB (default: studybuddy)
|
| 69 |
+
- ATLAS_VECTOR=1 to enable Atlas Vector Search, MONGO_VECTOR_INDEX (default: vector_index)
|
| 70 |
+
- EMBED_MODEL (default: sentence-transformers/all-MiniLM-L6-v2)
|
| 71 |
+
- NVIDIA_API_1..5, GEMINI_API_1..5 (key rotation); model overrides via GEMINI_SMALL|MED|PRO, NVIDIA_SMALL
|
|
|
|
|
|
|
|
|
|
| 72 |
|
| 73 |
+
### Retrieval Strategy (concise)
|
| 74 |
|
| 75 |
+
1) Detect mentioned filenames (e.g., `JADE.pdf`).
|
| 76 |
+
2) Classify file relevance (NVIDIA) and restrict search.
|
| 77 |
+
3) Vector search → on empty hits, retry with mentions-only → all files → fallback to file-level summaries.
|
| 78 |
+
4) Answer from context only; store compact memory summaries.
|
| 79 |
|
| 80 |
+
### Notes
|
| 81 |
|
| 82 |
+
- PDF export renders code blocks with a dark IDE-like theme and lightweight syntax highlighting; control characters are stripped to avoid square artifacts.
|
| 83 |
+
- CORS is open for the demo UI; restrict for production.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 84 |
|
| 85 |
+
### Samples
|
| 86 |
|
| 87 |
+
[Report Generation](https://huggingface.co/spaces/BinKhoaLe1812/EdSummariser/blob/main/report.pdf)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
|
| 89 |
+
[Memo Dir](https://huggingface.co/spaces/BinKhoaLe1812/EdSummariser/blob/main/memo/README.md)
|
| 90 |
|
| 91 |
+
[Utils Dir](https://huggingface.co/spaces/BinKhoaLe1812/EdSummariser/blob/main/utils/README.md)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
|
|
|
|
| 93 |
|
| 94 |
+
### License
|
| 95 |
|
| 96 |
+
Apache-2.0
|
report.pdf
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
%PDF-1.4
|
| 2 |
+
%���� ReportLab Generated PDF document http://www.reportlab.com
|
| 3 |
+
1 0 obj
|
| 4 |
+
<<
|
| 5 |
+
/F1 2 0 R /F2 3 0 R /F3 4 0 R /F4 5 0 R /F5 7 0 R
|
| 6 |
+
>>
|
| 7 |
+
endobj
|
| 8 |
+
2 0 obj
|
| 9 |
+
<<
|
| 10 |
+
/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font
|
| 11 |
+
>>
|
| 12 |
+
endobj
|
| 13 |
+
3 0 obj
|
| 14 |
+
<<
|
| 15 |
+
/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font
|
| 16 |
+
>>
|
| 17 |
+
endobj
|
| 18 |
+
4 0 obj
|
| 19 |
+
<<
|
| 20 |
+
/BaseFont /Helvetica-Oblique /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font
|
| 21 |
+
>>
|
| 22 |
+
endobj
|
| 23 |
+
5 0 obj
|
| 24 |
+
<<
|
| 25 |
+
/BaseFont /Helvetica-BoldOblique /Encoding /WinAnsiEncoding /Name /F4 /Subtype /Type1 /Type /Font
|
| 26 |
+
>>
|
| 27 |
+
endobj
|
| 28 |
+
6 0 obj
|
| 29 |
+
<<
|
| 30 |
+
/Contents 16 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 15 0 R /Resources <<
|
| 31 |
+
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
| 32 |
+
>> /Rotate 0 /Trans <<
|
| 33 |
+
|
| 34 |
+
>>
|
| 35 |
+
/Type /Page
|
| 36 |
+
>>
|
| 37 |
+
endobj
|
| 38 |
+
7 0 obj
|
| 39 |
+
<<
|
| 40 |
+
/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F5 /Subtype /Type1 /Type /Font
|
| 41 |
+
>>
|
| 42 |
+
endobj
|
| 43 |
+
8 0 obj
|
| 44 |
+
<<
|
| 45 |
+
/Contents 17 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 15 0 R /Resources <<
|
| 46 |
+
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
| 47 |
+
>> /Rotate 0 /Trans <<
|
| 48 |
+
|
| 49 |
+
>>
|
| 50 |
+
/Type /Page
|
| 51 |
+
>>
|
| 52 |
+
endobj
|
| 53 |
+
9 0 obj
|
| 54 |
+
<<
|
| 55 |
+
/Contents 18 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 15 0 R /Resources <<
|
| 56 |
+
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
| 57 |
+
>> /Rotate 0 /Trans <<
|
| 58 |
+
|
| 59 |
+
>>
|
| 60 |
+
/Type /Page
|
| 61 |
+
>>
|
| 62 |
+
endobj
|
| 63 |
+
10 0 obj
|
| 64 |
+
<<
|
| 65 |
+
/Contents 19 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 15 0 R /Resources <<
|
| 66 |
+
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
| 67 |
+
>> /Rotate 0 /Trans <<
|
| 68 |
+
|
| 69 |
+
>>
|
| 70 |
+
/Type /Page
|
| 71 |
+
>>
|
| 72 |
+
endobj
|
| 73 |
+
11 0 obj
|
| 74 |
+
<<
|
| 75 |
+
/Contents 20 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 15 0 R /Resources <<
|
| 76 |
+
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
| 77 |
+
>> /Rotate 0 /Trans <<
|
| 78 |
+
|
| 79 |
+
>>
|
| 80 |
+
/Type /Page
|
| 81 |
+
>>
|
| 82 |
+
endobj
|
| 83 |
+
12 0 obj
|
| 84 |
+
<<
|
| 85 |
+
/Contents 21 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 15 0 R /Resources <<
|
| 86 |
+
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
| 87 |
+
>> /Rotate 0 /Trans <<
|
| 88 |
+
|
| 89 |
+
>>
|
| 90 |
+
/Type /Page
|
| 91 |
+
>>
|
| 92 |
+
endobj
|
| 93 |
+
13 0 obj
|
| 94 |
+
<<
|
| 95 |
+
/PageMode /UseNone /Pages 15 0 R /Type /Catalog
|
| 96 |
+
>>
|
| 97 |
+
endobj
|
| 98 |
+
14 0 obj
|
| 99 |
+
<<
|
| 100 |
+
/Author (\(anonymous\)) /CreationDate (D:20250915071444+00'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20250915071444+00'00') /Producer (ReportLab PDF Library - www.reportlab.com)
|
| 101 |
+
/Subject (\(unspecified\)) /Title (\(anonymous\)) /Trapped /False
|
| 102 |
+
>>
|
| 103 |
+
endobj
|
| 104 |
+
15 0 obj
|
| 105 |
+
<<
|
| 106 |
+
/Count 6 /Kids [ 6 0 R 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R ] /Type /Pages
|
| 107 |
+
>>
|
| 108 |
+
endobj
|
| 109 |
+
16 0 obj
|
| 110 |
+
<<
|
| 111 |
+
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1822
|
| 112 |
+
>>
|
| 113 |
+
stream
|
| 114 |
+
Gatm;9lo&K%)(h*@!Ysga3e(r("p-ol,U/pcF10B^+^1:F%_?>8_J69r;r'3.3E`FSXiG0N[Or>&&88e_?bWXrgW$MYF"b1]+DgbQ>6aR_$$(un90*Im36B'9W!nF_I,Eq:%8E/"OUmFM]rGdg%>VHK5!H=7MD0(a#j0V!j9BPs%_QV&1-j(9Hp\R()L?AG*k\fA-P=V)2I5T!r<kT?oJmX-#DOG+efs]7=_6I)`gAtK8$M7"3b=jXM9GM5Ht'Li-o+h4il6]U^)1`#>\WaCCan\_`E,;n6QmY$841h"Y=3KAc<f(K^fVJ&HW[g7`c+RI/E.ZJ>D5ll-ZGjm8jUNY)e6hdiKYi'fYW]dU)#^',kaIZLB>tKj";d5j!!%\lE(6^9[<cH*B1B6iloVX#j19#;'@u7AbqO/.N/B4r7HdSXg*?*lU>i5&$Ap+#C[e.Yi^EnN^g5:1_k)J@.s!LZq?(-6Io)LcPXcKnL&-S[:I)pHV$@VJtBmWM`id)fORG1^$)Q?'2B#HkWpJVup.>A`('%/^ZW9E8^9MDJN-k[4iL@P.T:om8g1:YURtlqB<L,`K9P;]RBAe8hE0^b8Df4!JBec?*7Prpfb:NW="#1PrZO(081t`mV4Gj?X7-FH"dUH@<7i%V`P3$9Pt?%+a@ir\m'qj>*TJBk`l1S$V3B\4#%/H:h;)h@tW)O<dCY^aUtR@(D^:gYdPmV$a&Y?LDf0/`@@QeE3?,dZgk#hRQM@Y?gX4XgG.;bAlC=g0Rs[f[jIj_0u]'Qe*e,#@Xd3he[3HO:nm_a.-#%>)kg)`:ad"Ve94M&?nd'h`ICg!MW$b%4g)E*gtG#bPhl8/he>`=Mi#d*VJU]akf2$:k9:n[W!0@TV7A/]3)cP*?rgBo7HI7hT,opD$HKVJ=]PsTAYk+B7`'V=>,t/EpY.c[>NhlVAdAc0PZYUCh0)-G8Y$n4i++9m1A$MWT1W<IEai5<)1aA;5G[GcX+GjXcD)Ac%nBW%)atR>+iW[*\iIrZR%3.U#B#Uo(T=JCmKc%S"U;"]8V#W;cg^1lhu1gQn`Bh^YWH=,QH%E^E;do]=_q&g'S#WId8cKH_uV?pDPM)p46A>_WH*7<TuP2^'+BF=_V/[7kb:Z%[R9QufiFh?O3c4DbiB\UAV^[>FUbe-KWW=%OD$QU=(-7a\Q/&JBZ*RT1K6-qe6:BtN^ZBgkA"F#7B&Ba8rKLUI'uV@./@5V_B$<.Hk\Y>CDOR.gBp*VZQb`_A�!T;AVjcP!0UXa6qESbdE,b6\NoZ!`E$NVrG7=uN/n@ki3&5NfTkQH%6SRm!U$-X"`rFT[H>#*,L_R'fV4dIYp\;>l;U@>^3D"!,SR19EM<9h1bt5T#9S1(_c\,6MT!nh\is1N998=]QW/<rRX/6Q9.6#&#bi7qoMu>sAjjhAoamXTu)b,fp\`S/(_FZWDV!]Jm4?@]-:V#V"mDWtjOV$!&[m;p/XAd4Zs`G*(E#b?b-NZW;Nt):T>^%r</:q]\X6ML-*KG+_%[AO(P-O94]JI'a@LKN8u'&j19PPp2KslCD@u<G@H%V1NNZ>D)c+XHeE.!NH?F6rM-=OK@;.9=p9d!]Q[VKeP^$]8!*<REa-;>=K;h>8?,">7k66MKmpdh]*s2*:S:;:9IsXO-8qp57UlN$.l%(Z<GGU8LY8E9Z9D8Zb^@SQ)#R)Vj/ck<1N&Lq9&<UXn,1SMF4%8OB/ucn:AQr><V[7:0sonQC::Ma^E.)/.e=U2l6-!)Z7%lIQn^O#'Z!OX32YZnt'X/NI]4tjCT8Wfk.X,l3'V_AcXnF*TOY*4C%dlfCsY-~>endstream
|
| 115 |
+
endobj
|
| 116 |
+
17 0 obj
|
| 117 |
+
<<
|
| 118 |
+
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1662
|
| 119 |
+
>>
|
| 120 |
+
stream
|
| 121 |
+
Gb!;cCQI1/'`C51ii5m&VO`%m,_T^??"s/&G.N+h%]WPZr=BSDmNsi7%$[pkhtPhrJ1r7tN]PT@8-G)khq,F%(^^beWVoM2JB(#:4f:PN(f#VX`/!;%GW%\\HpfL.5mRQW,%2=B\,m``3cOtF"N9srl4&92:U^jLHA&oX*='J%2tq=HEc\R0cR"gk42hp2]\itFXFOEKGXm3lM2"[#(\;,RIY-NA'?;3iDT:]/2mM^6EX"U63qgC=:ioN'KdkKAW.kr)Cs'^'XQ;dbbBOm,'2,L(aI1D:0+*[SO@V+bdtM6[XLOk<bGW*BGi*-&3aOQBhL,HD7De=(HJ9/^O=1l["u-ClWpJnKhHZ;:0:k@[;6Rd=$2Xmtb[_p>4Ir!!9/\gX>r;t`ef"]8]s^De_%N%'5%Sd^;C7QLB)k6I)M#RA^k(@,m^DQL(nl/>VP%S'XNH/gR4XhYN/pu?et?SW^q-3!2:aV+(+C%u]4rOr9WlUCFH]'tp,\Pho0,R^Bl>VFng2WKK5E/&R.-%H(s[AW!6?odj[s&=:+ZT(0)i;n"A;ioR'>lFbdsO\Bl8:BW8!iW^`QD*^]+$Kf<"JHr=/X*m'6U5*e]&R9ADft!#P)ZG^Rj6,D"lDXpYAlSN`'X&G_QFHg!_hW8Q'Yd%Z.rFF<lLorF-Zl1Nlr<cX#/SK+)L#,0!L/b)e_Q@t!q]IR%cY[;5K]a[.b/'9rgfo)D6^fPf&hg0^tp58fJai40%h)4Ul2'n)JF^\/'=E&Ro7Jle`dX2ZTHI"tUmY;Uc42;:40#atJ$#()5+`&:^gN*.D3n<iqRZjlp_J>Li=WE7_E4\k,qK9bf%fgInG,"He<3OEC#FYRF>T#FM1j3JQgu[1L#&TTU_t4TggEfDg'.s]?%TR=*onaB:<\YE%<:KXeipf"/.b5AT^HLQ\62Zfu$ti%tOTsmbdP&r0))JiECW$@=r6jN;5iStf0LiXr!sJe%c:^<-ek)6nFu?p-Q,!dWi=f<JaCWLL'_Ak7)T@D'Lf%TDdV$8Z6n5-'Um;d979&9@@(KP_I+hmda1J=HgC,\;f0%@R<uZEd&7.cZK(&j1VVO>sWmE-G,t,D]8F-XsY@]]@.s7%c,PB]J),Fk@*b26-2TiD$fhC%4U@$*`m.Y6G'^J)l]X&2V^V'iCs.>YBQY5d53d'/QiN4@kh4RcHWC)/3WH#dpl<pBVV6H*I@aXace(nnO4@_"4nA!S(K.:mb1m6^-SR"<aN&.%jP2T*P]:'Voc8ErD=$3YbZghLhWNn,b;'iH24G=ae3pL!cKm<Ob&RmW:e,J2Zo/]$g0'/n\$h&9.R3ff=N:$Hj3MPTG8*(g/o6o-#;[L::SXE3PG=KU`)k260r;+uu3uWf;;acC`6JVu@_k:k8;)3&\X0iS7Ag.`7[BrO.V_s:M1cBd2DH_J+^*#;12MABP>NEX]'&]p5TlB]U)7%t^`1g4(jC0B5V;enf61SPb[cPac_iB%iN*Qq65%Pt''q6^STK(Oi4D3;/AF1i#'i79F/4NgP;4YKjaW-h_GV[utViGi-PH1\3g>1*s2?q"tS#aH]8HK^9;7.MD+B'L\iCOWN]eKCSAMsYr3R]dP&jdMtM7.=<q&!fYYu[UHXKWhHTt4fLTg>367ZTU@Y^\5@2E8@L1`ZH%hLa;0~>endstream
|
| 122 |
+
endobj
|
| 123 |
+
18 0 obj
|
| 124 |
+
<<
|
| 125 |
+
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1952
|
| 126 |
+
>>
|
| 127 |
+
stream
|
| 128 |
+
Gb!#\D,8nW&H9tY(a2nH2AiW)@Y\8cU'3#A=(icBI3<oVm5<Rtm7k9;+?J>.^Y-#Y(m?r)V'd9OE>#HfkN/+EAsRsus$XO*$,HE]*+'7"-4D+A[Vj"PG;p]4rR`@F9%O0s13Ch]Gk_Eud#$Md>lr::bt!0D&T=`=d(Es$HR[TdjFM.[h/o2OfE92C]RRWh"i[2_o.<fY',=)h&?3tFK`_FVTC,k#Eig/0liFKR@lU4q9.BWbpfZb*J4IE'S3G:.VLHP_D_Vt<nI0dgBF]J2o>&Zi:PF6'_`qT)>)>96KCRq%<,e!t6.9((5,L$-=b'lW#?lJg'Ui'C8",U<HXtJ^4OEt[2)%`if1J2clK3CcNnPO%`b#7H_kfM_C&ZZ/md<a(:7!<F4%OTeA"BS6Vp]'"D?!Qfg[@G.5):9HAkW$mh2HV@2[3^d77!a[9i?bDTl)"$C1&g4P#+3RYS<TQasF!nOX>=(_*!8Z@ifT;&k5$ojTu*V9JSf.M%'7EY\j.6^g$0^]]IgP'dM$>qgd)91EYWYT=N$GqTu6oCT^[RhQ-cu=6_IZ1BI8s*)k'X$%15N6rb?[A/>"9.npWL!=a2H"7lROKj^T7-4<n9.?*45+7h(T/RUU3@hs[SEM;qN.I_&&^_G0iDme/"D_:Kof"UctC"^q_\N^W3`-"_C*ab;b?#@Z(5DEad^bRGge_7PZ%>JPq-kaW]a9jTrV)4;5-r;1@r`-"Yc84O_Lt7]^)m3b@puQL"ZYl0*hJ11J#D$kajt!P>OOmH:=^L/ESdH#'UM[Z,p*ru$=W[+#E>`nfMB\g:!tD6)(:#C6"H-CHO*:+8UYYi"/\\&INqD*F4q9;?(e3]qEK&WG+K"sc5Y01bJQ6OJa,":Db5@BgrXh]q<.E8AOOIUM^pd.0NXho_;D&+XP_RQB'RFOHT/\1n:MMSXBN]s(r/?OCB7STb9o.D/%4og?F#i/-dSOLY]DM!flfiheIDg2UWY)\7pVF04CYK-<,hr&*#Sgn+6F%V!DXum.c,VrrogSN8c,.lU&U_=,*F<'#KFc[9\&4]abH'U(r4TYJ[1[AYKDGt=C!t0`UuWmfaQ(t!7JG=6aCUE_gQ&XQ#LS2&GPaV"_!A:NN9Z\BMp'<S/lQT\a\T0IPL]SA-+f08Bq<l0p9ZokXqmC9)^ZNBOX<^^_o?K$T'@oM:lD\fb0.G#_]*ON+Qr[1fG<t[N$,R8q05=>n(9eCnX6m]61*T`<AE&'hBog7LZhd_IU8018NfG*8+(PA1cETmfKmsJjLno"M1Zt;M+[AlATK<V+_)hi\5k9:G3sLi@^A>cNPo-2M]Fs9R!OB=g.H/d2f9#R%R0`uoOE(FkU2\%"S'"o^kqD8r$f\K2p^-@@6]R[Z\hO][%&>Fq&\!Elno?+9o9"/+t[W2A*W*`2FX2(-k#1>^L)"j^lq>`T5)'QhGEG<F-+P4=Xi20MNG];Rpg57)j+"WDO?%A)eo7UNqR5lJK9aM+)s,qOMK<0pgAPd3sr0]Z6:g2A4:E\/N.2'k2=_p;JOQ^:!TAYM,`"HV/Ut34(D-@j(k)*JB2@XX^N($oeA*@`gAtW8;nqf;k+TA)hhWgn4<)'#r,l)GM*m(),DAc,021X78\W4ipoc6_/aGU73#@'&/%$W`?^be%t/oV,Z@48Y9f'H1K(.A1X5Hhpt9%,7rOZ\)3*n1Drfs$;[rC3.0BenMLu`Qb\%TZimCa`amDS=V!n6*K,.Ui]C5,hlc(,X]$D`2e$3n10l74@d,hn(]MR*+'t'<a$UmeGdc#eSlC?m\P-Y9SF^(D6LfO]$=p<*+a6dep#U@B;19b`qOsBUA)UR2p$=Y>3@Vk^)Fm'_:@)`T)c5*-Z-[:TTQ4l82#a*COB.iICVEAp.FCAH8YKQ`.<^ggjC-cST?!V5[B6//8Cj*Y[UTh<#iJ(gP7't!O.bJWE"k`\W!DhEl~>endstream
|
| 129 |
+
endobj
|
| 130 |
+
19 0 obj
|
| 131 |
+
<<
|
| 132 |
+
/Filter [ /ASCII85Decode /FlateDecode ] /Length 2017
|
| 133 |
+
>>
|
| 134 |
+
stream
|
| 135 |
+
Gau0D9lo#Z&A@sBFF:r0TJ2N_OAl_.Z*U6rfJ.49Yj=YH"&'nQfU3>QCFfF5]13rjfTNSDXJl7?BkFq`^\><N#$lU2q]7'aDl<*qM?.d,\cCkS5"r0=EdI<.#qPH1&"rCaSAASm^_M(pQ`t3@eq[sk$Yc$bLs\[tqbg(#9ii=[@/:Tkp0^GC=ppH^',bFPaE6"%SJ@L7[4OqZ=igrX,*"t\5_U^j8-K$1![WGDbTY>:/CT9M#0\PN\:PY/!T(#cQtlrH$OH+5dpJcU$"=L_=t6k?Z&j("$j/O3KZ:.#1hu&7%g">8Hk;s@J*!BG!t8aU!eEENV`YOLqi%^G#[OWcnG#oUHk0M<p!<S#KB(:ipUFgnQgN[Lr2Gu0.JV7-JF>55mJ"oB`G[cLrPbAkS9MZ?l[jaJGC)^T*;YU'B\cuXOTllWP;!hU7PH<.l]2RO0;Cb$o'>uFs%<t5A)5=;i%_G(_=?]@/=>UeGmsH<Gkht)Y[/Nu7(NN&>!f(/q;sY:!A/*VhG0sNPFLkkj%o,PqWfH_hVGiX^ALOZ+5Aoff7kZ5b`&l/+uM+GqK-279BVQ#X^`NGHoa?9?1G>`*U*'\2iu+:a3Khe]XZpXFQ4>Kl1I>=@KEf9[DRn]OCiJp4+i$_Er^\2&%u4j7G<!+&7"%cng)8sM8:j3'[cosn%`GXJ)pB#EgO=:B.e4a@-NC'\^42tg*eMEd>-q6DksAA:Xdah%P=eZJ60fTpU1iKR&Q1^Jr>m&V6c0tD4k?7KulI.8tn0hKqHndn+Q$_^`P`\>4/g\.k5"tY0b4*=9qR*Q73\](o389/^-6EABps+PGK1.,a'kle<2%,Qe"J8Dlu!/X*_!p\jI=O'bA'!FUH4NdiF/640m4(]JSfmF5/"R#@&!`nlG`K%l;+u7VhW$opGC(TrY[d+2,kj8bV)h]A%[_P+.)W/oY\o)H`(`#<n+'?,F\FHlE<XKM&=*Dc!C&Ej_.$[Ep-b^,B+*2cnK&C*WJ-hU=l&O&`O8Fh01E$o%B,[!l?glurWJ2M-gR"GUD.N&=!9.r;4$'V\+MHmm<!Cq8Xm=="X<!t$Uq.FuN&19muF7nGfIpRm_OD].n\RGnB`>FEHPEf,g\pV^OW_u#OA1$TETQXm'DR]9W>/UQkd$(:%JCc^0'd8UFCmmV=A($XK^RLo2tX;:>4mhoBpjsBLKpm%L7LH4jaduZkH9oB!'F`_,@IXQV3%pRAB]LS'><$VK=6RH"R`=Q`#B2O[3at]2d$8De]<F^uhQF6.Rs4fnY`qoYo!U=0f^2``s0S)[\G`I(RG?gnIBgFNq&Q`Ud*@`eQSgok@ZlUFH!#D(p)R[\XV:.mgLlgrrNap]p'!ALQ&KTKV4;N7.4#>TP84i),3H88[OK"D'KdBoV'qWdn5hE-/L&E&Y7/@oJf6l#sJ&?%g(;uR62/(AgI6&`G4tSTl8d<;4_@HGfk*TYUAFeA\qa=_[6YdN?%\rE'GLmDLV$LqWP2I:q]FrCf-fu?h6c;?c&SZ)TO_LDjZL+WT:G5`$G26oaME&m;BQ(^lDE&CEPJH*9+_!T.EPpP^3+<Irf<S*t#`V!J,Xqcg>+;LOW4E]R9MKY@6hW=8Iq^tdL/q6ra[*<EF/^Zo,<[R_OR)1.;AB\o`jo7U+]XF[O%@N\`26:i5.Vb5(asnG0hu7/YbegG!=R5?.cO&Z,M4*hq$QG55LGs+VeG'+#Ao6j*E/7aNfB`Yoq=/7bV@<K^YAFL<DD=#W282P]'GFt2Boq6lTPbZ8uC)UdCD)b]VajqXA<HcYK"&HcKO7+\\5%gV96^2YCgqbi>,4NHt_!sT0N#`b'',C_uE4JoUi@UU5uErR#qt-6M$&r=N$tO`h0DOmQNi*?NLV(0$UAc_pQDBQE,7;oFPm/lfQThs3h!^'Pn^D'IrB*jMF)KUjQrp]3PK5,ka3nOD0?ikW]KE]U*;Lc#f9r4WEZkXqnh230:bqcbEa\VKE_Z$[NY=Z\RWp6H^PmPS?0fFg2/m!@RmK7c+a(~>endstream
|
| 136 |
+
endobj
|
| 137 |
+
20 0 obj
|
| 138 |
+
<<
|
| 139 |
+
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1969
|
| 140 |
+
>>
|
| 141 |
+
stream
|
| 142 |
+
Gatm<gJ[&k&:L1S;"6;L$TrFsll/#O'jJlkfJd+N>DY5YP#mg1aaX2[QL-YBP&Qhg:g=W9l9;-CS/*jFiY@7;8^>sqp[#dtbi0\UT<WVP%G:Ug]=`Xfn%6)93M*HpIi(m,B+mCY&+E-&hBa5Lqja4#UH%\%H['jn?"f;'CJ;?`_op>.k91mVGp_/u]Dmm+6Ztp,3gW'!;L3'Lq-7T?J(Qm?@7sP!Pke#:m0BgZ?[]K`o[<pAk9KE-j^-/4]2.?`;u5u#IO6D^cWU#V:Sf6d^]+C-+M3YIJn5H5&^@)7m@ujoq0[=u,:[34='hG)hu%PB\\7Rm3,4HV'Ar;*b!rSLAn1/%dFfjD%IgtHqf()hO/qL04ETuuOiWqa=CP1ES<cSe]ONb9rV--,-0#+KPBiiiNo,)sJEmp8o=WR.WSat4C#bZk3dec?i_q.je,e%8RY=F(b&T1F-!)^F3'NSrBX0k]_:_;p;*=7U#A5UQ%Jk'obTco?)u]t+Y<no&i__sK&eGmJlrHZ:I$9X7]+Nh5WTWVOUNA&j8cNIG+pq[toh=$:rF'nWc;XY*-Yf:.)oB6AR\Jk8RAC;4\s;k2BAP=2Ta,VR([qY(TTZ=Cno8e.ZlG@fJ.5>ReEUH3%F=_p2&qV5^dY`TEY.eGB/te-Lsc_!)G9L.V0S*\C`8_4VnAscn6ioHrUKTQ;76?h<g03#*"c3AA;*BJZ_d:s?0ACgTI@mUo3dO3[+a7Kp"!'h&lfW<U3/_@:$/&QZ]Fim5FB)Dq]OpA#/)@94)c@Oe+tkrQ'Bi4NB+J/_P;3q.Z$*._GUZT!r:'AaTH3*pUjL^l&+>612O5n'R%('g>.)3.!&g.,$61_2g0>\]LXg+.0V.m8["(A%)sIu2DsV/i=nJ&7XbT[ppU<KSuc`&$$,4pG"n[R%Vr"6Ugs1'AcaIZ0f+YpL#OW'3(p=]%EtnNU8fR^[\a9PaGd='aRWp(ChsI5j#FhG$b-RSrQH[(80Q-oQT2orgt*obgp%#a&fcc#0LkU-[pjG0Q=u1^(caV.a>lYV$gnRHV1jW-OH#btX3&SrY0goKoW+]!]Z-4KZ?7`IN\\nRP.p4NLL[\M')rIZ5t`dPF,a=KR8`.'i\2JoK"ptUIm!^!0ApS_5^o$&li,XQj'=&!ldmeG^JY]9IP76&?6J3@QCo`nGd8M^RILI/Y$c9c,Qb>Q$e944>_3#gEfN1KHfq5W&Ar$pi5m!mU-I?B`=k[hWIka!4"[6E<JC>,Z!1/O*uAB5K;Fd@<8DOqE%2IC=p:\.iUUNCJB8hU-B@h3e(Y^D?:jKDHP@urA:RnJH&.uTIoSuKm&;%%Qc=VV<%b&KgbC)s`EG)pi'O1Zkk@@$L6-Sq-jNjhY/AKGpe3O)*))*&+#OC(aYAWG@@$,X;PD\RSX(l=jp]Qt9R:Wi+/ZlD@CcY3</]sY-+pEZX]cpm%7t/jUSLp0dRNh+26*657qIi,@Hri+1oOm5Y]Pr.;O0qj,*mhGXq=p3T2HP`E**[i7VNmn;Ph&,/J/PU`ki8_FK`G$T'i*,=^SYhJDbTLPb*],hE=kJ+]M8>rT$:d,^"\?6cS2S9`-:I$0r1G$"oja\S.7knG6MrbX,ATWl-\')NW0m0dZ'BU6]5leW/9Tl$Yp6Dl2D\&k$G7lA?U>5-79bZ4)9jg2ag"JRlCC4&o9>PioOgWP^ahp.beip]Z\ej&UR&at!)$4P!h?"mLsiD^$@FGZ3F1$eSD)pnmn?'MOM4esSSkJt'l.X"]-',@r]eDBOSk+Jpm!!E8=*qa(t4>=^TJ_N=lJKlOF&hm\D";rF+3_g$A!j7slYANd)1j?=<#[BBY5)`GK_V2capU&)1sS2cnS,h2X7[-Io5[i`<;oarnE^`#tmWS<i='g=H>HNch;.KbBs=Wq21obE1eUEK@B9;^jl;*4Wud)Y-&S3XE+@hP'j2+)XpFDZ`ETLf>`n6k_a#JUBf$3~>endstream
|
| 143 |
+
endobj
|
| 144 |
+
21 0 obj
|
| 145 |
+
<<
|
| 146 |
+
/Filter [ /ASCII85Decode /FlateDecode ] /Length 900
|
| 147 |
+
>>
|
| 148 |
+
stream
|
| 149 |
+
Gas1]968f@&AI`dp..7&`]O;_[V9dGjO1ue>S_UEe]<n(a\_tb=)1J98NY.@Qs&hEpQBR,k$K`JeGstKi:B;Gq$`,fnjU!;iXtU:dB?Dr4LnY5C;.pCle=:@E8at-IQQQGr%p$56.,2'3TPHM.npqsN1X<P]$^qM.g^gXD+cTKjZI2qC$RKg]7mlN.0k2?CI!+gD>A^VL2;N56>t>@b%!eck?kEcp^+ne(o&I_/ctH;)r):iR1O.cf"7J*WItI#H&X.]03:L[oD?A=[iB&P'??$Zc2.-mI[70LbJc&DZc,&!Y96Kqg%([VZX/\1j>WgR>4bp/E9F;X?-pmr&'rMcT6QZ[eJXsf0'(3_[MN;0'f-';?sM2BJ>^uo#d0(T>7)pkGFL5'#rJ30\oB#7^b'?J[\6d1Nhg.)=sqqK_UIPPFaN\\DtI/;2^_,4+[g'#.*bOXeo*5RPghZ3\0pk$hBu:8L%ji/2<$RX_-(`Be<TWIR]ZEmNm4psb5`h0au-<-koYi+.?WX7]PnrcZDPsnm)U8aK.c0jlt`_<&5`Li#s*crBqCWR%@p:9d?oJ:o2%J.aP(nP"@aU\OSlPg$WX9E$,/20HHW:I*KN0Rh?!QRjkK_;0\Li<Y8=4g9O2SJaA^'H^UHL6iS.7o.%B]8*SRM!&]8BTJsI8D9MAsK<@0GOhN9C"6X'Wj-InqZ"qTF:N;;KQH7:L#XiRDj8R/:@SCY0:Utdj0^-#M63,8U+^_5Bc#a8TDrcne1G6:"iFWVUlfJ-u.!pE>oZ(cIS:1B$h#Wjl32&,<e>#^a7apBbHO@Wm)as3fNH'4gEoVpud(ca+E"aj60K75!tR5$budVGecQ03sC\X&8Y,UWFQ-!1fj/,AFkPE"mEM-b7*/fk05r;i1&`K^~>endstream
|
| 150 |
+
endobj
|
| 151 |
+
xref
|
| 152 |
+
0 22
|
| 153 |
+
0000000000 65535 f
|
| 154 |
+
0000000073 00000 n
|
| 155 |
+
0000000144 00000 n
|
| 156 |
+
0000000251 00000 n
|
| 157 |
+
0000000363 00000 n
|
| 158 |
+
0000000478 00000 n
|
| 159 |
+
0000000597 00000 n
|
| 160 |
+
0000000802 00000 n
|
| 161 |
+
0000000907 00000 n
|
| 162 |
+
0000001112 00000 n
|
| 163 |
+
0000001317 00000 n
|
| 164 |
+
0000001523 00000 n
|
| 165 |
+
0000001729 00000 n
|
| 166 |
+
0000001935 00000 n
|
| 167 |
+
0000002005 00000 n
|
| 168 |
+
0000002289 00000 n
|
| 169 |
+
0000002382 00000 n
|
| 170 |
+
0000004296 00000 n
|
| 171 |
+
0000006050 00000 n
|
| 172 |
+
0000008094 00000 n
|
| 173 |
+
0000010203 00000 n
|
| 174 |
+
0000012264 00000 n
|
| 175 |
+
trailer
|
| 176 |
+
<<
|
| 177 |
+
/ID
|
| 178 |
+
[<6161c847c487331f71cdbc5a1598b1d8><6161c847c487331f71cdbc5a1598b1d8>]
|
| 179 |
+
% ReportLab generated PDF document -- digest (http://www.reportlab.com)
|
| 180 |
+
|
| 181 |
+
/Info 14 0 R
|
| 182 |
+
/Root 13 0 R
|
| 183 |
+
/Size 22
|
| 184 |
+
>>
|
| 185 |
+
startxref
|
| 186 |
+
13255
|
| 187 |
+
%%EOF
|