Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
48cb5ab
chore: remove plotting scripts
dilyabareeva May 4, 2026
c3478f4
chore: full reproduction scripts
dilyabareeva May 4, 2026
6d2ea96
chore: start anonymization pt1
dilyabareeva May 4, 2026
84dd6d3
chore: remove slurm folder
dilyabareeva May 4, 2026
0fb0d97
chore: anonymization pt2
dilyabareeva May 4, 2026
07b6e57
chore: anonymize docs
dilyabareeva May 4, 2026
6ae2ab3
chore: update readme and docs
dilyabareeva May 4, 2026
47f890c
fix: problematic docstrings
dilyabareeva May 4, 2026
662344b
fix: docs compile errors
dilyabareeva May 4, 2026
c379bb4
fix: docs compile errors pt2
dilyabareeva May 4, 2026
480da4c
chore: anonymous links to readme assets
dilyabareeva May 4, 2026
e0bb072
chore: remove pip references
dilyabareeva May 4, 2026
8747f9c
chore: remove paper link
dilyabareeva May 4, 2026
f7dd1d3
chore: fixing anynomyzation gone wrong
dilyabareeva May 4, 2026
2cb2724
chore: add randomit initialization to representer points
dilyabareeva May 5, 2026
9ca9f63
chore: recover awa eval scripts
dilyabareeva May 5, 2026
1520e22
refactor: remove load_meta_from_disk argument, accept different types…
dilyabareeva May 5, 2026
c6b8706
docs: extend integration tests to use in docs snippets
dilyabareeva May 5, 2026
3b24b11
docs: update docs and readme
dilyabareeva May 5, 2026
9b358c7
refactor: rename common utils
dilyabareeva May 5, 2026
2ad4807
docs: small updates
dilyabareeva May 5, 2026
9d011d6
test: update after refactor
dilyabareeva May 5, 2026
0dd2eb9
style: run ruff
dilyabareeva May 5, 2026
6ed6eee
chore: delete empty CHANGELOG.md
dilyabareeva May 5, 2026
288c767
docs: fix in the lds
dilyabareeva May 5, 2026
9442011
style: add a docstring to resolve_config
dilyabareeva May 5, 2026
47ab406
docs: anonymize
dilyabareeva May 5, 2026
048661d
docs: update formulations, citations, tutorials
dilyabareeva May 6, 2026
e298ddd
docs: dark-mode figure
dilyabareeva May 6, 2026
6e0651f
chore: script comment clean-up
dilyabareeva May 7, 2026
db1995a
chore: README fixes
dilyabareeva May 7, 2026
8fb625d
docs: typo
dilyabareeva May 7, 2026
a071819
docs: small bench_ids explanation
dilyabareeva May 7, 2026
e4007aa
docs: formatting
dilyabareeva May 7, 2026
4d3d0a1
docs: update py version in readme
dilyabareeva May 7, 2026
4264b05
docs: py version in docs
dilyabareeva May 7, 2026
a767850
chore: deanonymize
dilyabareeva May 8, 2026
6972e1d
test: add missing s arg for class detection test
dilyabareeva May 8, 2026
2c7a1a4
test: switch to lower bound for failing tests across platforms
dilyabareeva May 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,15 @@ outputs/
cache/
/.env
bin/*
docs/source/**
docs/source/docs_api/**
eval_results/*
eval_bench/**

assets/demo/*
bench_out/*
fig_1_images/*
tutorials/*
scripts/bench_out/*
scriptsbench_out/*
CLAUDE.md
.vscode/
quanda_benchmark_tutorial_cache/*
Expand All @@ -88,4 +88,8 @@ tmp_*/*
scripts/paper_tex/**
scratch/*
slurm/get_logs.sh
scripts/delete_hf.py
scripts/delete_hf.py
scripts/plot_results_LOCAL.py
scripts/**/plot_*_LOCAL.sh
scripts/PLOT_ALL_LOCAL.sh
slurm_LOCAL/*
Empty file removed CHANGELOG.md
Empty file.
2 changes: 1 addition & 1 deletion CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ representative at an online or offline event.

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
dilyabareeva@gmail.com.
[dilyabareeva@gmail.com](mailto:dilyabareeva@gmail.com).
All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
Expand Down
8 changes: 7 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ Currently, the following markers are available to filter tests:
- benchmarks: Benchmark modules
- global_ranking: global_ranking modules
- self_influence: self_influence methods of explainers
- tasks: task modules
- integration: integration tests
- slow: tests marked as slow (excluded by default; run with `pytest -m slow`)
- production_bench: production benchmark sanity checks, run only when explicitly specified

The authoritative list lives in `pytest.ini`.

Ideally, all contributions should include tests to ensure correctness.

Expand Down Expand Up @@ -187,7 +193,7 @@ To contribute a new benchmark you generally do not need to override these four c
1. **A subclass of** `Benchmark` under the appropriate `quanda/benchmarks/{downstream_eval,heuristics,ground_truth}/` subdirectory. Subclasses customize behavior via:

- `__init__` — accept any benchmark-specific fields beyond what the base `__init__` already stores (`model`, `train_dataset`, `eval_dataset`, `checkpoints`, `checkpoints_load_func`, `device`, `val_dataset`, `use_predictions`).
- `_extra_kwargs_from_config(cls, config, train_dataset, eval_dataset, metadata_dir, load_meta_from_disk)` — extract any subclass-specific kwargs from the YAML and return them as a dict; they get passed into `__init__` by `from_config`.
- `_extra_kwargs_from_config(cls, config, train_dataset, eval_dataset, metadata_dir, load_fresh)` — extract any subclass-specific kwargs from the YAML and return them as a dict; they get passed into `__init__` by `from_config`.
- `_compute_and_save_indices(self, config, batch_size)` — only override if your benchmark needs to cache extra metadata on the train pass (filtered eval indices, ranking caches, etc.).
- `evaluate(self, explainer_cls, expl_kwargs, batch_size)` — runs the explainer over `eval_dataset`, feeds the attributions to the corresponding `Metric` via `update`/`compute`, and returns the result dict (must contain `"score"`).

Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2024 Dilyara Bareeva, Galip Ümit Yolcu
Copyright (c) 2026 Dilyara Bareeva, Galip Ümit Yolcu, Anna Hedström, Niklas Schmolenski, Thomas Wiegand, Wojciech Samek, Sebastian Lapuschkin

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
62 changes: 30 additions & 32 deletions README.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion config/eval/awa2_resnet50.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ hydra:
n_jobs: 1

bench: awa2_class_detection
root_dir: ${cluster_or_local:/data/cluster/users/bareeva/quanda_output_new2,/data2/bareeva/Projects/quanda/cluster_output_new2}
root_dir: bench_out
cache_dir: ${root_dir}/eval_bench/awa2
results_dir: ${root_dir}/eval_results/awa2

Expand Down
2 changes: 1 addition & 1 deletion config/eval/bert_qnli.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ hydra:
n_jobs: 1

bench: qnli_class_detection
root_dir: ${cluster_or_local:/data/cluster/users/bareeva/quanda_output_new2,/data2/bareeva/Projects/quanda/cluster_output_new2}
root_dir: bench_out
cache_dir: ${root_dir}/eval_bench/qnli
results_dir: ${root_dir}/eval_results/qnli
device: cuda:0
Expand Down
2 changes: 1 addition & 1 deletion config/eval/cifar_resnet9.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ hydra:
n_jobs: 1

bench: cifar_class_detection
root_dir: ${cluster_or_local:/data/cluster/users/bareeva/quanda_output_new2,/data2/bareeva/Projects/quanda/cluster_output_new2}
root_dir: bench_out
cache_dir: ${root_dir}/eval_bench/cifar
results_dir: ${root_dir}/eval_results/cifar

Expand Down
2 changes: 1 addition & 1 deletion config/eval/gpt2_trex.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ hydra:
n_jobs: 1

bench: gpt2_trex_openwebtext_ft_mrr
root_dir: ${cluster_or_local:/data/cluster/users/bareeva/quanda_output_new2,/data2/bareeva/Projects/quanda/cluster_output_new2}
root_dir: bench_out
cache_dir: ${root_dir}/eval_bench/gpt2_trex
results_dir: ${root_dir}/eval_results/gpt2_trex
device: cuda:0
Expand Down
2 changes: 1 addition & 1 deletion config/eval/mnist_lenet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ hydra:
n_jobs: 1

bench: mnist_class_detection
root_dir: ${cluster_or_local:/data/cluster/users/bareeva/quanda_output_new2,/data2/bareeva/Projects/quanda/cluster_output_new2}
root_dir: bench_out
cache_dir: ${root_dir}/eval_bench/mnist
results_dir: ${root_dir}/eval_results/mnist

Expand Down
1 change: 1 addition & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ help:

rst:
@sphinx-apidoc -o source/docs_api ../quanda --module-first --separate --force
@sed -i '/^\.\. automodule:: quanda$$/,/^$$/ { /:members:/d; /:undoc-members:/d; }' source/docs_api/quanda.rst


clean:
Expand Down
Binary file modified docs/source/_static/components-darkmode.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/source/background.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
What is Training Data Attribution?
==========
==================================

The interpretability of neural network decisions is an active area of research which has seen a variety of approaches over time. Most of the initial focus was on feature attribution methods, which highlight features in the input space that are responsible for a specific prediction (`Simonyan et al., 2014 <https://arxiv.org/abs/1312.6034>`_; `Bach et al., 2015 <https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0130140>`_; `Lundberg and Lee, 2017 <https://proceedings.neurips.cc/paper_files/paper/2017/file/8a20a8621978632d76c43dfd28b67767-Paper.pdf>`_). These methods were often criticized for being unreliable and difficult to understand (`Adebayo et al., 2018 <https://proceedings.neurips.cc/paper_files/paper/2018/file/294a8ed24b1ad22ec2e7efea049b8737-Paper.pdf>`_; `Ghorbani et al., 2019 <https://ojs.aaai.org/index.php/AAAI/article/view/4252>`_). In response, researchers explored new directions, such as concept-based (`Poeta et al., 2023 <https://arxiv.org/abs/2312.12936>`_) and mechanistic interpretability (`Bereska and Gavves <https://openreview.net/forum?id=ePUVetPKu6>`_) methods. Recently, **Training Data Attribution** (TDA) has gained attention as a promising approach for enhancing the interpretability of neural networks.

Expand Down
5 changes: 4 additions & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
project = "quanda"
copyright = f"{str(datetime.utcnow().year)}, Dilyara Bareeva, Galip Ümit Yolcu"
author = "Dilyara Bareeva, Galip Ümit Yolcu"
release = "05.10.2024"
release = "05.05.2026"

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
Expand All @@ -30,6 +30,9 @@
]
source_suffix = [".rst", ".md"]
autosummary_generate = True
numpydoc_class_members_toctree = False
numpydoc_show_class_members = False
suppress_warnings = ["ref.python"]
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
rst_epilog = """
.. |quanda| raw:: html
Expand Down
11 changes: 9 additions & 2 deletions docs/source/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ In this guide, you will get a summary of the main components of

If you have any questions regarding the codebase, please `open an
issue <https://github.com/dilyabareeva/quanda/issues/new/choose>`__ or write us
at dilyabareeva@gmail.com or galip.uemit.yolcu@hhi.fraunhofer.de.
at `dilyabareeva@gmail.com <mailto:dilyabareeva@gmail.com>`__ or
`galip.uemit.yolcu@hhi.fraunhofer.de <mailto:galip.uemit.yolcu@hhi.fraunhofer.de>`__.

Table of Contents
-----------------
Expand Down Expand Up @@ -122,6 +123,12 @@ Currently, the following markers are available to filter tests:
- benchmarks: Benchmark modules
- global_ranking: global_ranking modules
- self_influence: self_influence methods of explainers
- tasks: task modules
- integration: integration tests
- slow: tests marked as slow (excluded by default; run with ``pytest -m slow``)
- production_bench: production benchmark sanity checks, run only when explicitly specified

The authoritative list lives in ``pytest.ini``.

Ideally, all contributions should include tests to ensure correctness.

Expand Down Expand Up @@ -330,7 +337,7 @@ these four classmethods . What you should provide is:
``checkpoints_load_func``, ``device``, ``val_dataset``,
``use_predictions``).
- ``_extra_kwargs_from_config(cls, config, train_dataset,
eval_dataset, metadata_dir, load_meta_from_disk)`` — extract any
eval_dataset, metadata_dir, load_fresh)`` — extract any
subclass-specific kwargs from the YAML and return them as a dict;
they get passed into ``__init__`` by ``from_config``.
- ``_compute_and_save_indices(self, config, batch_size)`` — only
Expand Down
154 changes: 154 additions & 0 deletions docs/source/explainers.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
Explainer Wrappers
==================

|quanda| ships wrappers around several existing TDA libraries, exposing them
through a single :doc:`Explainer <docs_api/quanda.explainers.base>` interface.
The tables below list every wrapper class and cite the paper that introduced
the underlying method. All wrapper sources live under
``quanda/explainers/wrappers/``.

All wrappers can be imported directly from ``quanda.explainers.wrappers``,
for example:

.. code:: python

from quanda.explainers.wrappers import (
CaptumSimilarity,
TRAK,
Kronfluence,
RepresenterPoints,
DattriIFExplicit,
)

Captum
------
Wrappers around the influence methods provided by `Captum
<https://github.com/pytorch/captum/tree/master>`_. Source:
``quanda/explainers/wrappers/captum_influence.py``.

.. list-table::
:header-rows: 1
:widths: 25 75

* - Wrapper
- Reference
* - ``CaptumSimilarity``
- Similarity between test and training samples in the representation
space of a chosen layer. See `Captum's SimilarityInfluence docs
<https://captum.ai/api/influence.html#similarityinfluence>`__.
* - ``CaptumArnoldi``
- Schioppa et al., 2022. *Scaling Up Influence Functions.*
`arXiv:2112.03052 <https://arxiv.org/abs/2112.03052>`__
* - ``CaptumTracInCP``
- Pruthi et al., 2020. *Estimating Training Data Influence by Tracing
Gradient Descent.* `NeurIPS 2020
<https://proceedings.neurips.cc/paper/2020/hash/e6385d39ec9394f2f3a354d9d2b88eec-Abstract.html>`__
* - ``CaptumTracInCPFast``
- Pruthi et al., 2020. *Estimating Training Data Influence by Tracing
Gradient Descent.* `NeurIPS 2020
<https://proceedings.neurips.cc/paper/2020/hash/e6385d39ec9394f2f3a354d9d2b88eec-Abstract.html>`__
* - ``CaptumTracInCPFastRandProj``
- Pruthi et al., 2020. *Estimating Training Data Influence by Tracing
Gradient Descent.* `NeurIPS 2020
<https://proceedings.neurips.cc/paper/2020/hash/e6385d39ec9394f2f3a354d9d2b88eec-Abstract.html>`__

Representer Point Selection
---------------------------
Source: ``quanda/explainers/wrappers/representer_points.py``.

.. list-table::
:header-rows: 1
:widths: 25 75

* - Wrapper
- Reference
* - ``RepresenterPoints``
- Yeh et al., 2018. *Representer Point Selection for Explaining Deep
Neural Networks.* `NeurIPS 2018
<https://proceedings.neurips.cc/paper/2018/hash/8a7129b8f3edd95b7d969dfc2c8e9d9d-Abstract.html>`__
— original implementation: `chihkuanyeh/Representer_Point_Selection
<https://github.com/chihkuanyeh/Representer_Point_Selection>`__

TRAK
----
Source: ``quanda/explainers/wrappers/trak_wrapper.py``.

.. list-table::
:header-rows: 1
:widths: 25 75

* - Wrapper
- Reference
* - ``TRAK``
- Park et al., 2023. *TRAK: Attributing Model Behavior at Scale.*
`ICML 2023 <https://proceedings.mlr.press/v202/park23c.html>`__
— original implementation: `MadryLab/trak
<https://github.com/MadryLab/trak>`__

Kronfluence
-----------
Source: ``quanda/explainers/wrappers/kronfluence.py``.

.. list-table::
:header-rows: 1
:widths: 25 75

* - Wrapper
- Reference
* - ``Kronfluence (incl. EK-FAC)``
- Grosse et al., 2023. *Studying Large Language Model Generalization with
Influence Functions.* `arXiv:2308.03296
<https://arxiv.org/abs/2308.03296>`__
— original implementation: `pomonam/kronfluence
<https://github.com/pomonam/kronfluence>`__

Dattri
------
Wrappers around the unified TDA family provided by `Dattri
<https://github.com/TRAIS-Lab/dattri>`_ (Deng et al., 2024,
`arXiv:2410.04555 <https://arxiv.org/abs/2410.04555>`__). Source:
``quanda/explainers/wrappers/dattri_influence.py``.

.. list-table::
:header-rows: 1
:widths: 25 75

* - Wrapper
- Reference
* - ``DattriIFExplicit``
- Koh and Liang, 2017. *Understanding Black-box Predictions via Influence
Functions.* `ICML 2017
<https://proceedings.mlr.press/v70/koh17a.html>`__
* - ``DattriIFCG``
- Koh and Liang, 2017 (conjugate-gradient solver). `ICML 2017
<https://proceedings.mlr.press/v70/koh17a.html>`__
* - ``DattriIFLiSSA``
- Agarwal et al., 2017. *Second-Order Stochastic Optimization for Machine
Learning in Linear Time.* `JMLR 2017
<https://www.jmlr.org/papers/v18/16-491.html>`__
* - ``DattriIFDataInf``
- Kwon et al., 2024. *DataInf: Efficiently Estimating Data Influence in
LoRA-tuned LLMs and Diffusion Models.* `ICLR 2024
<https://openreview.net/forum?id=9m02ib92Wz>`__
* - ``DattriArnoldi``
- Schioppa et al., 2022. *Scaling Up Influence Functions.*
`arXiv:2112.03052 <https://arxiv.org/abs/2112.03052>`__
* - ``DattriEKFAC``
- Grosse et al., 2023. *Studying Large Language Model Generalization with
Influence Functions.* `arXiv:2308.03296
<https://arxiv.org/abs/2308.03296>`__
* - ``DattriTracInCP``
- Pruthi et al., 2020. *Estimating Training Data Influence by Tracing
Gradient Descent.* `NeurIPS 2020
<https://proceedings.neurips.cc/paper/2020/hash/e6385d39ec9394f2f3a354d9d2b88eec-Abstract.html>`__
* - ``DattriGradDot``
- Charpiat et al., 2019. *Input Similarity from the Neural Network
Perspective.* `NeurIPS 2019
<https://proceedings.neurips.cc/paper_files/paper/2019/hash/c61f571dbd2fb949d3fe5ae1608dd48b-Abstract.html>`__
* - ``DattriGradCos``
- Charpiat et al., 2019. *Input Similarity from the Neural Network
Perspective.* `NeurIPS 2019
<https://proceedings.neurips.cc/paper_files/paper/2019/hash/c61f571dbd2fb949d3fe5ae1608dd48b-Abstract.html>`__
* - ``DattriTRAK``
- Park et al., 2023. *TRAK: Attributing Model Behavior at Scale.*
`ICML 2023 <https://proceedings.mlr.press/v202/park23c.html>`__
4 changes: 2 additions & 2 deletions docs/source/how_to_evaluate.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
How to Assess the Quality of Attributions?
==========
==========================================

Evaluation of interpretability approaches is a challenging task, as it is often difficult to define a ground truth for interpretability. Although there are various demonstrations of TDA’s potential for interpretability and practical applications, the critical question of how TDA methods should be effectively evaluated remains open. While methods based on estimating counterfactual retraining effects have a well-defined ground truth, this ground truth is computationally demanding and is not feasibly computable for large scale experiments. To address these shortcomings, several approaches have been proposed by the community, which can be categorized into three groups:

Expand All @@ -17,7 +17,7 @@ As some of the methods are designed to approximate LOO effects, ground truth can

<details><summary><b><big>Downstream Task Evaluators</big></b></summary>

To remedy the challenges associated with ground truth evaluation, the literature proposes to assess the utility of a TDA method within the context of an end-task. The most commonly used evaluation criteria is Mislabeling Detection (`Koh and Liang, 2017 <https://proceedings.mlr.press/v70/koh17a.html>`_; `Yeh et al., 2018 <https://proceedings.neurips.cc/paper/2018/hash/8a7129b8f3edd95b7d969dfc2c8e9d9d-Abstract.html>`_; `Pruthi et al., 2020 <https://proceedings.neurips.cc/paper/2020/hash/e6385d39ec9394f2f3a354d9d2b88eec-Abstract.html>`_) which compares different TDA methods in terms of their usefulness for detecting mislabeled samples after training the network on a dataset of which the labels are deliberately poisoned. Other examples could be detecting backdoor attacks (`Karthikeyan et al., 2021 <https://arxiv.org/abs/2111.04683>`_; `Yolcu et al., 2024 <https://arxiv.org/abs/2402.12118>`_) or predicting the model decision from its attributions (`Hanawa et al., 2021 <https://openreview.net/forum?id=9uvhpyQwzM_>`_).
To remedy the challenges associated with ground truth evaluation, the literature proposes to assess the utility of a TDA method within the context of an end-task. The most commonly used evaluation criteria is Mislabeling Detection (`Koh and Liang, 2017 <https://proceedings.mlr.press/v70/koh17a.html>`_; `Yeh et al., 2018 <https://proceedings.neurips.cc/paper/2018/hash/8a7129b8f3edd95b7d969dfc2c8e9d9d-Abstract.html>`_; `Pruthi et al., 2020 <https://proceedings.neurips.cc/paper/2020/hash/e6385d39ec9394f2f3a354d9d2b88eec-Abstract.html>`_) which compares different TDA methods in terms of their usefulness for detecting mislabeled samples after training the network on a dataset of which the labels are deliberately poisoned. Other examples could be detecting backdoor attacks (`Karthikeyan et al., 2021 <https://arxiv.org/abs/2111.04683>`_; `Yolcu et al., 2025 <https://openreview.net/forum?id=qfx81N884A>`_) or predicting the model decision from its attributions (`Hanawa et al., 2021 <https://openreview.net/forum?id=9uvhpyQwzM_>`_).

.. raw:: html

Expand Down
Loading
Loading