n-ou commited on
Commit
146e133
·
1 Parent(s): 392d774
data/context.json CHANGED
The diff for this file is too large to render. See raw diff
 
pyproject.toml CHANGED
@@ -4,24 +4,29 @@ version = "0.1.0"
4
  requires-python = ">=3.12"
5
  dependencies = [
6
  "anthropic>=0.52.2",
 
7
  "fitz>=0.0.1.dev2",
8
  "fpdf>=1.7.2",
9
  "frontend>=0.0.3",
10
  "google>=3.0.0",
11
  "google-generativeai>=0.8.5",
12
  "ipywidgets>=8.1.7",
 
13
  "langchain>=0.3.25",
14
  "langchain-anthropic>=0.3.14",
15
  "langchain-community>=0.3.24",
16
  "langchain-google-genai>=2.0.10",
17
  "langchain-openai>=0.3.19",
18
  "markdown>=3.8",
 
19
  "numpy>=2.2.6",
20
  "openai>=1.83.0",
21
  "orjson>=3.10.18",
 
22
  "plotly>=6.1.2",
23
  "pydantic>=2.11.5",
24
  "pydantic-ai>=0.2.12",
 
25
  "pypdf2>=3.0.1",
26
  "pyrsm>=1.6.0",
27
  "python-dotenv>=1.1.0",
@@ -30,4 +35,5 @@ dependencies = [
30
  "simplejson>=3.20.1",
31
  "tools>=1.0.2",
32
  "uuid>=1.30",
 
33
  ]
 
4
  requires-python = ">=3.12"
5
  dependencies = [
6
  "anthropic>=0.52.2",
7
+ "faker>=37.3.0",
8
  "fitz>=0.0.1.dev2",
9
  "fpdf>=1.7.2",
10
  "frontend>=0.0.3",
11
  "google>=3.0.0",
12
  "google-generativeai>=0.8.5",
13
  "ipywidgets>=8.1.7",
14
+ "jinja2>=3.1.6",
15
  "langchain>=0.3.25",
16
  "langchain-anthropic>=0.3.14",
17
  "langchain-community>=0.3.24",
18
  "langchain-google-genai>=2.0.10",
19
  "langchain-openai>=0.3.19",
20
  "markdown>=3.8",
21
+ "markdown2>=2.5.3",
22
  "numpy>=2.2.6",
23
  "openai>=1.83.0",
24
  "orjson>=3.10.18",
25
+ "pdfkit>=1.0.0",
26
  "plotly>=6.1.2",
27
  "pydantic>=2.11.5",
28
  "pydantic-ai>=0.2.12",
29
+ "pymupdf>=1.26.0",
30
  "pypdf2>=3.0.1",
31
  "pyrsm>=1.6.0",
32
  "python-dotenv>=1.1.0",
 
35
  "simplejson>=3.20.1",
36
  "tools>=1.0.2",
37
  "uuid>=1.30",
38
+ "weasyprint>=65.1",
39
  ]
server/candidate_profile.py CHANGED
@@ -9,7 +9,7 @@ import html
9
  import markdown
10
 
11
 
12
- RESUME_DIR = "../data/resumes"
13
 
14
  def extract_text_from_pdf(filename):
15
  path = os.path.join(RESUME_DIR, filename) + '.pdf'
@@ -144,7 +144,7 @@ def server(input, output, session):
144
  filtered = {
145
  cid: f"{v.get('Name', cid)} ({v.get('Resume File', 'N/A')})"
146
  for cid, v in candidates.items()
147
- if v.get("job_id") == job_id and v.get("Resume File")
148
  }
149
 
150
  print(f"✅ Found {len(filtered)} candidates for job {job_id}")
@@ -161,13 +161,15 @@ def server(input, output, session):
161
  @render.ui
162
  def summary():
163
  input.show_gemini() # ✅ force reactive trigger
164
- input.job_dropdown_doc()
165
- input.candidate_dropdown_doc()
166
 
167
- filename = input.candidate_dropdown_doc()
168
- job_id = input.job_dropdown_doc() # 🔧 ADD THIS LINE
169
  use_gemini = input.show_gemini()
170
 
 
 
171
  if not filename or not job_id:
172
  return "Please select both resume and job ID."
173
 
@@ -267,8 +269,8 @@ def server(input, output, session):
267
  @output
268
  @render.ui
269
  def score():
270
- filename = input.candidate_dropdown_doc()
271
- job_id = input.job_dropdown_doc()
272
 
273
  if not filename or not job_id:
274
  return ui.HTML("<p style='color: #888;'>Select a resume and job to view score.</p>")
@@ -276,7 +278,7 @@ def server(input, output, session):
276
  candidate_id = os.path.splitext(filename)[0]
277
  ctx = get_candidate_context(candidate_id)
278
 
279
- if ctx.get("job_id") == job_id and "avg_score" in ctx:
280
  score = ctx["avg_score"]
281
 
282
  # Choose a color based on the score
@@ -309,8 +311,8 @@ def server(input, output, session):
309
  @output
310
  @render.text
311
  def candidate_note_ui():
312
- filename = input.candidate_dropdown_doc()
313
- job_id = input.job_dropdown_doc()
314
  if not filename or not job_id:
315
  return ui.input_text_area("candidate_note", "Add a note:", rows=3)
316
 
@@ -322,8 +324,8 @@ def server(input, output, session):
322
  @output
323
  @render.ui
324
  def candidate_tags_ui():
325
- filename = input.candidate_dropdown_doc()
326
- job_id = input.job_dropdown_doc()
327
  if not filename or not job_id:
328
  return ui.input_text("candidate_tags", "Tags (comma-separated):")
329
 
@@ -336,8 +338,8 @@ def server(input, output, session):
336
  @output
337
  @render.text
338
  def note_preview():
339
- filename = input.candidate_dropdown_doc()
340
- job_id = input.job_dropdown_doc()
341
  if not filename or not job_id:
342
  return ""
343
 
@@ -355,8 +357,8 @@ def server(input, output, session):
355
  @render.text
356
  @reactive.event(input.save_note_tags)
357
  def note_tag_status():
358
- filename = input.candidate_dropdown_doc()
359
- job_id = input.job_dropdown_doc()
360
  if not filename or not job_id:
361
  return "❌ Please select both a resume and a job ID."
362
 
 
9
  import markdown
10
 
11
 
12
+ RESUME_DIR = "data/resumes/"
13
 
14
  def extract_text_from_pdf(filename):
15
  path = os.path.join(RESUME_DIR, filename) + '.pdf'
 
144
  filtered = {
145
  cid: f"{v.get('Name', cid)} ({v.get('Resume File', 'N/A')})"
146
  for cid, v in candidates.items()
147
+ if str(v.get("job_id")) == str(job_id) and v.get("Resume File")
148
  }
149
 
150
  print(f"✅ Found {len(filtered)} candidates for job {job_id}")
 
161
  @render.ui
162
  def summary():
163
  input.show_gemini() # ✅ force reactive trigger
164
+ input.job_dropdown_for_doc()
165
+ input.candidate_dropdown_for_doc()
166
 
167
+ filename = input.candidate_dropdown_for_doc()
168
+ job_id = input.job_dropdown_for_doc() # 🔧 ADD THIS LINE
169
  use_gemini = input.show_gemini()
170
 
171
+ print(filename)
172
+
173
  if not filename or not job_id:
174
  return "Please select both resume and job ID."
175
 
 
269
  @output
270
  @render.ui
271
  def score():
272
+ filename = input.candidate_dropdown_for_doc()
273
+ job_id = input.job_dropdown_for_doc()
274
 
275
  if not filename or not job_id:
276
  return ui.HTML("<p style='color: #888;'>Select a resume and job to view score.</p>")
 
278
  candidate_id = os.path.splitext(filename)[0]
279
  ctx = get_candidate_context(candidate_id)
280
 
281
+ if ctx.get("job_id") == str(job_id) and "avg_score" in ctx:
282
  score = ctx["avg_score"]
283
 
284
  # Choose a color based on the score
 
311
  @output
312
  @render.text
313
  def candidate_note_ui():
314
+ filename = input.candidate_dropdown_for_doc()
315
+ job_id = input.job_dropdown_for_doc()
316
  if not filename or not job_id:
317
  return ui.input_text_area("candidate_note", "Add a note:", rows=3)
318
 
 
324
  @output
325
  @render.ui
326
  def candidate_tags_ui():
327
+ filename = input.candidate_dropdown_for_doc()
328
+ job_id = input.job_dropdown_for_doc()
329
  if not filename or not job_id:
330
  return ui.input_text("candidate_tags", "Tags (comma-separated):")
331
 
 
338
  @output
339
  @render.text
340
  def note_preview():
341
+ filename = input.candidate_dropdown_for_doc()
342
+ job_id = input.job_dropdown_for_doc()
343
  if not filename or not job_id:
344
  return ""
345
 
 
357
  @render.text
358
  @reactive.event(input.save_note_tags)
359
  def note_tag_status():
360
+ filename = input.candidate_dropdown_for_doc()
361
+ job_id = input.job_dropdown_for_doc()
362
  if not filename or not job_id:
363
  return "❌ Please select both a resume and a job ID."
364
 
server/correlation_analysis.py CHANGED
@@ -80,9 +80,9 @@ def server(input, output, session):
80
  if not job_id:
81
  return pd.DataFrame()
82
  df = pd.DataFrame([c for c in raw.values() if c.get("job_id") == job_id])
83
- df["Years of Experience"] = pd.to_numeric(df["Years of Experience"], errors="coerce")
84
- df["avg_score"] = pd.to_numeric(df["avg_score"], errors="coerce")
85
- df["Key Skills"] = df["Key Skills"].apply(lambda x: ast.literal_eval(x) if isinstance(x, str) else x)
86
  return df
87
 
88
  @reactive.effect
 
80
  if not job_id:
81
  return pd.DataFrame()
82
  df = pd.DataFrame([c for c in raw.values() if c.get("job_id") == job_id])
83
+ #df["Years of Experience"] = pd.to_numeric(df["Years of Experience"], errors="coerce")
84
+ #df["avg_score"] = pd.to_numeric(df["avg_score"], errors="coerce")
85
+ #df["Key Skills"] = df["Key Skills"].apply(lambda x: ast.literal_eval(x) if isinstance(x, str) else x)
86
  return df
87
 
88
  @reactive.effect
server/document_creation.py CHANGED
@@ -64,6 +64,7 @@ def generate_full_contract(candidate_name, job_title, compensation, start_date,
64
 
65
 
66
  def server(input, output, session):
 
67
  # === Update job dropdown from context ===
68
  @reactive.effect
69
  def _populate_job_dropdown():
 
64
 
65
 
66
  def server(input, output, session):
67
+ print("✅ Entered document generation server()")
68
  # === Update job dropdown from context ===
69
  @reactive.effect
70
  def _populate_job_dropdown():
server/home.py CHANGED
@@ -15,11 +15,11 @@ from context import (
15
 
16
  init_context()
17
 
18
- UPLOAD_DIR = Path(os.path.join("..", "data"))
19
  UPLOAD_DIR.mkdir(parents=True, exist_ok=True)
20
 
21
  def server(input, output, session):
22
-
23
  @output
24
  @render.text
25
  @reactive.event(input.upload_resume_btn)
@@ -58,7 +58,7 @@ def server(input, output, session):
58
  all_jobs = get_all_jobs()
59
 
60
  chart_choices = {
61
- job_id: f"{job_data.get('title', 'Untitled')} ({job_id[:8]})"
62
  for job_id, job_data in all_jobs.items()
63
  }
64
 
 
15
 
16
  init_context()
17
 
18
+ UPLOAD_DIR = Path(__file__).resolve().parents[1] / "data" / "resumes"
19
  UPLOAD_DIR.mkdir(parents=True, exist_ok=True)
20
 
21
  def server(input, output, session):
22
+ print("✅ Entered homepage server()")
23
  @output
24
  @render.text
25
  @reactive.event(input.upload_resume_btn)
 
58
  all_jobs = get_all_jobs()
59
 
60
  chart_choices = {
61
+ job_id: f"{job_data.get('title', 'Untitled')} ({str(job_id)[:8]})"
62
  for job_id, job_data in all_jobs.items()
63
  }
64
 
server/interview_scheduler.py CHANGED
@@ -85,7 +85,7 @@ def export_email_as_pdf(name, email_text):
85
 
86
  # === MAIN SHINY SERVER FUNCTION ===
87
  def server(input, output, session):
88
- print("✅ Entered server()")
89
 
90
  if not hasattr(session, "_memo"):
91
  session._memo = {} # 🛠 manually initialize in-memory store
@@ -95,7 +95,7 @@ def server(input, output, session):
95
  raw_candidates = get_all_candidates()
96
  job_ids_used = {c.get("job_id") for c in raw_candidates.values() if "job_id" in c}
97
 
98
- path = "../data/context.json"
99
  try:
100
  with open(path, "r") as f:
101
  full = json.load(f)
 
85
 
86
  # === MAIN SHINY SERVER FUNCTION ===
87
  def server(input, output, session):
88
+ print("✅ Entered interview scheduler server()")
89
 
90
  if not hasattr(session, "_memo"):
91
  session._memo = {} # 🛠 manually initialize in-memory store
 
95
  raw_candidates = get_all_candidates()
96
  job_ids_used = {c.get("job_id") for c in raw_candidates.values() if "job_id" in c}
97
 
98
+ path = "data/context.json"
99
  try:
100
  with open(path, "r") as f:
101
  full = json.load(f)
server/job_creation.py CHANGED
@@ -64,6 +64,7 @@ Job Description:
64
 
65
 
66
  def server(input, output, session):
 
67
  session_id = str(uuid.uuid4())
68
  chat_status = reactive.Value("")
69
  save_status = reactive.Value("")
 
64
 
65
 
66
  def server(input, output, session):
67
+ print("✅ Entered job post creation server()")
68
  session_id = str(uuid.uuid4())
69
  chat_status = reactive.Value("")
70
  save_status = reactive.Value("")
server/plot_generation.py CHANGED
@@ -86,7 +86,7 @@ model = genai.GenerativeModel("gemini-2.0-flash", tools=[plot_tool])
86
  # === MAIN SHINY SERVER FUNCTION ===
87
 
88
  def server(input, output, session):
89
- print("✅ Entered server()")
90
 
91
  last_cols = reactive.Value(('', ''))
92
  last_type = reactive.Value('')
 
86
  # === MAIN SHINY SERVER FUNCTION ===
87
 
88
  def server(input, output, session):
89
+ print("✅ Entered plot generation server()")
90
 
91
  last_cols = reactive.Value(('', ''))
92
  last_type = reactive.Value('')
uv.lock CHANGED
@@ -257,6 +257,61 @@ wheels = [
257
  { url = "https://files.pythonhosted.org/packages/bc/0f/7090e2b6cef7c7f8d8c92a98ccfdb3800f2de90e553df7fb9c63c9e882d0/botocore-1.38.28-py3-none-any.whl", hash = "sha256:515e1a535a27f17e1381aec1fb48eaa2c2308258c4db0bfd09e4f1cd1f239c44", size = 13586155 },
258
  ]
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  [[package]]
261
  name = "cachetools"
262
  version = "5.5.2"
@@ -464,6 +519,19 @@ wheels = [
464
  { url = "https://files.pythonhosted.org/packages/b0/e6/6000d0094e8a5e32ad62591c8609e269febb6e4db83a1c75ff8868b42731/contourpy-1.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:78e9253c3de756b3f6a5174d024c4835acd59eb3f8e2ca13e775dbffe1558f69", size = 238214 },
465
  ]
466
 
 
 
 
 
 
 
 
 
 
 
 
 
 
467
  [[package]]
468
  name = "cycler"
469
  version = "0.12.1"
@@ -598,6 +666,18 @@ wheels = [
598
  { url = "https://files.pythonhosted.org/packages/65/3c/1db1b0f878319bb227f35a0fca7cad64e1f528b518bcab1a708da305c86d/faicons-0.2.2-py3-none-any.whl", hash = "sha256:d45d7c2635b53582a3375c67d7e975a28a91d2c16ef5f6b5033b5cdd507224b6", size = 607225 },
599
  ]
600
 
 
 
 
 
 
 
 
 
 
 
 
 
601
  [[package]]
602
  name = "fasta2a"
603
  version = "0.2.12"
@@ -699,6 +779,13 @@ wheels = [
699
  { url = "https://files.pythonhosted.org/packages/21/ff/995277586691c0cc314c28b24b4ec30610440fd7bf580072aed1409f95b0/fonttools-4.58.1-py3-none-any.whl", hash = "sha256:db88365d0962cd6f5bce54b190a4669aeed9c9941aa7bd60a5af084d8d9173d6", size = 1113429 },
700
  ]
701
 
 
 
 
 
 
 
 
702
  [[package]]
703
  name = "fpdf"
704
  version = "1.7.2"
@@ -998,24 +1085,29 @@ version = "0.1.0"
998
  source = { virtual = "." }
999
  dependencies = [
1000
  { name = "anthropic" },
 
1001
  { name = "fitz" },
1002
  { name = "fpdf" },
1003
  { name = "frontend" },
1004
  { name = "google" },
1005
  { name = "google-generativeai" },
1006
  { name = "ipywidgets" },
 
1007
  { name = "langchain" },
1008
  { name = "langchain-anthropic" },
1009
  { name = "langchain-community" },
1010
  { name = "langchain-google-genai" },
1011
  { name = "langchain-openai" },
1012
  { name = "markdown" },
 
1013
  { name = "numpy" },
1014
  { name = "openai" },
1015
  { name = "orjson" },
 
1016
  { name = "plotly" },
1017
  { name = "pydantic" },
1018
  { name = "pydantic-ai" },
 
1019
  { name = "pypdf2" },
1020
  { name = "pyrsm" },
1021
  { name = "python-dotenv" },
@@ -1024,29 +1116,35 @@ dependencies = [
1024
  { name = "simplejson" },
1025
  { name = "tools" },
1026
  { name = "uuid" },
 
1027
  ]
1028
 
1029
  [package.metadata]
1030
  requires-dist = [
1031
  { name = "anthropic", specifier = ">=0.52.2" },
 
1032
  { name = "fitz", specifier = ">=0.0.1.dev2" },
1033
  { name = "fpdf", specifier = ">=1.7.2" },
1034
  { name = "frontend", specifier = ">=0.0.3" },
1035
  { name = "google", specifier = ">=3.0.0" },
1036
  { name = "google-generativeai", specifier = ">=0.8.5" },
1037
  { name = "ipywidgets", specifier = ">=8.1.7" },
 
1038
  { name = "langchain", specifier = ">=0.3.25" },
1039
  { name = "langchain-anthropic", specifier = ">=0.3.14" },
1040
  { name = "langchain-community", specifier = ">=0.3.24" },
1041
  { name = "langchain-google-genai", specifier = ">=2.0.10" },
1042
  { name = "langchain-openai", specifier = ">=0.3.19" },
1043
  { name = "markdown", specifier = ">=3.8" },
 
1044
  { name = "numpy", specifier = ">=2.2.6" },
1045
  { name = "openai", specifier = ">=1.83.0" },
1046
  { name = "orjson", specifier = ">=3.10.18" },
 
1047
  { name = "plotly", specifier = ">=6.1.2" },
1048
  { name = "pydantic", specifier = ">=2.11.5" },
1049
  { name = "pydantic-ai", specifier = ">=0.2.12" },
 
1050
  { name = "pypdf2", specifier = ">=3.0.1" },
1051
  { name = "pyrsm", specifier = ">=1.6.0" },
1052
  { name = "python-dotenv", specifier = ">=1.1.0" },
@@ -1055,6 +1153,7 @@ requires-dist = [
1055
  { name = "simplejson", specifier = ">=3.20.1" },
1056
  { name = "tools", specifier = ">=1.0.2" },
1057
  { name = "uuid", specifier = ">=1.30" },
 
1058
  ]
1059
 
1060
  [[package]]
@@ -1331,6 +1430,18 @@ wheels = [
1331
  { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278 },
1332
  ]
1333
 
 
 
 
 
 
 
 
 
 
 
 
 
1334
  [[package]]
1335
  name = "jiter"
1336
  version = "0.10.0"
@@ -1733,6 +1844,53 @@ wheels = [
1733
  { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528 },
1734
  ]
1735
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1736
  [[package]]
1737
  name = "marshmallow"
1738
  version = "3.26.1"
@@ -2188,6 +2346,15 @@ wheels = [
2188
  { url = "https://files.pythonhosted.org/packages/87/2b/b50d3d08ea0fc419c183a84210571eba005328efa62b6b98bc28e9ead32a/patsy-1.0.1-py2.py3-none-any.whl", hash = "sha256:751fb38f9e97e62312e921a1954b81e1bb2bcda4f5eeabaf94db251ee791509c", size = 232923 },
2189
  ]
2190
 
 
 
 
 
 
 
 
 
 
2191
  [[package]]
2192
  name = "pexpect"
2193
  version = "4.9.0"
@@ -2680,6 +2847,15 @@ wheels = [
2680
  { url = "https://files.pythonhosted.org/packages/0a/16/984c0cf5073a23154b1f95c9d131b14c9fea83bfadae4ba8fc169daded11/pydot-4.0.0-py3-none-any.whl", hash = "sha256:cf86e13a6cfe2a96758a9702537f77e0ac1368db8ef277b4d3b34473ea425c97", size = 37535 },
2681
  ]
2682
 
 
 
 
 
 
 
 
 
 
2683
  [[package]]
2684
  name = "pygments"
2685
  version = "2.19.1"
@@ -2689,6 +2865,21 @@ wheels = [
2689
  { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293 },
2690
  ]
2691
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2692
  [[package]]
2693
  name = "pyparsing"
2694
  version = "3.2.3"
@@ -2707,6 +2898,15 @@ wheels = [
2707
  { url = "https://files.pythonhosted.org/packages/8e/5e/c86a5643653825d3c913719e788e41386bee415c2b87b4f955432f2de6b2/pypdf2-3.0.1-py3-none-any.whl", hash = "sha256:d16e4205cfee272fbdc0568b68d82be796540b1537508cef59388f839c191928", size = 232572 },
2708
  ]
2709
 
 
 
 
 
 
 
 
 
 
2710
  [[package]]
2711
  name = "pyrsm"
2712
  version = "1.6.0"
@@ -3350,6 +3550,30 @@ wheels = [
3350
  { url = "https://files.pythonhosted.org/packages/de/a8/8f499c179ec900783ffe133e9aab10044481679bb9aad78436d239eee716/tiktoken-0.9.0-cp313-cp313-win_amd64.whl", hash = "sha256:5ea0edb6f83dc56d794723286215918c1cde03712cbbafa0348b33448faf5b95", size = 894669 },
3351
  ]
3352
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3353
  [[package]]
3354
  name = "tokenizers"
3355
  version = "0.21.1"
@@ -3594,6 +3818,34 @@ wheels = [
3594
  { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166 },
3595
  ]
3596
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3597
  [[package]]
3598
  name = "websockets"
3599
  version = "15.0.1"
@@ -3770,6 +4022,34 @@ wheels = [
3770
  { url = "https://files.pythonhosted.org/packages/ad/da/f64669af4cae46f17b90798a827519ce3737d31dbafad65d391e49643dc4/zipp-3.22.0-py3-none-any.whl", hash = "sha256:fe208f65f2aca48b81f9e6fd8cf7b8b32c26375266b009b413d45306b6148343", size = 9796 },
3771
  ]
3772
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3773
  [[package]]
3774
  name = "zstandard"
3775
  version = "0.23.0"
 
257
  { url = "https://files.pythonhosted.org/packages/bc/0f/7090e2b6cef7c7f8d8c92a98ccfdb3800f2de90e553df7fb9c63c9e882d0/botocore-1.38.28-py3-none-any.whl", hash = "sha256:515e1a535a27f17e1381aec1fb48eaa2c2308258c4db0bfd09e4f1cd1f239c44", size = 13586155 },
258
  ]
259
 
260
+ [[package]]
261
+ name = "brotli"
262
+ version = "1.1.0"
263
+ source = { registry = "https://pypi.org/simple" }
264
+ sdist = { url = "https://files.pythonhosted.org/packages/2f/c2/f9e977608bdf958650638c3f1e28f85a1b075f075ebbe77db8555463787b/Brotli-1.1.0.tar.gz", hash = "sha256:81de08ac11bcb85841e440c13611c00b67d3bf82698314928d0b676362546724", size = 7372270 }
265
+ wheels = [
266
+ { url = "https://files.pythonhosted.org/packages/5c/d0/5373ae13b93fe00095a58efcbce837fd470ca39f703a235d2a999baadfbc/Brotli-1.1.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:32d95b80260d79926f5fab3c41701dbb818fde1c9da590e77e571eefd14abe28", size = 815693 },
267
+ { url = "https://files.pythonhosted.org/packages/8e/48/f6e1cdf86751300c288c1459724bfa6917a80e30dbfc326f92cea5d3683a/Brotli-1.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b760c65308ff1e462f65d69c12e4ae085cff3b332d894637f6273a12a482d09f", size = 422489 },
268
+ { url = "https://files.pythonhosted.org/packages/06/88/564958cedce636d0f1bed313381dfc4b4e3d3f6015a63dae6146e1b8c65c/Brotli-1.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:316cc9b17edf613ac76b1f1f305d2a748f1b976b033b049a6ecdfd5612c70409", size = 873081 },
269
+ { url = "https://files.pythonhosted.org/packages/58/79/b7026a8bb65da9a6bb7d14329fd2bd48d2b7f86d7329d5cc8ddc6a90526f/Brotli-1.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:caf9ee9a5775f3111642d33b86237b05808dafcd6268faa492250e9b78046eb2", size = 446244 },
270
+ { url = "https://files.pythonhosted.org/packages/e5/18/c18c32ecea41b6c0004e15606e274006366fe19436b6adccc1ae7b2e50c2/Brotli-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70051525001750221daa10907c77830bc889cb6d865cc0b813d9db7fefc21451", size = 2906505 },
271
+ { url = "https://files.pythonhosted.org/packages/08/c8/69ec0496b1ada7569b62d85893d928e865df29b90736558d6c98c2031208/Brotli-1.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7f4bf76817c14aa98cc6697ac02f3972cb8c3da93e9ef16b9c66573a68014f91", size = 2944152 },
272
+ { url = "https://files.pythonhosted.org/packages/ab/fb/0517cea182219d6768113a38167ef6d4eb157a033178cc938033a552ed6d/Brotli-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0c5516f0aed654134a2fc936325cc2e642f8a0e096d075209672eb321cff408", size = 2919252 },
273
+ { url = "https://files.pythonhosted.org/packages/c7/53/73a3431662e33ae61a5c80b1b9d2d18f58dfa910ae8dd696e57d39f1a2f5/Brotli-1.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c3020404e0b5eefd7c9485ccf8393cfb75ec38ce75586e046573c9dc29967a0", size = 2845955 },
274
+ { url = "https://files.pythonhosted.org/packages/55/ac/bd280708d9c5ebdbf9de01459e625a3e3803cce0784f47d633562cf40e83/Brotli-1.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4ed11165dd45ce798d99a136808a794a748d5dc38511303239d4e2363c0695dc", size = 2914304 },
275
+ { url = "https://files.pythonhosted.org/packages/76/58/5c391b41ecfc4527d2cc3350719b02e87cb424ef8ba2023fb662f9bf743c/Brotli-1.1.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4093c631e96fdd49e0377a9c167bfd75b6d0bad2ace734c6eb20b348bc3ea180", size = 2814452 },
276
+ { url = "https://files.pythonhosted.org/packages/c7/4e/91b8256dfe99c407f174924b65a01f5305e303f486cc7a2e8a5d43c8bec3/Brotli-1.1.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e4c4629ddad63006efa0ef968c8e4751c5868ff0b1c5c40f76524e894c50248", size = 2938751 },
277
+ { url = "https://files.pythonhosted.org/packages/5a/a6/e2a39a5d3b412938362bbbeba5af904092bf3f95b867b4a3eb856104074e/Brotli-1.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:861bf317735688269936f755fa136a99d1ed526883859f86e41a5d43c61d8966", size = 2933757 },
278
+ { url = "https://files.pythonhosted.org/packages/13/f0/358354786280a509482e0e77c1a5459e439766597d280f28cb097642fc26/Brotli-1.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:87a3044c3a35055527ac75e419dfa9f4f3667a1e887ee80360589eb8c90aabb9", size = 2936146 },
279
+ { url = "https://files.pythonhosted.org/packages/80/f7/daf538c1060d3a88266b80ecc1d1c98b79553b3f117a485653f17070ea2a/Brotli-1.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c5529b34c1c9d937168297f2c1fde7ebe9ebdd5e121297ff9c043bdb2ae3d6fb", size = 2848055 },
280
+ { url = "https://files.pythonhosted.org/packages/ad/cf/0eaa0585c4077d3c2d1edf322d8e97aabf317941d3a72d7b3ad8bce004b0/Brotli-1.1.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ca63e1890ede90b2e4454f9a65135a4d387a4585ff8282bb72964fab893f2111", size = 3035102 },
281
+ { url = "https://files.pythonhosted.org/packages/d8/63/1c1585b2aa554fe6dbce30f0c18bdbc877fa9a1bf5ff17677d9cca0ac122/Brotli-1.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e79e6520141d792237c70bcd7a3b122d00f2613769ae0cb61c52e89fd3443839", size = 2930029 },
282
+ { url = "https://files.pythonhosted.org/packages/5f/3b/4e3fd1893eb3bbfef8e5a80d4508bec17a57bb92d586c85c12d28666bb13/Brotli-1.1.0-cp312-cp312-win32.whl", hash = "sha256:5f4d5ea15c9382135076d2fb28dde923352fe02951e66935a9efaac8f10e81b0", size = 333276 },
283
+ { url = "https://files.pythonhosted.org/packages/3d/d5/942051b45a9e883b5b6e98c041698b1eb2012d25e5948c58d6bf85b1bb43/Brotli-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:906bc3a79de8c4ae5b86d3d75a8b77e44404b0f4261714306e3ad248d8ab0951", size = 357255 },
284
+ { url = "https://files.pythonhosted.org/packages/0a/9f/fb37bb8ffc52a8da37b1c03c459a8cd55df7a57bdccd8831d500e994a0ca/Brotli-1.1.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8bf32b98b75c13ec7cf774164172683d6e7891088f6316e54425fde1efc276d5", size = 815681 },
285
+ { url = "https://files.pythonhosted.org/packages/06/b3/dbd332a988586fefb0aa49c779f59f47cae76855c2d00f450364bb574cac/Brotli-1.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7bc37c4d6b87fb1017ea28c9508b36bbcb0c3d18b4260fcdf08b200c74a6aee8", size = 422475 },
286
+ { url = "https://files.pythonhosted.org/packages/bb/80/6aaddc2f63dbcf2d93c2d204e49c11a9ec93a8c7c63261e2b4bd35198283/Brotli-1.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c0ef38c7a7014ffac184db9e04debe495d317cc9c6fb10071f7fefd93100a4f", size = 2906173 },
287
+ { url = "https://files.pythonhosted.org/packages/ea/1d/e6ca79c96ff5b641df6097d299347507d39a9604bde8915e76bf026d6c77/Brotli-1.1.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91d7cc2a76b5567591d12c01f019dd7afce6ba8cba6571187e21e2fc418ae648", size = 2943803 },
288
+ { url = "https://files.pythonhosted.org/packages/ac/a3/d98d2472e0130b7dd3acdbb7f390d478123dbf62b7d32bda5c830a96116d/Brotli-1.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a93dde851926f4f2678e704fadeb39e16c35d8baebd5252c9fd94ce8ce68c4a0", size = 2918946 },
289
+ { url = "https://files.pythonhosted.org/packages/c4/a5/c69e6d272aee3e1423ed005d8915a7eaa0384c7de503da987f2d224d0721/Brotli-1.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f0db75f47be8b8abc8d9e31bc7aad0547ca26f24a54e6fd10231d623f183d089", size = 2845707 },
290
+ { url = "https://files.pythonhosted.org/packages/58/9f/4149d38b52725afa39067350696c09526de0125ebfbaab5acc5af28b42ea/Brotli-1.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6967ced6730aed543b8673008b5a391c3b1076d834ca438bbd70635c73775368", size = 2936231 },
291
+ { url = "https://files.pythonhosted.org/packages/5a/5a/145de884285611838a16bebfdb060c231c52b8f84dfbe52b852a15780386/Brotli-1.1.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7eedaa5d036d9336c95915035fb57422054014ebdeb6f3b42eac809928e40d0c", size = 2848157 },
292
+ { url = "https://files.pythonhosted.org/packages/50/ae/408b6bfb8525dadebd3b3dd5b19d631da4f7d46420321db44cd99dcf2f2c/Brotli-1.1.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d487f5432bf35b60ed625d7e1b448e2dc855422e87469e3f450aa5552b0eb284", size = 3035122 },
293
+ { url = "https://files.pythonhosted.org/packages/af/85/a94e5cfaa0ca449d8f91c3d6f78313ebf919a0dbd55a100c711c6e9655bc/Brotli-1.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:832436e59afb93e1836081a20f324cb185836c617659b07b129141a8426973c7", size = 2930206 },
294
+ { url = "https://files.pythonhosted.org/packages/c2/f0/a61d9262cd01351df22e57ad7c34f66794709acab13f34be2675f45bf89d/Brotli-1.1.0-cp313-cp313-win32.whl", hash = "sha256:43395e90523f9c23a3d5bdf004733246fba087f2948f87ab28015f12359ca6a0", size = 333804 },
295
+ { url = "https://files.pythonhosted.org/packages/7e/c1/ec214e9c94000d1c1974ec67ced1c970c148aa6b8d8373066123fc3dbf06/Brotli-1.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:9011560a466d2eb3f5a6e4929cf4a09be405c64154e12df0dd72713f6500e32b", size = 358517 },
296
+ ]
297
+
298
+ [[package]]
299
+ name = "brotlicffi"
300
+ version = "1.1.0.0"
301
+ source = { registry = "https://pypi.org/simple" }
302
+ dependencies = [
303
+ { name = "cffi" },
304
+ ]
305
+ sdist = { url = "https://files.pythonhosted.org/packages/95/9d/70caa61192f570fcf0352766331b735afa931b4c6bc9a348a0925cc13288/brotlicffi-1.1.0.0.tar.gz", hash = "sha256:b77827a689905143f87915310b93b273ab17888fd43ef350d4832c4a71083c13", size = 465192 }
306
+ wheels = [
307
+ { url = "https://files.pythonhosted.org/packages/a2/11/7b96009d3dcc2c931e828ce1e157f03824a69fb728d06bfd7b2fc6f93718/brotlicffi-1.1.0.0-cp37-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9b7ae6bd1a3f0df532b6d67ff674099a96d22bc0948955cb338488c31bfb8851", size = 453786 },
308
+ { url = "https://files.pythonhosted.org/packages/d6/e6/a8f46f4a4ee7856fbd6ac0c6fb0dc65ed181ba46cd77875b8d9bbe494d9e/brotlicffi-1.1.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19ffc919fa4fc6ace69286e0a23b3789b4219058313cf9b45625016bf7ff996b", size = 2911165 },
309
+ { url = "https://files.pythonhosted.org/packages/be/20/201559dff14e83ba345a5ec03335607e47467b6633c210607e693aefac40/brotlicffi-1.1.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9feb210d932ffe7798ee62e6145d3a757eb6233aa9a4e7db78dd3690d7755814", size = 2927895 },
310
+ { url = "https://files.pythonhosted.org/packages/cd/15/695b1409264143be3c933f708a3f81d53c4a1e1ebbc06f46331decbf6563/brotlicffi-1.1.0.0-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84763dbdef5dd5c24b75597a77e1b30c66604725707565188ba54bab4f114820", size = 2851834 },
311
+ { url = "https://files.pythonhosted.org/packages/b4/40/b961a702463b6005baf952794c2e9e0099bde657d0d7e007f923883b907f/brotlicffi-1.1.0.0-cp37-abi3-win32.whl", hash = "sha256:1b12b50e07c3911e1efa3a8971543e7648100713d4e0971b13631cce22c587eb", size = 341731 },
312
+ { url = "https://files.pythonhosted.org/packages/1c/fa/5408a03c041114ceab628ce21766a4ea882aa6f6f0a800e04ee3a30ec6b9/brotlicffi-1.1.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:994a4f0681bb6c6c3b0925530a1926b7a189d878e6e5e38fae8efa47c5d9c613", size = 366783 },
313
+ ]
314
+
315
  [[package]]
316
  name = "cachetools"
317
  version = "5.5.2"
 
519
  { url = "https://files.pythonhosted.org/packages/b0/e6/6000d0094e8a5e32ad62591c8609e269febb6e4db83a1c75ff8868b42731/contourpy-1.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:78e9253c3de756b3f6a5174d024c4835acd59eb3f8e2ca13e775dbffe1558f69", size = 238214 },
520
  ]
521
 
522
+ [[package]]
523
+ name = "cssselect2"
524
+ version = "0.8.0"
525
+ source = { registry = "https://pypi.org/simple" }
526
+ dependencies = [
527
+ { name = "tinycss2" },
528
+ { name = "webencodings" },
529
+ ]
530
+ sdist = { url = "https://files.pythonhosted.org/packages/9f/86/fd7f58fc498b3166f3a7e8e0cddb6e620fe1da35b02248b1bd59e95dbaaa/cssselect2-0.8.0.tar.gz", hash = "sha256:7674ffb954a3b46162392aee2a3a0aedb2e14ecf99fcc28644900f4e6e3e9d3a", size = 35716 }
531
+ wheels = [
532
+ { url = "https://files.pythonhosted.org/packages/0f/e7/aa315e6a749d9b96c2504a1ba0ba031ba2d0517e972ce22682e3fccecb09/cssselect2-0.8.0-py3-none-any.whl", hash = "sha256:46fc70ebc41ced7a32cd42d58b1884d72ade23d21e5a4eaaf022401c13f0e76e", size = 15454 },
533
+ ]
534
+
535
  [[package]]
536
  name = "cycler"
537
  version = "0.12.1"
 
666
  { url = "https://files.pythonhosted.org/packages/65/3c/1db1b0f878319bb227f35a0fca7cad64e1f528b518bcab1a708da305c86d/faicons-0.2.2-py3-none-any.whl", hash = "sha256:d45d7c2635b53582a3375c67d7e975a28a91d2c16ef5f6b5033b5cdd507224b6", size = 607225 },
667
  ]
668
 
669
+ [[package]]
670
+ name = "faker"
671
+ version = "37.3.0"
672
+ source = { registry = "https://pypi.org/simple" }
673
+ dependencies = [
674
+ { name = "tzdata" },
675
+ ]
676
+ sdist = { url = "https://files.pythonhosted.org/packages/97/4b/5354912eaff922876323f2d07e21408b10867f3295d5f917748341cb6f53/faker-37.3.0.tar.gz", hash = "sha256:77b79e7a2228d57175133af0bbcdd26dc623df81db390ee52f5104d46c010f2f", size = 1901376 }
677
+ wheels = [
678
+ { url = "https://files.pythonhosted.org/packages/ce/99/045b2dae19a01b9fbb23b9971bc04f4ef808e7f3a213d08c81067304a210/faker-37.3.0-py3-none-any.whl", hash = "sha256:48c94daa16a432f2d2bc803c7ff602509699fca228d13e97e379cd860a7e216e", size = 1942203 },
679
+ ]
680
+
681
  [[package]]
682
  name = "fasta2a"
683
  version = "0.2.12"
 
779
  { url = "https://files.pythonhosted.org/packages/21/ff/995277586691c0cc314c28b24b4ec30610440fd7bf580072aed1409f95b0/fonttools-4.58.1-py3-none-any.whl", hash = "sha256:db88365d0962cd6f5bce54b190a4669aeed9c9941aa7bd60a5af084d8d9173d6", size = 1113429 },
780
  ]
781
 
782
+ [package.optional-dependencies]
783
+ woff = [
784
+ { name = "brotli", marker = "platform_python_implementation == 'CPython'" },
785
+ { name = "brotlicffi", marker = "platform_python_implementation != 'CPython'" },
786
+ { name = "zopfli" },
787
+ ]
788
+
789
  [[package]]
790
  name = "fpdf"
791
  version = "1.7.2"
 
1085
  source = { virtual = "." }
1086
  dependencies = [
1087
  { name = "anthropic" },
1088
+ { name = "faker" },
1089
  { name = "fitz" },
1090
  { name = "fpdf" },
1091
  { name = "frontend" },
1092
  { name = "google" },
1093
  { name = "google-generativeai" },
1094
  { name = "ipywidgets" },
1095
+ { name = "jinja2" },
1096
  { name = "langchain" },
1097
  { name = "langchain-anthropic" },
1098
  { name = "langchain-community" },
1099
  { name = "langchain-google-genai" },
1100
  { name = "langchain-openai" },
1101
  { name = "markdown" },
1102
+ { name = "markdown2" },
1103
  { name = "numpy" },
1104
  { name = "openai" },
1105
  { name = "orjson" },
1106
+ { name = "pdfkit" },
1107
  { name = "plotly" },
1108
  { name = "pydantic" },
1109
  { name = "pydantic-ai" },
1110
+ { name = "pymupdf" },
1111
  { name = "pypdf2" },
1112
  { name = "pyrsm" },
1113
  { name = "python-dotenv" },
 
1116
  { name = "simplejson" },
1117
  { name = "tools" },
1118
  { name = "uuid" },
1119
+ { name = "weasyprint" },
1120
  ]
1121
 
1122
  [package.metadata]
1123
  requires-dist = [
1124
  { name = "anthropic", specifier = ">=0.52.2" },
1125
+ { name = "faker", specifier = ">=37.3.0" },
1126
  { name = "fitz", specifier = ">=0.0.1.dev2" },
1127
  { name = "fpdf", specifier = ">=1.7.2" },
1128
  { name = "frontend", specifier = ">=0.0.3" },
1129
  { name = "google", specifier = ">=3.0.0" },
1130
  { name = "google-generativeai", specifier = ">=0.8.5" },
1131
  { name = "ipywidgets", specifier = ">=8.1.7" },
1132
+ { name = "jinja2", specifier = ">=3.1.6" },
1133
  { name = "langchain", specifier = ">=0.3.25" },
1134
  { name = "langchain-anthropic", specifier = ">=0.3.14" },
1135
  { name = "langchain-community", specifier = ">=0.3.24" },
1136
  { name = "langchain-google-genai", specifier = ">=2.0.10" },
1137
  { name = "langchain-openai", specifier = ">=0.3.19" },
1138
  { name = "markdown", specifier = ">=3.8" },
1139
+ { name = "markdown2", specifier = ">=2.5.3" },
1140
  { name = "numpy", specifier = ">=2.2.6" },
1141
  { name = "openai", specifier = ">=1.83.0" },
1142
  { name = "orjson", specifier = ">=3.10.18" },
1143
+ { name = "pdfkit", specifier = ">=1.0.0" },
1144
  { name = "plotly", specifier = ">=6.1.2" },
1145
  { name = "pydantic", specifier = ">=2.11.5" },
1146
  { name = "pydantic-ai", specifier = ">=0.2.12" },
1147
+ { name = "pymupdf", specifier = ">=1.26.0" },
1148
  { name = "pypdf2", specifier = ">=3.0.1" },
1149
  { name = "pyrsm", specifier = ">=1.6.0" },
1150
  { name = "python-dotenv", specifier = ">=1.1.0" },
 
1153
  { name = "simplejson", specifier = ">=3.20.1" },
1154
  { name = "tools", specifier = ">=1.0.2" },
1155
  { name = "uuid", specifier = ">=1.30" },
1156
+ { name = "weasyprint", specifier = ">=65.1" },
1157
  ]
1158
 
1159
  [[package]]
 
1430
  { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278 },
1431
  ]
1432
 
1433
+ [[package]]
1434
+ name = "jinja2"
1435
+ version = "3.1.6"
1436
+ source = { registry = "https://pypi.org/simple" }
1437
+ dependencies = [
1438
+ { name = "markupsafe" },
1439
+ ]
1440
+ sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115 }
1441
+ wheels = [
1442
+ { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899 },
1443
+ ]
1444
+
1445
  [[package]]
1446
  name = "jiter"
1447
  version = "0.10.0"
 
1844
  { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528 },
1845
  ]
1846
 
1847
+ [[package]]
1848
+ name = "markdown2"
1849
+ version = "2.5.3"
1850
+ source = { registry = "https://pypi.org/simple" }
1851
+ sdist = { url = "https://files.pythonhosted.org/packages/44/52/d7dcc6284d59edb8301b8400435fbb4926a9b0f13a12b5cbaf3a4a54bb7b/markdown2-2.5.3.tar.gz", hash = "sha256:4d502953a4633408b0ab3ec503c5d6984d1b14307e32b325ec7d16ea57524895", size = 141676 }
1852
+ wheels = [
1853
+ { url = "https://files.pythonhosted.org/packages/84/37/0a13c83ccf5365b8e08ea572dfbc04b8cb87cadd359b2451a567f5248878/markdown2-2.5.3-py3-none-any.whl", hash = "sha256:a8ebb7e84b8519c37bf7382b3db600f1798a22c245bfd754a1f87ca8d7ea63b3", size = 48550 },
1854
+ ]
1855
+
1856
+ [[package]]
1857
+ name = "markupsafe"
1858
+ version = "3.0.2"
1859
+ source = { registry = "https://pypi.org/simple" }
1860
+ sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537 }
1861
+ wheels = [
1862
+ { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274 },
1863
+ { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348 },
1864
+ { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149 },
1865
+ { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118 },
1866
+ { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993 },
1867
+ { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178 },
1868
+ { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319 },
1869
+ { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352 },
1870
+ { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097 },
1871
+ { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601 },
1872
+ { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274 },
1873
+ { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352 },
1874
+ { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122 },
1875
+ { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085 },
1876
+ { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978 },
1877
+ { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208 },
1878
+ { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357 },
1879
+ { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344 },
1880
+ { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101 },
1881
+ { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603 },
1882
+ { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510 },
1883
+ { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486 },
1884
+ { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480 },
1885
+ { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914 },
1886
+ { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796 },
1887
+ { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473 },
1888
+ { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114 },
1889
+ { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098 },
1890
+ { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208 },
1891
+ { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739 },
1892
+ ]
1893
+
1894
  [[package]]
1895
  name = "marshmallow"
1896
  version = "3.26.1"
 
2346
  { url = "https://files.pythonhosted.org/packages/87/2b/b50d3d08ea0fc419c183a84210571eba005328efa62b6b98bc28e9ead32a/patsy-1.0.1-py2.py3-none-any.whl", hash = "sha256:751fb38f9e97e62312e921a1954b81e1bb2bcda4f5eeabaf94db251ee791509c", size = 232923 },
2347
  ]
2348
 
2349
+ [[package]]
2350
+ name = "pdfkit"
2351
+ version = "1.0.0"
2352
+ source = { registry = "https://pypi.org/simple" }
2353
+ sdist = { url = "https://files.pythonhosted.org/packages/58/bb/6ddc62b4622776a6514fd749041c2b4bccd343e006d00de590f8090ac8b1/pdfkit-1.0.0.tar.gz", hash = "sha256:992f821e1e18fc8a0e701ecae24b51a2d598296a180caee0a24c0af181da02a9", size = 13288 }
2354
+ wheels = [
2355
+ { url = "https://files.pythonhosted.org/packages/64/1b/26c080096dd93936dccfd32c682bed3d5630a84aae9d493ff68afb2ae0fb/pdfkit-1.0.0-py3-none-any.whl", hash = "sha256:a7a4ca0d978e44fa8310c4909f087052430a6e8e0b1dd7ceef657f139789f96f", size = 12099 },
2356
+ ]
2357
+
2358
  [[package]]
2359
  name = "pexpect"
2360
  version = "4.9.0"
 
2847
  { url = "https://files.pythonhosted.org/packages/0a/16/984c0cf5073a23154b1f95c9d131b14c9fea83bfadae4ba8fc169daded11/pydot-4.0.0-py3-none-any.whl", hash = "sha256:cf86e13a6cfe2a96758a9702537f77e0ac1368db8ef277b4d3b34473ea425c97", size = 37535 },
2848
  ]
2849
 
2850
+ [[package]]
2851
+ name = "pydyf"
2852
+ version = "0.11.0"
2853
+ source = { registry = "https://pypi.org/simple" }
2854
+ sdist = { url = "https://files.pythonhosted.org/packages/2e/c2/97fc6ce4ce0045080dc99446def812081b57750ed8aa67bfdfafa4561fe5/pydyf-0.11.0.tar.gz", hash = "sha256:394dddf619cca9d0c55715e3c55ea121a9bf9cbc780cdc1201a2427917b86b64", size = 17769 }
2855
+ wheels = [
2856
+ { url = "https://files.pythonhosted.org/packages/c9/ac/d5db977deaf28c6ecbc61bbca269eb3e8f0b3a1f55c8549e5333e606e005/pydyf-0.11.0-py3-none-any.whl", hash = "sha256:0aaf9e2ebbe786ec7a78ec3fbffa4cdcecde53fd6f563221d53c6bc1328848a3", size = 8104 },
2857
+ ]
2858
+
2859
  [[package]]
2860
  name = "pygments"
2861
  version = "2.19.1"
 
2865
  { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293 },
2866
  ]
2867
 
2868
+ [[package]]
2869
+ name = "pymupdf"
2870
+ version = "1.26.0"
2871
+ source = { registry = "https://pypi.org/simple" }
2872
+ sdist = { url = "https://files.pythonhosted.org/packages/99/13/d9f3b67b98111e79307e2a3cf6d5f73daaca002144cc6d236c4a0adbc386/pymupdf-1.26.0.tar.gz", hash = "sha256:ffe023f820379c84a0ddae38b0d07ea4016e1de84929491c34415520c629bcce", size = 74590906 }
2873
+ wheels = [
2874
+ { url = "https://files.pythonhosted.org/packages/b0/c8/e43b872d807ade267699b383d04927e4a1cca05268a43aa9ae0382b6f66a/pymupdf-1.26.0-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:86195673a5f2b3fbf0f75c73c40975a893fc42bf3d5c2a7cce9fb160704d9997", size = 23240576 },
2875
+ { url = "https://files.pythonhosted.org/packages/ed/bb/2c39c2016b5be35372c5df08b44fa9a4778ccf03f9532b59e9d22f05921c/pymupdf-1.26.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:26c5df128a0ed7c38b80a1e7ddd792dd4d8b264839b6b8b6b6b768b13c0bb60e", size = 22409814 },
2876
+ { url = "https://files.pythonhosted.org/packages/90/e1/847d93fecbc975978cb2c6c38dbfbd09dde48c1bc97f9298f2b719880230/pymupdf-1.26.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:84a4dc96144a6bdf13f7d78c21500b3d1bef14d658156afd479acb3995f650c3", size = 23447163 },
2877
+ { url = "https://files.pythonhosted.org/packages/bb/86/959057f3cbbff4a7a00a8214f9f1787f6f708bd3c63091b47a95f1ae4053/pymupdf-1.26.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a3f6a45fcf8177763a2629a2ab2cad326e8950a0d120b174b56369365355a2a7", size = 24052460 },
2878
+ { url = "https://files.pythonhosted.org/packages/e1/80/9cca07bf9c5dfa273781d3559266dcce2001ed111f068b80cad950584c01/pymupdf-1.26.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b5d4751696ba888ab1a91c6a0208c5d31724ee0bebe406f7a83067a08214f88b", size = 25300434 },
2879
+ { url = "https://files.pythonhosted.org/packages/59/c7/2e3e3d9419415e3c479fd9cb23067d33cc17db89e64c9167551a4acb66f2/pymupdf-1.26.0-cp39-abi3-win32.whl", hash = "sha256:eeb04a439355e2077f7675b8ad9377263d81990fc507748f2254a87d771d682b", size = 16925774 },
2880
+ { url = "https://files.pythonhosted.org/packages/e9/d7/a6ce6629b66921529543c899830104f40dde45d98534d945970ea61ca8c9/pymupdf-1.26.0-cp39-abi3-win_amd64.whl", hash = "sha256:e39cc74ff030d773c4e76b9e5c5919cc4683895b73bd63bfd7a349a53ab5e8d7", size = 18525321 },
2881
+ ]
2882
+
2883
  [[package]]
2884
  name = "pyparsing"
2885
  version = "3.2.3"
 
2898
  { url = "https://files.pythonhosted.org/packages/8e/5e/c86a5643653825d3c913719e788e41386bee415c2b87b4f955432f2de6b2/pypdf2-3.0.1-py3-none-any.whl", hash = "sha256:d16e4205cfee272fbdc0568b68d82be796540b1537508cef59388f839c191928", size = 232572 },
2899
  ]
2900
 
2901
+ [[package]]
2902
+ name = "pyphen"
2903
+ version = "0.17.2"
2904
+ source = { registry = "https://pypi.org/simple" }
2905
+ sdist = { url = "https://files.pythonhosted.org/packages/69/56/e4d7e1bd70d997713649c5ce530b2d15a5fc2245a74ca820fc2d51d89d4d/pyphen-0.17.2.tar.gz", hash = "sha256:f60647a9c9b30ec6c59910097af82bc5dd2d36576b918e44148d8b07ef3b4aa3", size = 2079470 }
2906
+ wheels = [
2907
+ { url = "https://files.pythonhosted.org/packages/7b/1f/c2142d2edf833a90728e5cdeb10bdbdc094dde8dbac078cee0cf33f5e11b/pyphen-0.17.2-py3-none-any.whl", hash = "sha256:3a07fb017cb2341e1d9ff31b8634efb1ae4dc4b130468c7c39dd3d32e7c3affd", size = 2079358 },
2908
+ ]
2909
+
2910
  [[package]]
2911
  name = "pyrsm"
2912
  version = "1.6.0"
 
3550
  { url = "https://files.pythonhosted.org/packages/de/a8/8f499c179ec900783ffe133e9aab10044481679bb9aad78436d239eee716/tiktoken-0.9.0-cp313-cp313-win_amd64.whl", hash = "sha256:5ea0edb6f83dc56d794723286215918c1cde03712cbbafa0348b33448faf5b95", size = 894669 },
3551
  ]
3552
 
3553
+ [[package]]
3554
+ name = "tinycss2"
3555
+ version = "1.4.0"
3556
+ source = { registry = "https://pypi.org/simple" }
3557
+ dependencies = [
3558
+ { name = "webencodings" },
3559
+ ]
3560
+ sdist = { url = "https://files.pythonhosted.org/packages/7a/fd/7a5ee21fd08ff70d3d33a5781c255cbe779659bd03278feb98b19ee550f4/tinycss2-1.4.0.tar.gz", hash = "sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7", size = 87085 }
3561
+ wheels = [
3562
+ { url = "https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl", hash = "sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289", size = 26610 },
3563
+ ]
3564
+
3565
+ [[package]]
3566
+ name = "tinyhtml5"
3567
+ version = "2.0.0"
3568
+ source = { registry = "https://pypi.org/simple" }
3569
+ dependencies = [
3570
+ { name = "webencodings" },
3571
+ ]
3572
+ sdist = { url = "https://files.pythonhosted.org/packages/fd/03/6111ed99e9bf7dfa1c30baeef0e0fb7e0bd387bd07f8e5b270776fe1de3f/tinyhtml5-2.0.0.tar.gz", hash = "sha256:086f998833da24c300c414d9fe81d9b368fd04cb9d2596a008421cbc705fcfcc", size = 179507 }
3573
+ wheels = [
3574
+ { url = "https://files.pythonhosted.org/packages/5c/de/27c57899297163a4a84104d5cec0af3b1ac5faf62f44667e506373c6b8ce/tinyhtml5-2.0.0-py3-none-any.whl", hash = "sha256:13683277c5b176d070f82d099d977194b7a1e26815b016114f581a74bbfbf47e", size = 39793 },
3575
+ ]
3576
+
3577
  [[package]]
3578
  name = "tokenizers"
3579
  version = "0.21.1"
 
3818
  { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166 },
3819
  ]
3820
 
3821
+ [[package]]
3822
+ name = "weasyprint"
3823
+ version = "65.1"
3824
+ source = { registry = "https://pypi.org/simple" }
3825
+ dependencies = [
3826
+ { name = "cffi" },
3827
+ { name = "cssselect2" },
3828
+ { name = "fonttools", extra = ["woff"] },
3829
+ { name = "pillow" },
3830
+ { name = "pydyf" },
3831
+ { name = "pyphen" },
3832
+ { name = "tinycss2" },
3833
+ { name = "tinyhtml5" },
3834
+ ]
3835
+ sdist = { url = "https://files.pythonhosted.org/packages/38/76/7f865f0019120be20276813097b5729b8487b93dd4aff339aa77ed8c7ad2/weasyprint-65.1.tar.gz", hash = "sha256:120281bdbd42ffaa7d7e5cedbe3182a2cef36ea5ad97fe9f357e43be6a1e58ea", size = 499028 }
3836
+ wheels = [
3837
+ { url = "https://files.pythonhosted.org/packages/fe/9a/14f4e5fd4bba988d3684602b72f04c0b299c0f368d26c11a79ceab97aa68/weasyprint-65.1-py3-none-any.whl", hash = "sha256:9baa54282dc86929f6b877034d06b0416e2a7cacb1af3f73d80960592fd0af89", size = 298040 },
3838
+ ]
3839
+
3840
+ [[package]]
3841
+ name = "webencodings"
3842
+ version = "0.5.1"
3843
+ source = { registry = "https://pypi.org/simple" }
3844
+ sdist = { url = "https://files.pythonhosted.org/packages/0b/02/ae6ceac1baeda530866a85075641cec12989bd8d31af6d5ab4a3e8c92f47/webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923", size = 9721 }
3845
+ wheels = [
3846
+ { url = "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", size = 11774 },
3847
+ ]
3848
+
3849
  [[package]]
3850
  name = "websockets"
3851
  version = "15.0.1"
 
4022
  { url = "https://files.pythonhosted.org/packages/ad/da/f64669af4cae46f17b90798a827519ce3737d31dbafad65d391e49643dc4/zipp-3.22.0-py3-none-any.whl", hash = "sha256:fe208f65f2aca48b81f9e6fd8cf7b8b32c26375266b009b413d45306b6148343", size = 9796 },
4023
  ]
4024
 
4025
+ [[package]]
4026
+ name = "zopfli"
4027
+ version = "0.2.3.post1"
4028
+ source = { registry = "https://pypi.org/simple" }
4029
+ sdist = { url = "https://files.pythonhosted.org/packages/5e/7c/a8f6696e694709e2abcbccd27d05ef761e9b6efae217e11d977471555b62/zopfli-0.2.3.post1.tar.gz", hash = "sha256:96484dc0f48be1c5d7ae9f38ed1ce41e3675fd506b27c11a6607f14b49101e99", size = 175629 }
4030
+ wheels = [
4031
+ { url = "https://files.pythonhosted.org/packages/3f/ce/b6441cc01881d06e0b5883f32c44e7cc9772e0d04e3e59277f59f80b9a19/zopfli-0.2.3.post1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3f0197b6aa6eb3086ae9e66d6dd86c4d502b6c68b0ec490496348ae8c05ecaef", size = 295489 },
4032
+ { url = "https://files.pythonhosted.org/packages/93/f0/24dd708f00ae0a925bc5c9edae858641c80f6a81a516810dc4d21688a930/zopfli-0.2.3.post1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5fcfc0dc2761e4fcc15ad5d273b4d58c2e8e059d3214a7390d4d3c8e2aee644e", size = 163010 },
4033
+ { url = "https://files.pythonhosted.org/packages/65/57/0378eeeb5e3e1e83b1b0958616b2bf954f102ba5b0755b9747dafbd8cb72/zopfli-0.2.3.post1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cac2b37ab21c2b36a10b685b1893ebd6b0f83ae26004838ac817680881576567", size = 823649 },
4034
+ { url = "https://files.pythonhosted.org/packages/ab/8a/3ab8a616d4655acf5cf63c40ca84e434289d7d95518a1a42d28b4a7228f8/zopfli-0.2.3.post1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d5ab297d660b75c159190ce6d73035502310e40fd35170aed7d1a1aea7ddd65", size = 826557 },
4035
+ { url = "https://files.pythonhosted.org/packages/ed/4d/7f6820af119c4fec6efaf007bffee7bc9052f695853a711a951be7afd26b/zopfli-0.2.3.post1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ba214f4f45bec195ee8559651154d3ac2932470b9d91c5715fc29c013349f8c", size = 851127 },
4036
+ { url = "https://files.pythonhosted.org/packages/e1/db/1ef5353ab06f9f2fb0c25ed0cddf1418fe275cc2ee548bc4a29340c44fe1/zopfli-0.2.3.post1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c1e0ed5d84ffa2d677cc9582fc01e61dab2e7ef8b8996e055f0a76167b1b94df", size = 1754183 },
4037
+ { url = "https://files.pythonhosted.org/packages/39/03/44f8f39950354d330fa798e4bab1ac8e38ec787d3fde25d5b9c7770065a2/zopfli-0.2.3.post1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:bfa1eb759e07d8b7aa7a310a2bc535e127ee70addf90dc8d4b946b593c3e51a8", size = 1905945 },
4038
+ { url = "https://files.pythonhosted.org/packages/74/7b/94b920c33cc64255f59e3cfc77c829b5c6e60805d189baeada728854a342/zopfli-0.2.3.post1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cd2c002f160502608dcc822ed2441a0f4509c52e86fcfd1a09e937278ed1ca14", size = 1835885 },
4039
+ { url = "https://files.pythonhosted.org/packages/ad/89/c869ac844351e285a6165e2da79b715b0619a122e3160d183805adf8ab45/zopfli-0.2.3.post1-cp312-cp312-win32.whl", hash = "sha256:7be5cc6732eb7b4df17305d8a7b293223f934a31783a874a01164703bc1be6cd", size = 82743 },
4040
+ { url = "https://files.pythonhosted.org/packages/29/e6/c98912fd3a589d8a7316c408fd91519f72c237805c4400b753e3942fda0b/zopfli-0.2.3.post1-cp312-cp312-win_amd64.whl", hash = "sha256:4e50ffac74842c1c1018b9b73875a0d0a877c066ab06bf7cccbaa84af97e754f", size = 99403 },
4041
+ { url = "https://files.pythonhosted.org/packages/2b/24/0e552e2efce9a20625b56e9609d1e33c2966be33fc008681121ec267daec/zopfli-0.2.3.post1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ecb7572df5372abce8073df078207d9d1749f20b8b136089916a4a0868d56051", size = 295485 },
4042
+ { url = "https://files.pythonhosted.org/packages/08/83/b2564369fb98797a617fe2796097b1d719a4937234375757ad2a3febc04b/zopfli-0.2.3.post1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a1cf720896d2ce998bc8e051d4b4ce0d8bec007aab6243102e8e1d22a0b2fb3f", size = 163000 },
4043
+ { url = "https://files.pythonhosted.org/packages/3c/55/81d419739c2aab35e19b58bce5498dcb58e6446e5eb69f2d3c748b1c9151/zopfli-0.2.3.post1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5aad740b4d4fcbaaae4887823925166ffd062db3b248b3f432198fc287381d1a", size = 823699 },
4044
+ { url = "https://files.pythonhosted.org/packages/9e/91/89f07c8ea3c9bc64099b3461627b07a8384302235ee0f357eaa86f98f509/zopfli-0.2.3.post1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6617fb10f9e4393b331941861d73afb119cd847e88e4974bdbe8068ceef3f73f", size = 826612 },
4045
+ { url = "https://files.pythonhosted.org/packages/41/31/46670fc0c7805d42bc89702440fa9b73491d68abbc39e28d687180755178/zopfli-0.2.3.post1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a53b18797cdef27e019db595d66c4b077325afe2fd62145953275f53d84ce40c", size = 851148 },
4046
+ { url = "https://files.pythonhosted.org/packages/22/00/71ad39277bbb88f9fd20fb786bd3ff2ea4025c53b31652a0da796fb546cd/zopfli-0.2.3.post1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b78008a69300d929ca2efeffec951b64a312e9a811e265ea4a907ab546d79fa6", size = 1754215 },
4047
+ { url = "https://files.pythonhosted.org/packages/d0/4e/e542c508d20c3dfbef1b90fcf726f824f505e725747f777b0b7b7d1deb95/zopfli-0.2.3.post1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:0aa5f90d6298bda02a95bc8dc8c3c19004d5a4e44bda00b67ca7431d857b4b54", size = 1905988 },
4048
+ { url = "https://files.pythonhosted.org/packages/ba/a5/817ac1ecc888723e91dc172e8c6eeab9f48a1e52285803b965084e11bbd5/zopfli-0.2.3.post1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2768c877f76c8a0e7519b1c86c93757f3c01492ddde55751e9988afb7eff64e1", size = 1835907 },
4049
+ { url = "https://files.pythonhosted.org/packages/cd/35/2525f90c972d8aafc39784a8c00244eeee8e8221b26cbc576748ee9dc1cd/zopfli-0.2.3.post1-cp313-cp313-win32.whl", hash = "sha256:71390dbd3fbf6ebea9a5d85ffed8c26ee1453ee09248e9b88486e30e0397b775", size = 82742 },
4050
+ { url = "https://files.pythonhosted.org/packages/2f/c6/49b27570923956d52d37363e8f5df3a31a61bd7719bb8718527a9df3ae5f/zopfli-0.2.3.post1-cp313-cp313-win_amd64.whl", hash = "sha256:a86eb88e06bd87e1fff31dac878965c26b0c26db59ddcf78bb0379a954b120de", size = 99408 },
4051
+ ]
4052
+
4053
  [[package]]
4054
  name = "zstandard"
4055
  version = "0.23.0"