diff --git a/pyproject.toml b/pyproject.toml index 6af4f57..4dd013c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,6 +5,7 @@ description = "SSL (Software and Systems Laboratory) website " readme = "README.md" requires-python = ">=3.14" dependencies = [ + "ablog>=0.11.13", "sphinx>=8.2.3", "sphinx-autobuild>=2025.8.25", "sphinx-book-theme>=1.1.4", diff --git a/src/conf.py b/src/conf.py index ab29bcc..37586e8 100644 --- a/src/conf.py +++ b/src/conf.py @@ -16,6 +16,7 @@ # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration extensions = [ + "ablog", "sphinx.ext.autosectionlabel", "sphinx.ext.intersphinx", "sphinx.ext.todo", diff --git a/src/index.rst b/src/index.rst index 138caf1..58781f2 100644 --- a/src/index.rst +++ b/src/index.rst @@ -366,6 +366,6 @@ consult Loyola University Chicago's `official admissions resources `_ - for our latest publications. diff --git a/src/publications/agentic-tutor-hpc-sc25-eduhpc2025.rst b/src/publications/agentic-tutor-hpc-sc25-eduhpc2025.rst new file mode 100644 index 0000000..5b1b9b4 --- /dev/null +++ b/src/publications/agentic-tutor-hpc-sc25-eduhpc2025.rst @@ -0,0 +1,120 @@ +:blogpost: true +:date: November 29, 2025 +:category: Blog Post +:tags: Artificial Intelligence, 11-29-2025 +:nocomments: + +====================================================================== +Advancing HPC Education with an Agentic Tutoring System (EduHPC 2025) +====================================================================== + +This post highlights a recent **EduHPC 2025** paper `doi:10.1145/3731599.3767386 `__ led by my PhD student **Erik Pautsch** and co-supervised by me and **Silvio Rizzi** at Argonne National Laboratory. + +In this work, we introduce an **agentic tutoring system** that supports instructors in planning, teaching, and assessing high-performance computing (HPC) content. +Our goal is to make HPC instruction more accessible, scalable, and sustainable as it is presently lacking in all three dimensions. +We think AI can help. + +Abstract / Summary +------------------ + +This summer we explored how an agentic tutoring system could lower barriers to HPC and parallel/distributed computing (PDC) education. +Our EduHPC 2025 paper presents a system that assists instructors with: + +- lesson planning +- generation of teaching materials +- adaptive explanations based on learner background +- structured assessment and feedback + +Our initial deployment at Argonne demonstrates that we can prepare lessons more efficiently, improve accessibility of HPC concepts, and streamline evaluation. +We believe this represents a meaningful step toward **democratizing HPC education**. + +Background: Why HPC Needs Better Teaching Tools +----------------------------------------------- + +HPC and PDC skills are increasingly essential across scientific computing, engineering, modeling and simulation, and data-intensive research. + +Yet teaching HPC remains challenging for many reasons: + +- Many institutions lack faculty with substantial HPC experience. +- Preparing examples for MPI, OpenMP, GPUs, profiling, and performance studies is labor-intensive. +- Existing curricula are fragmented and often tied to individual experts. +- Adoption of HPC coursework is still uneven, especially at teaching-focused institutions. + +Our work asks whether **intelligent tutoring systems can meaningfully support instructors** -- reducing preparation time, lowering expertise requirements, and expanding access. + +Key Contributions +----------------- + +Our paper makes several core contributions: + +1. **We created an agentic HPC tutoring system** that helps with lesson planning, content generation, instructional guidance, and assessment. +2. **We designed the system explicitly for instructors of varying experience levels**, not only HPC specialists. +3. **We implemented adaptive content generation**, allowing material to adjust for novice or advanced learners. +4. **We integrated assessment capabilities** that support consistent evaluation of student work. +5. **We conducted an evaluation at Argonne**, demonstrating feasibility under realistic instructional conditions. + +Initial Results +--------------- + +Our early results show: + +- Lesson plans and teaching units could be generated significantly faster than preparing materials manually. +- The generated instructional materials—slides, examples, exercises—were high enough quality for direct classroom use. +- Adaptivity helped us reach learners with different backgrounds effectively. +- The system performed well in a realistic (but small) instructional environment. + +These findings suggest that intelligent systems can **augment instructors**, helping expand HPC education capacity. + +Key Take-Aways +-------------- + +- Agentic systems can broaden access to HPC education across many types of institutions. +- Automating planning and assessment reduces barriers to offering HPC courses. +- Adaptivity improves inclusion by addressing diverse learner backgrounds. +- The Argonne deployment on leadership-class systems (e.g. Polaris) demonstrated real-world practicality. + +Future Work +----------- + +We plan to extend this work by: + +- Deploying the system across additional academic settings +- Conducting longitudinal studies over full terms +- Expanding HPC topic coverage (MPI, OpenMP, GPUs, profiling, debugging, energy-aware computing) +- Adding automated grading and adaptive exercises +- Integrating with learning management systems +- Supporting community-driven lesson templates and shared teaching modules + +Access +---------------------- + +.. note:: You should be able to downlaod this paper with or without an ACM Digital Library subscription. + Please contact me if you cannot do so. + +- `DOI 10.1145/3731599.3767386 `__ +- `PDF `__ + +Citation +---------------------- + +Erik Pautsch, Mengjiao Han, Joseph A. Insley, Janet Knowles, Victor A. Mateevitsi, Silvio Rizzi, and George K. Thiruvathukal. 2025. *An Interactive Agentic HPC Tutor for Lesson Planning, Teaching, and Assessment*. In Proceedings of the SC '25 Workshops of the International Conference for High Performance Computing, Networking, Storage and Analysis (SC Workshops '25). Association for Computing Machinery, New York, NY, USA, 367–375. https://doi.org/10.1145/3731599.3767386 + +.. code-block:: bibtex + + @inproceedings{10.1145/3731599.3767386, + author = {Pautsch, Erik and Han, Mengjiao and Insley, Joseph A. and Knowles, Janet and Mateevitsi, Victor A. and Rizzi, Silvio and Thiruvathukal, George K.}, + title = {An Interactive Agentic HPC Tutor for Lesson Planning, Teaching, and Assessment}, + year = {2025}, + isbn = {9798400718717}, + publisher = {Association for Computing Machinery}, + address = {New York, NY, USA}, + url = {https://doi.org/10.1145/3731599.3767386}, + doi = {10.1145/3731599.3767386}, + abstract = {High-performance computing (HPC) education is at an inflection point, driven by agentic systems and “prompt-engineering” as a form of programming. We describe an interactive tutor built from autonomous LLM-based agents, each with a narrow role: planning lessons, explaining concepts, scaffolding code, and executing runs. Using open-source toolkits and locally hosted models on leadership-class supercomputers, the tutor lets educators generate and refine parallel-programming examples in real time without external APIs or subscription fees. Complex workflows are composed through structured prompts rather than traditional source code, while per-agent history summarization prevents context-window overflow and enables self-correcting code generation. Requiring no proprietary services, the platform is immediately deployable in institutional HPC environments and scales from single-user sessions to classroom labs. Beyond a teaching aid, it illustrates how prompt-driven, multi-agent software can deliver dynamic, personalized, and extensible learning experiences across technical domains.}, + booktitle = {Proceedings of the SC '25 Workshops of the International Conference for High Performance Computing, Networking, Storage and Analysis}, + pages = {367–375}, + numpages = {9}, + keywords = {high-performance computing, multi-agent systems, large language models, education, CUDA, SYCL}, + location = {St. Louis, MO, USA}, + series = {SC Workshops '25} + } diff --git a/src/publications/ai-in-hiring-fairness-or-just-automated-bias.rst b/src/publications/ai-in-hiring-fairness-or-just-automated-bias.rst new file mode 100644 index 0000000..e3bf722 --- /dev/null +++ b/src/publications/ai-in-hiring-fairness-or-just-automated-bias.rst @@ -0,0 +1,64 @@ +:blogpost: true +:date: November 18, 2024 +:category: Blog Post +:tags: Artificial Intelligence, 11-18-2024 +:nocomments: + +AI in Hiring: Fairness or Just Automated Bias? +============================================== + +Artificial intelligence has become increasingly embedded in modern hiring systems. +From résumé screening to candidate scoring, automated tools promise efficiency, objectivity, and scale. +Yet these promises often obscure important risks: when AI models inherit biased historical data, they can reinforce or even amplify inequities in hiring. + +Many hiring datasets reflect systemic social, cultural, and economic disparities. +If an organization’s historical hiring patterns favored one demographic group—intentionally or not—an AI system trained on that data is likely to replicate those preferences. +Under the guise of neutrality, the model may recommend “more of the same,” reducing diversity and overlooking equally qualified candidates. + +This raises a crucial question: +**Are AI hiring tools fair, or are they simply automating existing forms of bias?** + +Important concerns +------------------ + +* **Historical bias baked into training data** + AI systems inherit the limitations and inequities of the datasets used to train them. + +* **Opacity and lack of accountability** + Candidates often cannot understand, challenge, or appeal algorithmic decisions. + +* **Risk of reinforcing homogeneity** + Automated systems may unintentionally filter out qualified applicants whose backgrounds differ from past hires. + +* **Regulatory and legal implications** + As governments introduce stricter rules for automated hiring systems, organizations must ensure transparent and fair processes. + +Moving forward responsibly +--------------------------- + +To ensure responsible AI use in hiring, organizations must: + +* audit models regularly for disparate impact, +* adopt transparent scoring criteria, +* maintain meaningful human oversight, and +* prioritize fairness and inclusivity in both design and deployment. + +AI can assist in hiring, but it must never replace critical human judgment—especially when people’s careers and livelihoods are at stake. + +Citation +-------- + +Theresa Fister and George K. Thiruvathukal, "Artificial Intelligence Employment Interviews: Examining Limitations, Biases, and Perceptions," in Computer, volume 57, number 10, pages 76-81, October 2024, https://doi.org/10.1109/MC.2024.3404669. + +.. code-block:: bibtex + + @article{10687332, + author={Fister, Theresa and Thiruvathukal, George K.}, + journal={Computer}, + title={Artificial Intelligence Employment Interviews: Examining Limitations, Biases, and Perceptions}, + year={2024}, + volume={57}, + number={10}, + pages={76-81}, + keywords={Artificial intelligence;Employment;Training;Quality assessment;Software quality;Business}, + doi={10.1109/MC.2024.3404669}} diff --git a/src/publications/index.rst b/src/publications/index.rst new file mode 100644 index 0000000..62c8408 --- /dev/null +++ b/src/publications/index.rst @@ -0,0 +1,9 @@ +################ + Blog Posts +################ + +.. postlist:: + :date: %A, %B %d, %Y + :format: {title} + :excerpts: + :expand: Read more ... diff --git a/src/publications/model-naming-emse-2025.rst b/src/publications/model-naming-emse-2025.rst new file mode 100644 index 0000000..ad957e4 --- /dev/null +++ b/src/publications/model-naming-emse-2025.rst @@ -0,0 +1,84 @@ +:blogpost: true +:date: December 27, 2025 +:category: Blog Post +:tags: Software Engineering, 12-27-2025 +:nocomments: + +PTM Naming: Why “What’s in a Name” Actually Matters for AI Reuse +================================================================== + +I’m thrilled to share some recent work led by **Wenxin Jiang**, a PhD +student at Purdue University. Wenxin is supervised by **James C. +Davis**, and I have had the pleasure of serving as a key external +supervisor and PhD committee member on this project as part of my +ongoing collaboration with Dr. Davis. +This research was recently accepted for publication in `Journal of Empirical Software Engineering `__ and it tackles a problem that anyone working in +AI has likely grumbled about: how we name our models. + +If you’ve spent any time on registries like **Hugging Face**, you know +the drill: you need a model for a specific task, you search for +something like “BERT,” and you’re suddenly staring at a wall of names +like ``bert-base-uncased``. In traditional software, we’re used to +short, catchy names like ``requests`` or ``chalk``. But in the world of +deep learning, the name is often the only “spec sheet” a developer has +to infer critical details about architecture, size, and datasets. + +The Wild West of Model Names +----------------------------- + +Wenxin’s study—which included a survey of 108 Hugging Face users and a mining study of over 14,000 model packages—confirms that Pre-Trained Model (PTM) naming is a completely different from traditional software conventions. +While a traditional package name tells you “what it does,” a PTM name tries to pack in “how it works,” “how big it is,” and “what it was trained on” all at once. + +The problem is that we are currently in a bit of a “Wild West” environment when it comes to PTM naming. +Our research found a massive mismatch between what engineers *want* in a name and what they actually *get*. +For instance, most developers prefer names that reflect both the implementation and the intended task, but in practice, names tend to stick almost exclusively to technical architectural units. +Even worse, these names are often inconsistent; we’ve seen cases where a model’s identifier doesn’t match its internal metadata, leading to significant debugging effort for users. + +DARA: An Automated Consistency Detector +----------------------------------------- + +To help clean up this ecosystem, our team developed **DARA (DNN ARchitecture Assessment)**. +The idea is simple but powerful: can we look at the actual “guts” of a model—its layers and connections—and predict what its name *should* be?. + +It turns out, we can. By treating the model’s computational graph as an “abstract architecture” (APTM), DARA can detect inconsistencies with surprising accuracy. +Our results show that architectural information alone is sufficient to achieve an accuracy of **99%** in identifying the correct ``model_type``. + +This isn’t just an academic exercise. +We envision tools like DARA being used as “linters” during the model upload process. +Imagine uploading a model to a registry and getting an instant alert: “Hey, you named this model ‘nllb,’ but its architecture metadata says ‘m2m.’ +Want to double-check that?”. + +Why This Matters for the Supply Chain +----------------------------------------- + +Beyond just making it easier to find the right model, this is a security issue. +As PTMs become core components of our software supply chain, wee have to worry about things like **typosquatting** and **architectural backdoors**. +If an attacker can hide a malicious model under a familiar-looking name, and we don’t have automated ways to verify that the name matches the content, the entire ecosystem is at risk. + +Wenxin’s work provides the first empirical foundation for standardizing how we talk about and name these models. +It’s a major step toward making AI reuse as reliable and transparent as traditional software engineering. + +If you’re interested in the technical nitty-gritty or want to try out +the DARA tool yourself, the paper and the code are available at +`GitHub PurdueDualityLab/PTM-Naming `__. + +Citation +~~~~~~~~ + +Jiang, Wenxin, Mingyu Kim, Chingwo Cheung, Heesoo Kim, George K. Thiruvathukal, and James C. Davis. *"I See Models Being a Whole Other Thing": An Empirical Study of Pre-trained Model Naming Conventions and a Tool for Enhancing Naming Consistency*. Empirical Software Engineering, vol. 30, no. 6, 2025, p. 155. Springer Link, https://doi.org/10.1007/s10664-025-10711-4. + +.. code-block:: bibtex + + @article{Jiang2025, + author = {Jiang, Wenxin and Kim, Mingyu and Cheung, Chingwo and Kim, Heesoo and Thiruvathukal, George K. and Davis, James C.}, + title = {``I see models being a whole other thing'': An empirical study of pre-trained model naming conventions and a tool for enhancing naming consistency}, + journal = {Empirical Software Engineering}, + year = {2025}, + volume = {30}, + number = {6}, + pages = {155}, + month = {aug}, + doi = {10.1007/s10664-025-10711-4}, + url = {https://doi.org/10.1007/s10664-025-10711-4}, + issn = {1573-7616} + } diff --git a/src/publications/signal-injection-zipa.rst b/src/publications/signal-injection-zipa.rst new file mode 100644 index 0000000..f579c8f --- /dev/null +++ b/src/publications/signal-injection-zipa.rst @@ -0,0 +1,92 @@ +:blogpost: true +:date: December 28, 2024 +:category: Blog Post +:tags: Software Engineering, 12-28-2024 +:nocomments: + +A Signal Injection Attack Against Zero Involvement Pairing and Authentication for the Internet of Things +========================================================================================================= + +Overview +-------- + +Zero Involvement Pairing and Authentication (ZIPA) is a technique for automatically provisioning large networks of Internet-of-Things (IoT) devices with no user involvement. +Prior ZIPA work generally assumes that the environment used for pairing is sufficiently isolated from external, adversarial signals. +In our DESTION 2024 paper :cite:p:`ahlgren_not-so-secret_2025`, we present the first *signal-injection attack* capable of influencing ZIPA-based key generation, demonstrating that these assumptions can fail in realistic settings. + +Abstract Summary +---------------- + +We show that an adversary can broadcast audio at approximately 95 dBA and cause the popular Schürmann & Sigg ZIPA algorithm to generate keys that statistically match those produced by legitimate devices. +Under these conditions, adversary-generated keys become indistinguishable from the legitimate keys within standard error, effectively breaking the security guarantees of the scheme. +This result challenges the core premise that ambient environmental signals used for ZIPA cannot be meaningfully controlled by an attacker. + +Key Contributions +----------------- + +* A practical, experimentally validated signal-injection attack against a representative ZIPA system. +* Empirical evidence that adversarially generated keys fall within the standard error of legitimate keys. +* A re-examination of the assumptions underlying ZIPA, especially regarding ambient channel isolation and leakage. +* Design guidance and discussion of mitigation strategies for secure IoT auto-provisioning in adversarial environments. + +Background +---------- + +ZIPA (Zero Involvement Pairing and Authentication) schemes seek to make IoT deployment scalable by minimizing or eliminating user input during pairing. +The Schürmann & Sigg algorithm is a canonical example, using correlated ambient audio to derive shared cryptographic keys between nearby devices. +Earlier work assumes that adversaries cannot significantly alter or inject signals into the ambient environment, an assumption our work directly challenges. + +Threat Model and Attack Description +----------------------------------- + +In our threat model, the attacker is able to place or control a signal source in an adjacent or partially connected space near the target environment. +By injecting a controlled, high-volume audio signal (around 95 dBA), the attacker biases the ambient signal measurements that ZIPA devices rely on. +As a result, the attacker’s device generates a key that closely matches the key produced by the legitimate device, within statistical error bounds. + +Experimental Setup & Results +---------------------------- + +Our evaluation includes: + +* A controlled experimental setup with prototype ZIPA devices using the Schürmann & Sigg algorithm. +* Measurements of ambient correlation under normal conditions versus adversarial signal injection. +* Key-agreement statistics comparing the keys produced by legitimate devices and the attacker. + +The data show that, under signal injection, adversary-generated keys are highly correlated with legitimate keys and fall within the standard error of the intended ZIPA pairing. +This demonstrates a clear and practical break of the security model for ambient-signal-based pairing. + +Mitigation Discussion +--------------------- + +Our results suggest several directions for improving ZIPA-style schemes: + +* **Signal-level monitoring:** Detecting abnormal ambient signal power or patterns that could indicate injection. +* **Environmental sanity checks:** Rejecting key generation when environmental measurements fall outside expected thresholds. +* **Active elements:** Adding challenge-response mechanisms or additional authenticated steps instead of relying solely on passive ambient correlation. +* **Stronger threat models:** Designing ZIPA systems under the assumption that adversaries can inject or manipulate ambient signals, especially in shared or semi-public spaces. + +Conclusion +---------- + +This work presents the first demonstrated signal-injection attack on ZIPA-based IoT provisioning. +We show that relying purely on ambient signals for secure pairing is not sufficient in adversarial environments, even at moderate sound levels such as 95 dBA. +Designers of large-scale IoT auto-provisioning systems should adopt more robust threat models, incorporate active defenses, and treat ZIPA schemes with caution when security is a primary concern. + +Citaiton +-------------- + +Isaac Ahlgren, Rushikeshh Shirsat, Omar Achkar, George K. Thiruvathukal, Kyu In Lee and Neil Klingensmith, *Not-so-Secret Authentication: The SyncBleed Attacks and Defenses for Zero-Involvement Authentication Systems*, 2025 IEEE International Conference on Cyber Security and Resilience (CSR), Chania, Crete, Greece, 2025, pp. 592-599, https://doi.org/10.1109/CSR64739.2025.11130070. + +.. code-block:: bibtex + + @INPROCEEDINGS{11130070, + author={Ahlgren, Isaac and Shirsat, Rushikesh and Achkar, Omar and Thiruvathukal, George K and Lee, Kyu In and Klingensmith, Neil}, + booktitle={2025 IEEE International Conference on Cyber Security and Resilience (CSR)}, + title={Not-so-Secret Authentication: The SyncBleed Attacks and Defenses for Zero-Involvement Authentication Systems}, + year={2025}, + volume={}, + number={}, + pages={592-599}, + keywords={Resistance;Wireless communication;Privacy;Authentication;Vectors;Synchronization;Security;Standards;Resilience;Principal component analysis}, + doi={10.1109/CSR64739.2025.11130070}} + diff --git a/src/publications/tla-for-all-running-model-checking-in-a-python-notebook.rst b/src/publications/tla-for-all-running-model-checking-in-a-python-notebook.rst new file mode 100644 index 0000000..7af98f2 --- /dev/null +++ b/src/publications/tla-for-all-running-model-checking-in-a-python-notebook.rst @@ -0,0 +1,41 @@ +:blogpost: true +:date: February 5, 2025 +:category: Blog Post +:tags: Software Engineering, 02-05-2025 +:nocomments: + +TLA+ for All: Running Model Checking in a Python Notebook +========================================================= + +TLA+ has long been a powerful tool for designing and verifying complex systems. +However, many students and practitioners have felt excluded by the ecosystem’s complexity, the need to install multiple tools, or the misconception that formal methods are only for specialists. +This project aims to change that. + +By integrating TLA+ model checking directly into a Python notebook environment, we make formal specification and verification accessible to anyone who can open a browser. +Instead of requiring specialized tooling, users can write specifications, run the TLC model checker, explore traces, and visualize behaviors—all within a familiar computational notebook workflow. + +Why notebooks? +-------------- + +Computational notebooks are already widely used for data science, simulation, and teaching. +Embedding TLA+ into this environment enables: + +* barrier-free access to model checking, +* the ability to annotate specifications with narrative explanation, +* integration with example data, visualizations, and experiments, +* reproducibility for classroom and research settings. + +This approach supports learners encountering formal methods for the first time, researchers building executable documentation, and engineers who want to explore system behaviors without wrestling with installation steps. + +Key benefits +------------ + +* Makes TLA+ accessible through a fully browser-based workflow. +* Encourages literate modeling—combining specification, explanation, and results. +* Avoids challenging setup or complex toolchains. +* Ideal for teaching, tutorials, workshops, and exploratory modeling. + +Citation +-------- + +Konstantin Läufer and George K. Thiruvathukal, *TLA for All: Model Checking in a Python Notebook*, http://dx.doi.org/10.6084/m9.figshare.28376276.v1 diff --git a/uv.lock b/uv.lock index 473465d..e2b64fb 100644 --- a/uv.lock +++ b/uv.lock @@ -2,6 +2,24 @@ version = 1 revision = 3 requires-python = ">=3.14" +[[package]] +name = "ablog" +version = "0.11.13" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils" }, + { name = "feedgen" }, + { name = "invoke" }, + { name = "packaging" }, + { name = "python-dateutil" }, + { name = "sphinx" }, + { name = "watchdog" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ba/8c/bbe097fca7222bbb345e3102d99f773cad77a7871b65f3c476c9fef93e2d/ablog-0.11.13.tar.gz", hash = "sha256:ae990d2c5c495ced6a33e0ec47d34355b828b81b97b6ad3786f682252d1ad36a", size = 103676, upload-time = "2026-01-26T14:02:44.721Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ba/79/3c6119252db5158a8eb208d1d3ae4c87a57dccbcd42fa3dfdfd8c3b0a3cc/ablog-0.11.13-py3-none-any.whl", hash = "sha256:73eb092c2302e441262e202b0e59d7ee78e43e91ab1d8e4aacc4de2f1166d845", size = 64785, upload-time = "2026-01-26T14:02:43.521Z" }, +] + [[package]] name = "accessible-pygments" version = "0.0.5" @@ -121,6 +139,16 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", size = 587408, upload-time = "2024-04-23T18:57:14.835Z" }, ] +[[package]] +name = "feedgen" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "lxml" }, + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6b/59/be0a6f852b5dfbf19e6c8e962c8f41407697f9f52a7902250ed98683ae89/feedgen-1.0.0.tar.gz", hash = "sha256:d9bd51c3b5e956a2a52998c3708c4d2c729f2fcc311188e1e5d3b9726393546a", size = 258496, upload-time = "2023-12-25T18:04:08.421Z" } + [[package]] name = "h11" version = "0.16.0" @@ -148,6 +176,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b", size = 8769, upload-time = "2022-07-01T12:21:02.467Z" }, ] +[[package]] +name = "invoke" +version = "2.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/de/bd/b461d3424a24c80490313fd77feeb666ca4f6a28c7e72713e3d9095719b4/invoke-2.2.1.tar.gz", hash = "sha256:515bf49b4a48932b79b024590348da22f39c4942dff991ad1fb8b8baea1be707", size = 304762, upload-time = "2025-10-11T00:36:35.172Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/4b/b99e37f88336009971405cbb7630610322ed6fbfa31e1d7ab3fbf3049a2d/invoke-2.2.1-py3-none-any.whl", hash = "sha256:2413bc441b376e5cd3f55bb5d364f973ad8bdd7bf87e53c79de3c11bf3feecc8", size = 160287, upload-time = "2025-10-11T00:36:33.703Z" }, +] + [[package]] name = "jinja2" version = "3.1.6" @@ -160,6 +197,50 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, ] +[[package]] +name = "lxml" +version = "6.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/88/262177de60548e5a2bfc46ad28232c9e9cbde697bd94132aeb80364675cb/lxml-6.0.2.tar.gz", hash = "sha256:cd79f3367bd74b317dda655dc8fcfa304d9eb6e4fb06b7168c5cf27f96e0cd62", size = 4073426, upload-time = "2025-09-22T04:04:59.287Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/03/15/d4a377b385ab693ce97b472fe0c77c2b16ec79590e688b3ccc71fba19884/lxml-6.0.2-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:b0c732aa23de8f8aec23f4b580d1e52905ef468afb4abeafd3fec77042abb6fe", size = 8659801, upload-time = "2025-09-22T04:02:30.113Z" }, + { url = "https://files.pythonhosted.org/packages/c8/e8/c128e37589463668794d503afaeb003987373c5f94d667124ffd8078bbd9/lxml-6.0.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4468e3b83e10e0317a89a33d28f7aeba1caa4d1a6fd457d115dd4ffe90c5931d", size = 4659403, upload-time = "2025-09-22T04:02:32.119Z" }, + { url = "https://files.pythonhosted.org/packages/00/ce/74903904339decdf7da7847bb5741fc98a5451b42fc419a86c0c13d26fe2/lxml-6.0.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:abd44571493973bad4598a3be7e1d807ed45aa2adaf7ab92ab7c62609569b17d", size = 4966974, upload-time = "2025-09-22T04:02:34.155Z" }, + { url = "https://files.pythonhosted.org/packages/1f/d3/131dec79ce61c5567fecf82515bd9bc36395df42501b50f7f7f3bd065df0/lxml-6.0.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:370cd78d5855cfbffd57c422851f7d3864e6ae72d0da615fca4dad8c45d375a5", size = 5102953, upload-time = "2025-09-22T04:02:36.054Z" }, + { url = "https://files.pythonhosted.org/packages/3a/ea/a43ba9bb750d4ffdd885f2cd333572f5bb900cd2408b67fdda07e85978a0/lxml-6.0.2-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:901e3b4219fa04ef766885fb40fa516a71662a4c61b80c94d25336b4934b71c0", size = 5055054, upload-time = "2025-09-22T04:02:38.154Z" }, + { url = "https://files.pythonhosted.org/packages/60/23/6885b451636ae286c34628f70a7ed1fcc759f8d9ad382d132e1c8d3d9bfd/lxml-6.0.2-cp314-cp314-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:a4bf42d2e4cf52c28cc1812d62426b9503cdb0c87a6de81442626aa7d69707ba", size = 5352421, upload-time = "2025-09-22T04:02:40.413Z" }, + { url = "https://files.pythonhosted.org/packages/48/5b/fc2ddfc94ddbe3eebb8e9af6e3fd65e2feba4967f6a4e9683875c394c2d8/lxml-6.0.2-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2c7fdaa4d7c3d886a42534adec7cfac73860b89b4e5298752f60aa5984641a0", size = 5673684, upload-time = "2025-09-22T04:02:42.288Z" }, + { url = "https://files.pythonhosted.org/packages/29/9c/47293c58cc91769130fbf85531280e8cc7868f7fbb6d92f4670071b9cb3e/lxml-6.0.2-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:98a5e1660dc7de2200b00d53fa00bcd3c35a3608c305d45a7bbcaf29fa16e83d", size = 5252463, upload-time = "2025-09-22T04:02:44.165Z" }, + { url = "https://files.pythonhosted.org/packages/9b/da/ba6eceb830c762b48e711ded880d7e3e89fc6c7323e587c36540b6b23c6b/lxml-6.0.2-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:dc051506c30b609238d79eda75ee9cab3e520570ec8219844a72a46020901e37", size = 4698437, upload-time = "2025-09-22T04:02:46.524Z" }, + { url = "https://files.pythonhosted.org/packages/a5/24/7be3f82cb7990b89118d944b619e53c656c97dc89c28cfb143fdb7cd6f4d/lxml-6.0.2-cp314-cp314-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8799481bbdd212470d17513a54d568f44416db01250f49449647b5ab5b5dccb9", size = 5269890, upload-time = "2025-09-22T04:02:48.812Z" }, + { url = "https://files.pythonhosted.org/packages/1b/bd/dcfb9ea1e16c665efd7538fc5d5c34071276ce9220e234217682e7d2c4a5/lxml-6.0.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9261bb77c2dab42f3ecd9103951aeca2c40277701eb7e912c545c1b16e0e4917", size = 5097185, upload-time = "2025-09-22T04:02:50.746Z" }, + { url = "https://files.pythonhosted.org/packages/21/04/a60b0ff9314736316f28316b694bccbbabe100f8483ad83852d77fc7468e/lxml-6.0.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:65ac4a01aba353cfa6d5725b95d7aed6356ddc0a3cd734de00124d285b04b64f", size = 4745895, upload-time = "2025-09-22T04:02:52.968Z" }, + { url = "https://files.pythonhosted.org/packages/d6/bd/7d54bd1846e5a310d9c715921c5faa71cf5c0853372adf78aee70c8d7aa2/lxml-6.0.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:b22a07cbb82fea98f8a2fd814f3d1811ff9ed76d0fc6abc84eb21527596e7cc8", size = 5695246, upload-time = "2025-09-22T04:02:54.798Z" }, + { url = "https://files.pythonhosted.org/packages/fd/32/5643d6ab947bc371da21323acb2a6e603cedbe71cb4c99c8254289ab6f4e/lxml-6.0.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:d759cdd7f3e055d6bc8d9bec3ad905227b2e4c785dc16c372eb5b5e83123f48a", size = 5260797, upload-time = "2025-09-22T04:02:57.058Z" }, + { url = "https://files.pythonhosted.org/packages/33/da/34c1ec4cff1eea7d0b4cd44af8411806ed943141804ac9c5d565302afb78/lxml-6.0.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:945da35a48d193d27c188037a05fec5492937f66fb1958c24fc761fb9d40d43c", size = 5277404, upload-time = "2025-09-22T04:02:58.966Z" }, + { url = "https://files.pythonhosted.org/packages/82/57/4eca3e31e54dc89e2c3507e1cd411074a17565fa5ffc437c4ae0a00d439e/lxml-6.0.2-cp314-cp314-win32.whl", hash = "sha256:be3aaa60da67e6153eb15715cc2e19091af5dc75faef8b8a585aea372507384b", size = 3670072, upload-time = "2025-09-22T04:03:38.05Z" }, + { url = "https://files.pythonhosted.org/packages/e3/e0/c96cf13eccd20c9421ba910304dae0f619724dcf1702864fd59dd386404d/lxml-6.0.2-cp314-cp314-win_amd64.whl", hash = "sha256:fa25afbadead523f7001caf0c2382afd272c315a033a7b06336da2637d92d6ed", size = 4080617, upload-time = "2025-09-22T04:03:39.835Z" }, + { url = "https://files.pythonhosted.org/packages/d5/5d/b3f03e22b3d38d6f188ef044900a9b29b2fe0aebb94625ce9fe244011d34/lxml-6.0.2-cp314-cp314-win_arm64.whl", hash = "sha256:063eccf89df5b24e361b123e257e437f9e9878f425ee9aae3144c77faf6da6d8", size = 3754930, upload-time = "2025-09-22T04:03:41.565Z" }, + { url = "https://files.pythonhosted.org/packages/5e/5c/42c2c4c03554580708fc738d13414801f340c04c3eff90d8d2d227145275/lxml-6.0.2-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:6162a86d86893d63084faaf4ff937b3daea233e3682fb4474db07395794fa80d", size = 8910380, upload-time = "2025-09-22T04:03:01.645Z" }, + { url = "https://files.pythonhosted.org/packages/bf/4f/12df843e3e10d18d468a7557058f8d3733e8b6e12401f30b1ef29360740f/lxml-6.0.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:414aaa94e974e23a3e92e7ca5b97d10c0cf37b6481f50911032c69eeb3991bba", size = 4775632, upload-time = "2025-09-22T04:03:03.814Z" }, + { url = "https://files.pythonhosted.org/packages/e4/0c/9dc31e6c2d0d418483cbcb469d1f5a582a1cd00a1f4081953d44051f3c50/lxml-6.0.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:48461bd21625458dd01e14e2c38dd0aea69addc3c4f960c30d9f59d7f93be601", size = 4975171, upload-time = "2025-09-22T04:03:05.651Z" }, + { url = "https://files.pythonhosted.org/packages/e7/2b/9b870c6ca24c841bdd887504808f0417aa9d8d564114689266f19ddf29c8/lxml-6.0.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:25fcc59afc57d527cfc78a58f40ab4c9b8fd096a9a3f964d2781ffb6eb33f4ed", size = 5110109, upload-time = "2025-09-22T04:03:07.452Z" }, + { url = "https://files.pythonhosted.org/packages/bf/0c/4f5f2a4dd319a178912751564471355d9019e220c20d7db3fb8307ed8582/lxml-6.0.2-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5179c60288204e6ddde3f774a93350177e08876eaf3ab78aa3a3649d43eb7d37", size = 5041061, upload-time = "2025-09-22T04:03:09.297Z" }, + { url = "https://files.pythonhosted.org/packages/12/64/554eed290365267671fe001a20d72d14f468ae4e6acef1e179b039436967/lxml-6.0.2-cp314-cp314t-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:967aab75434de148ec80597b75062d8123cadf2943fb4281f385141e18b21338", size = 5306233, upload-time = "2025-09-22T04:03:11.651Z" }, + { url = "https://files.pythonhosted.org/packages/7a/31/1d748aa275e71802ad9722df32a7a35034246b42c0ecdd8235412c3396ef/lxml-6.0.2-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d100fcc8930d697c6561156c6810ab4a508fb264c8b6779e6e61e2ed5e7558f9", size = 5604739, upload-time = "2025-09-22T04:03:13.592Z" }, + { url = "https://files.pythonhosted.org/packages/8f/41/2c11916bcac09ed561adccacceaedd2bf0e0b25b297ea92aab99fd03d0fa/lxml-6.0.2-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ca59e7e13e5981175b8b3e4ab84d7da57993eeff53c07764dcebda0d0e64ecd", size = 5225119, upload-time = "2025-09-22T04:03:15.408Z" }, + { url = "https://files.pythonhosted.org/packages/99/05/4e5c2873d8f17aa018e6afde417c80cc5d0c33be4854cce3ef5670c49367/lxml-6.0.2-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:957448ac63a42e2e49531b9d6c0fa449a1970dbc32467aaad46f11545be9af1d", size = 4633665, upload-time = "2025-09-22T04:03:17.262Z" }, + { url = "https://files.pythonhosted.org/packages/0f/c9/dcc2da1bebd6275cdc723b515f93edf548b82f36a5458cca3578bc899332/lxml-6.0.2-cp314-cp314t-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b7fc49c37f1786284b12af63152fe1d0990722497e2d5817acfe7a877522f9a9", size = 5234997, upload-time = "2025-09-22T04:03:19.14Z" }, + { url = "https://files.pythonhosted.org/packages/9c/e2/5172e4e7468afca64a37b81dba152fc5d90e30f9c83c7c3213d6a02a5ce4/lxml-6.0.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e19e0643cc936a22e837f79d01a550678da8377d7d801a14487c10c34ee49c7e", size = 5090957, upload-time = "2025-09-22T04:03:21.436Z" }, + { url = "https://files.pythonhosted.org/packages/a5/b3/15461fd3e5cd4ddcb7938b87fc20b14ab113b92312fc97afe65cd7c85de1/lxml-6.0.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:1db01e5cf14345628e0cbe71067204db658e2fb8e51e7f33631f5f4735fefd8d", size = 4764372, upload-time = "2025-09-22T04:03:23.27Z" }, + { url = "https://files.pythonhosted.org/packages/05/33/f310b987c8bf9e61c4dd8e8035c416bd3230098f5e3cfa69fc4232de7059/lxml-6.0.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:875c6b5ab39ad5291588aed6925fac99d0097af0dd62f33c7b43736043d4a2ec", size = 5634653, upload-time = "2025-09-22T04:03:25.767Z" }, + { url = "https://files.pythonhosted.org/packages/70/ff/51c80e75e0bc9382158133bdcf4e339b5886c6ee2418b5199b3f1a61ed6d/lxml-6.0.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:cdcbed9ad19da81c480dfd6dd161886db6096083c9938ead313d94b30aadf272", size = 5233795, upload-time = "2025-09-22T04:03:27.62Z" }, + { url = "https://files.pythonhosted.org/packages/56/4d/4856e897df0d588789dd844dbed9d91782c4ef0b327f96ce53c807e13128/lxml-6.0.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:80dadc234ebc532e09be1975ff538d154a7fa61ea5031c03d25178855544728f", size = 5257023, upload-time = "2025-09-22T04:03:30.056Z" }, + { url = "https://files.pythonhosted.org/packages/0f/85/86766dfebfa87bea0ab78e9ff7a4b4b45225df4b4d3b8cc3c03c5cd68464/lxml-6.0.2-cp314-cp314t-win32.whl", hash = "sha256:da08e7bb297b04e893d91087df19638dc7a6bb858a954b0cc2b9f5053c922312", size = 3911420, upload-time = "2025-09-22T04:03:32.198Z" }, + { url = "https://files.pythonhosted.org/packages/fe/1a/b248b355834c8e32614650b8008c69ffeb0ceb149c793961dd8c0b991bb3/lxml-6.0.2-cp314-cp314t-win_amd64.whl", hash = "sha256:252a22982dca42f6155125ac76d3432e548a7625d56f5a273ee78a5057216eca", size = 4406837, upload-time = "2025-09-22T04:03:34.027Z" }, + { url = "https://files.pythonhosted.org/packages/92/aa/df863bcc39c5e0946263454aba394de8a9084dbaff8ad143846b0d844739/lxml-6.0.2-cp314-cp314t-win_arm64.whl", hash = "sha256:bb4c1847b303835d89d785a18801a883436cdfd5dc3d62947f9c49e24f0f5a2c", size = 3822205, upload-time = "2025-09-22T04:03:36.249Z" }, +] + [[package]] name = "markupsafe" version = "3.0.3" @@ -227,6 +308,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, ] +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + [[package]] name = "requests" version = "2.32.5" @@ -263,6 +356,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/27/2c/daca29684cbe9fd4bc711f8246da3c10adca1ccc4d24436b17572eb2590e/roman_numerals_py-4.1.0-py3-none-any.whl", hash = "sha256:553114c1167141c1283a51743759723ecd05604a1b6b507225e91dc1a6df0780", size = 4547, upload-time = "2025-12-17T18:25:40.136Z" }, ] +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + [[package]] name = "snowballstemmer" version = "3.0.1" @@ -410,6 +512,7 @@ name = "ssl-website" version = "0.1.0" source = { virtual = "." } dependencies = [ + { name = "ablog" }, { name = "sphinx" }, { name = "sphinx-autobuild" }, { name = "sphinx-book-theme" }, @@ -418,6 +521,7 @@ dependencies = [ [package.metadata] requires-dist = [ + { name = "ablog", specifier = ">=0.11.13" }, { name = "sphinx", specifier = ">=8.2.3" }, { name = "sphinx-autobuild", specifier = ">=2025.8.25" }, { name = "sphinx-book-theme", specifier = ">=1.1.4" }, @@ -467,6 +571,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3d/d8/2083a1daa7439a66f3a48589a57d576aa117726762618f6bb09fe3798796/uvicorn-0.40.0-py3-none-any.whl", hash = "sha256:c6c8f55bc8bf13eb6fa9ff87ad62308bbbc33d0b67f84293151efe87e0d5f2ee", size = 68502, upload-time = "2025-12-21T14:16:21.041Z" }, ] +[[package]] +name = "watchdog" +version = "6.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220, upload-time = "2024-11-01T14:07:13.037Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" }, + { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" }, + { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" }, + { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077, upload-time = "2024-11-01T14:07:03.893Z" }, + { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078, upload-time = "2024-11-01T14:07:05.189Z" }, + { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077, upload-time = "2024-11-01T14:07:06.376Z" }, + { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078, upload-time = "2024-11-01T14:07:07.547Z" }, + { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065, upload-time = "2024-11-01T14:07:09.525Z" }, + { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070, upload-time = "2024-11-01T14:07:10.686Z" }, + { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" }, +] + [[package]] name = "watchfiles" version = "1.1.1"