diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 277f37b24..ce1427854 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -5,11 +5,9 @@ # https://git-scm.com/docs/git-config#Documentation/git-config.txt-blameignoreRevsFile # https://github.com/pydata/pydata-sphinx-theme/pull/713 # -90550b66ace16a370caa446e54698b126fda740b # initial black-format -236d4c6d1f10f5da064d929e9eb594daecf23551 # apply black 20.8b1 format -69f1a42a3b184f4ba4c98f1745779a277d56c5e2 # [pre-commit.ci] Automatic linting and formatting fixes -a35529c9ee8d5863613df40787cda0021b3e0128 # Manual fixes for stylelint -ce583b8f3136d52e8056c9a651bf6f92e7922f79 # Manual adjustments to autofixes -d1ee9eb7a132cde51433e9594513319fdab41f2f # Autofix (stylelint) -0f3aa5ca174fe1534ef4817d42f0e2ffa7d9d921 # [pre-commit.ci] Automatic linting and formatting fixes -9c5a3d592d03849bd050fe946b246145ad171605 # Automated and manual fixes for pre-commits +90550b66ace16a370caa446e54698b126fda740b # initial black-format +236d4c6d1f10f5da064d929e9eb594daecf23551 # apply black 20.8b1 format +69f1a42a3b184f4ba4c98f1745779a277d56c5e2 # [pre-commit.ci] Automatic linting and formatting fixes +a35529c9ee8d5863613df40787cda0021b3e0128 # Manual fixes for stylelint +ce583b8f3136d52e8056c9a651bf6f92e7922f79 # Manual adjustments to autofixes +d1ee9eb7a132cde51433e9594513319fdab41f2f # Autofix (stylelint) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 04b6bdc64..ad1c49c2c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,11 +9,11 @@ ci: # Fix the node version to avoid a GLIBC error # ref: https://stackoverflow.com/questions/71939099/bitbucket-pipeline-error-installing-pre-commit-ts-lint/71940852#71940852 default_language_version: - node: 22.9.0 + node: 16.14.2 repos: - - repo: "https://github.com/pycontribs/mirrors-prettier" - rev: v3.3.3 + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v4.0.0-alpha.8 hooks: - id: prettier # Exclude the HTML, since it doesn't understand Jinja2 @@ -21,26 +21,29 @@ repos: # exclude the pytest-regressions folder tests/test_ally exclude: .+\.html|webpack\.config\.js|tests/test_a11y/ - - repo: "https://github.com/astral-sh/ruff-pre-commit" + - repo: https://github.com/psf/black + rev: 24.10.0 + hooks: + - id: black + + - repo: https://github.com/astral-sh/ruff-pre-commit rev: "v0.7.2" hooks: - id: ruff - args: [--exit-non-zero-on-fix] - - id: ruff-format - - repo: "https://github.com/asottile/pyupgrade" + - repo: https://github.com/asottile/pyupgrade rev: v3.19.0 hooks: - id: pyupgrade args: [--py37-plus] - - repo: "https://github.com/Riverside-Healthcare/djLint" + - repo: https://github.com/Riverside-Healthcare/djLint rev: v1.35.4 hooks: - id: djlint-jinja types_or: ["html"] - - repo: "https://github.com/PyCQA/doc8" + - repo: https://github.com/PyCQA/doc8 rev: v1.1.2 hooks: - id: doc8 @@ -50,12 +53,12 @@ repos: hooks: - id: nbstripout - - repo: "https://github.com/mondeja/pre-commit-po-hooks" + - repo: https://github.com/mondeja/pre-commit-po-hooks rev: v1.7.3 hooks: - id: remove-metadata - - repo: "https://github.com/thibaudcolas/pre-commit-stylelint" + - repo: https://github.com/thibaudcolas/pre-commit-stylelint rev: v16.10.0 hooks: - id: stylelint @@ -65,9 +68,3 @@ repos: # stylelint itself needs to be here when using additional_dependencies. - stylelint@16.5.0 - stylelint-config-standard-scss@13.1.0 - - - repo: "https://github.com/pre-commit/pre-commit-hooks" - rev: v5.0.0 - hooks: - - id: trailing-whitespace - - id: end-of-file-fixer diff --git a/docs/_extension/component_directive.py b/docs/_extension/component_directive.py index 334c79869..07ffcf66f 100644 --- a/docs/_extension/component_directive.py +++ b/docs/_extension/component_directive.py @@ -6,7 +6,6 @@ """ import re - from pathlib import Path from typing import Any, Dict, List @@ -15,7 +14,6 @@ from sphinx.util import logging from sphinx.util.docutils import SphinxDirective - logger = logging.getLogger(__name__) diff --git a/docs/_extension/gallery_directive.py b/docs/_extension/gallery_directive.py index b34a701ce..80642c545 100644 --- a/docs/_extension/gallery_directive.py +++ b/docs/_extension/gallery_directive.py @@ -19,7 +19,6 @@ from sphinx.util.docutils import SphinxDirective from yaml import safe_load - logger = logging.getLogger(__name__) @@ -77,7 +76,7 @@ def run(self) -> List[nodes.Node]: path_doc = Path(path_doc).parent path_data = (path_doc / path_data_rel).resolve() if not path_data.exists(): - logger.info("Could not find grid data at %s.", path_data) + logger.info(f"Could not find grid data at {path_data}.") nodes.text("No grid data found at {path_data}.") return yaml_string = path_data.read_text() diff --git a/docs/conf.py b/docs/conf.py index afab8132c..75722e9f1 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -8,7 +8,6 @@ # -- Path setup -------------------------------------------------------------- import os import sys - from pathlib import Path from typing import Any, Dict @@ -17,7 +16,6 @@ import pydata_sphinx_theme - sys.path.append(str(Path(".").resolve())) # -- Project information ----------------------------------------------------- @@ -194,8 +192,7 @@ }, "use_edit_page_button": True, "show_toc_level": 1, - # [left, content, right] For testing that the navbar items align properly - "navbar_align": "left", + "navbar_align": "left", # [left, content, right] For testing that the navbar items align properly # "show_nav_level": 2, "announcement": "https://raw.githubusercontent.com/pydata/pydata-sphinx-theme/main/docs/_templates/custom-template.html", "show_version_warning_banner": True, @@ -297,15 +294,10 @@ def setup_to_main( app: Sphinx, pagename: str, templatename: str, context, doctree ) -> None: - """ - Add a function that jinja can access for returning an "edit this page" link - pointing to `main`. - """ + """Add a function that jinja can access for returning an "edit this page" link pointing to `main`.""" def to_main(link: str) -> str: - """ - Transform "edit on github" links and make sure they always point to the - main branch. + """Transform "edit on github" links and make sure they always point to the main branch. Args: link: the link to the github edit interface diff --git a/docs/examples/pydata.ipynb b/docs/examples/pydata.ipynb index df86e223d..64c273503 100644 --- a/docs/examples/pydata.ipynb +++ b/docs/examples/pydata.ipynb @@ -29,7 +29,6 @@ "import numpy as np\n", "import pandas as pd\n", "\n", - "\n", "rng = np.random.default_rng(seed=15485863)\n", "data = rng.standard_normal((100, 26))\n", "df = pd.DataFrame(data, columns=list(string.ascii_lowercase))\n", @@ -52,10 +51,8 @@ "import ipywidgets as widgets\n", "import numpy as np\n", "import pandas as pd\n", - "\n", "from IPython.display import display\n", "\n", - "\n", "tab = widgets.Tab()\n", "\n", "descr_str = \"Hello\"\n", @@ -68,9 +65,9 @@ "\n", "# render in output widgets\n", "with widget_images:\n", - " display(pd.DataFrame(np.random.randn(10, 10)))\n", + " display(pd.DataFrame(np.random.randn(10,10)))\n", "with widget_annotations:\n", - " display(pd.DataFrame(np.random.randn(10, 10)))\n", + " display(pd.DataFrame(np.random.randn(10,10)))\n", "\n", "tab.children = [widget_images, widget_annotations]\n", "tab.titles = [\"Images\", \"Annotations\"]\n", @@ -93,7 +90,6 @@ "source": [ "import matplotlib.pyplot as plt\n", "\n", - "\n", "fig, ax = plt.subplots()\n", "ax.scatter(df[\"a\"], df[\"b\"], c=df[\"b\"], s=3)" ] @@ -129,13 +125,10 @@ "import plotly.express as px\n", "import plotly.io as pio\n", "\n", - "\n", "pio.renderers.default = \"notebook\"\n", "\n", "df = px.data.iris()\n", - "fig = px.scatter(\n", - " df, x=\"sepal_width\", y=\"sepal_length\", color=\"species\", size=\"sepal_length\"\n", - ")\n", + "fig = px.scatter(df, x=\"sepal_width\", y=\"sepal_length\", color=\"species\", size=\"sepal_length\")\n", "fig" ] }, @@ -156,10 +149,11 @@ "source": [ "import xarray as xr\n", "\n", - "\n", "data = xr.DataArray(\n", - " np.random.randn(2, 3), dims=(\"x\", \"y\"), coords={\"x\": [10, 20]}, attrs={\"foo\": \"bar\"}\n", - ")\n", + " np.random.randn(2, 3),\n", + " dims=(\"x\", \"y\"),\n", + " coords={\"x\": [10, 20]}, attrs={\"foo\": \"bar\"}\n", + " )\n", "data" ] }, @@ -180,9 +174,8 @@ "source": [ "from ipyleaflet import Map, basemaps\n", "\n", - "\n", "# display a map centered on France\n", - "m = Map(basemap=basemaps.Esri.WorldImagery, zoom=5, center=[46.21, 2.21])\n", + "m = Map(basemap=basemaps.Esri.WorldImagery, zoom=5, center=[46.21, 2.21])\n", "m" ] } diff --git a/docs/scripts/generate_collaborators_gallery.py b/docs/scripts/generate_collaborators_gallery.py index 8a03c22f5..110abfb0f 100644 --- a/docs/scripts/generate_collaborators_gallery.py +++ b/docs/scripts/generate_collaborators_gallery.py @@ -1,17 +1,12 @@ -""" -Uses the GitHub API to list a gallery of all people with direct access to the -repository. -""" +"""Uses the GitHub API to list a gallery of all people with direct access to the repository.""" import json import shlex - from pathlib import Path from subprocess import run from yaml import dump - COLLABORATORS_API = "https://api.github.com/repos/pydata/pydata-sphinx-theme/collaborators?affiliation=direct" print("Grabbing latest collaborators with GitHub API via GitHub's CLI...") diff --git a/docs/scripts/update_kitchen_sink.py b/docs/scripts/update_kitchen_sink.py index 5a8f35d91..4612e6687 100644 --- a/docs/scripts/update_kitchen_sink.py +++ b/docs/scripts/update_kitchen_sink.py @@ -3,13 +3,10 @@ from pathlib import Path from urllib.request import urlopen - EXTRA_MESSAGE = """\ .. note:: - The Kitchen Sink was generated from the - `Sphinx Themes website `_, a community-supported showcase - of themes for `Sphinx `_. + The Kitchen Sink was generated from the `Sphinx Themes website `_, a community-supported showcase of themes for `Sphinx `_. Check it out to see other great themes. .. button-link:: https://sphinx-themes.org diff --git a/docs/user_guide/layout.rst b/docs/user_guide/layout.rst index b3bc6d7b8..697f32171 100644 --- a/docs/user_guide/layout.rst +++ b/docs/user_guide/layout.rst @@ -593,3 +593,4 @@ Please find here the full list of keys you can use in the ``html_theme_options`` .. include:: ../../src/pydata_sphinx_theme/theme/pydata_sphinx_theme/theme.conf :code: ini :class: highlight-ini + diff --git a/pyproject.toml b/pyproject.toml index f8b2eb2ae..1d1272459 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -100,19 +100,15 @@ ignore = ["D001"] # we follow a 1 line = 1 paragraph style [tool.ruff] fix = true -# keep consistent with black -line-length = 88 -indent-width = 4 [tool.ruff.lint] ignore = [ + "E501", # line too long | Black take care of it "D107", # Missing docstring in `__init__` | set the docstring in the class - "D205", # 1 blank line required between summary line and description, - "D212", # docstring summary must be on first physical line - "W291", # let pre-commit handle trailing whitespace ] -select = ["E", "F", "W", "I", "D", "RUF", "G"] +ignore-init-module-imports = true +select = ["E", "F", "W", "I", "D", "RUF"] [tool.ruff.lint.flake8-quotes] docstring-quotes = "double" @@ -120,10 +116,6 @@ docstring-quotes = "double" [tool.ruff.lint.pydocstyle] convention = "google" -[tool.ruff.lint.isort] -lines-between-types = 1 -lines-after-imports = 2 - [tool.djlint] profile = "jinja" extension = "html" diff --git a/src/pydata_sphinx_theme/__init__.py b/src/pydata_sphinx_theme/__init__.py index 3c613831a..28b5a1c56 100644 --- a/src/pydata_sphinx_theme/__init__.py +++ b/src/pydata_sphinx_theme/__init__.py @@ -1,14 +1,12 @@ """Bootstrap-based sphinx theme from the PyData community.""" import json - from functools import partial from pathlib import Path from typing import Dict from urllib.parse import urlparse import requests - from requests.exceptions import ConnectionError, HTTPError, RetryError from sphinx.application import Sphinx from sphinx.builders.dirhtml import DirectoryHTMLBuilder @@ -16,7 +14,6 @@ from . import edit_this_page, logo, pygments, short_link, toctree, translator, utils - __version__ = "0.16.1dev0" @@ -205,7 +202,7 @@ def update_and_remove_templates( for i in range(len(context["css_files"])): asset = context["css_files"][i] # TODO: eventually the contents of context['css_files'] etc should probably - # only be _CascadingStyleSheet etc. For now, assume mixed with strings. + # only be _CascadingStyleSheet etc. For now, assume mixed with strings. asset_path = getattr(asset, "filename", str(asset)) if asset_path == theme_css_name: del context["css_files"][i] @@ -236,8 +233,7 @@ def update_and_remove_templates( DOCUMENTATION_OPTIONS.theme_version = '{__version__}'; DOCUMENTATION_OPTIONS.theme_switcher_json_url = '{json_url}'; DOCUMENTATION_OPTIONS.theme_switcher_version_match = '{version_match}'; - DOCUMENTATION_OPTIONS.show_version_warning_banner = - {str(context["theme_show_version_warning_banner"]).lower()}; + DOCUMENTATION_OPTIONS.show_version_warning_banner = {str(context["theme_show_version_warning_banner"]).lower()}; """ app.add_js_file(None, body=js) diff --git a/src/pydata_sphinx_theme/edit_this_page.py b/src/pydata_sphinx_theme/edit_this_page.py index c54fe20f6..7c97c86dc 100644 --- a/src/pydata_sphinx_theme/edit_this_page.py +++ b/src/pydata_sphinx_theme/edit_this_page.py @@ -1,7 +1,6 @@ """Create an "edit this page" url compatible with bitbucket, gitlab and github.""" import jinja2 - from sphinx.application import Sphinx from sphinx.errors import ExtensionError diff --git a/src/pydata_sphinx_theme/locale/ca/LC_MESSAGES/sphinx.po b/src/pydata_sphinx_theme/locale/ca/LC_MESSAGES/sphinx.po index 56916874d..cb51e2f18 100644 --- a/src/pydata_sphinx_theme/locale/ca/LC_MESSAGES/sphinx.po +++ b/src/pydata_sphinx_theme/locale/ca/LC_MESSAGES/sphinx.po @@ -6,6 +6,7 @@ # Translators: # Cristhian Rivera, 2024 # Oriol Abril-Pla , 2024 +# msgid "" msgstr "" diff --git a/src/pydata_sphinx_theme/locale/cs/LC_MESSAGES/sphinx.po b/src/pydata_sphinx_theme/locale/cs/LC_MESSAGES/sphinx.po index f54416d54..fa6c24b6c 100644 --- a/src/pydata_sphinx_theme/locale/cs/LC_MESSAGES/sphinx.po +++ b/src/pydata_sphinx_theme/locale/cs/LC_MESSAGES/sphinx.po @@ -180,3 +180,4 @@ msgstr "Navigace na stránce" #~ msgid "© Copyright %(copyright)s." #~ msgstr "© Copyright %(copyright)s." + diff --git a/src/pydata_sphinx_theme/locale/en/LC_MESSAGES/sphinx.po b/src/pydata_sphinx_theme/locale/en/LC_MESSAGES/sphinx.po index d0a30cf18..78b7fa8bc 100644 --- a/src/pydata_sphinx_theme/locale/en/LC_MESSAGES/sphinx.po +++ b/src/pydata_sphinx_theme/locale/en/LC_MESSAGES/sphinx.po @@ -181,9 +181,3 @@ msgstr "" #~ msgid "light/dark" #~ msgstr "" - -#~ msgid "" -#~ "Built with the PyData " -#~ "Sphinx Theme %(theme_version)s." -#~ msgstr "" diff --git a/src/pydata_sphinx_theme/locale/es/LC_MESSAGES/sphinx.po b/src/pydata_sphinx_theme/locale/es/LC_MESSAGES/sphinx.po index 0fd9c45fe..c3ce913b1 100644 --- a/src/pydata_sphinx_theme/locale/es/LC_MESSAGES/sphinx.po +++ b/src/pydata_sphinx_theme/locale/es/LC_MESSAGES/sphinx.po @@ -8,6 +8,7 @@ # Cristhian Rivera, 2024 # Felipe Moreno, 2024 # Tania Allard, 2024 +# msgid "" msgstr "" diff --git a/src/pydata_sphinx_theme/locale/fr/LC_MESSAGES/sphinx.po b/src/pydata_sphinx_theme/locale/fr/LC_MESSAGES/sphinx.po index c58ab3763..49439627b 100644 --- a/src/pydata_sphinx_theme/locale/fr/LC_MESSAGES/sphinx.po +++ b/src/pydata_sphinx_theme/locale/fr/LC_MESSAGES/sphinx.po @@ -6,6 +6,7 @@ # Translators: # Rambaud Pierrick , 2024 # Denis Bitouzé , 2024 +# msgid "" msgstr "" diff --git a/src/pydata_sphinx_theme/locale/it/LC_MESSAGES/sphinx.po b/src/pydata_sphinx_theme/locale/it/LC_MESSAGES/sphinx.po index 70f712959..5e1d00997 100644 --- a/src/pydata_sphinx_theme/locale/it/LC_MESSAGES/sphinx.po +++ b/src/pydata_sphinx_theme/locale/it/LC_MESSAGES/sphinx.po @@ -183,3 +183,4 @@ msgstr "Navigazione del sito" #~ msgid "© Copyright %(copyright)s." #~ msgstr "© Copyright %(copyright)s." + diff --git a/src/pydata_sphinx_theme/locale/ja/LC_MESSAGES/sphinx.po b/src/pydata_sphinx_theme/locale/ja/LC_MESSAGES/sphinx.po index d6ca6961b..ff2b44386 100644 --- a/src/pydata_sphinx_theme/locale/ja/LC_MESSAGES/sphinx.po +++ b/src/pydata_sphinx_theme/locale/ja/LC_MESSAGES/sphinx.po @@ -185,3 +185,4 @@ msgstr "サイトナビゲーション" #~ msgid "© Copyright %(copyright)s." #~ msgstr "© Copyright %(copyright)s." + diff --git a/src/pydata_sphinx_theme/locale/ru/LC_MESSAGES/sphinx.po b/src/pydata_sphinx_theme/locale/ru/LC_MESSAGES/sphinx.po index 9022e8940..09f2261d8 100644 --- a/src/pydata_sphinx_theme/locale/ru/LC_MESSAGES/sphinx.po +++ b/src/pydata_sphinx_theme/locale/ru/LC_MESSAGES/sphinx.po @@ -180,3 +180,4 @@ msgstr "Навигация по сайту" #~ msgid "© Copyright %(copyright)s." #~ msgstr "© Копирайт %(copyright)s." + diff --git a/src/pydata_sphinx_theme/locale/sphinx.pot b/src/pydata_sphinx_theme/locale/sphinx.pot index 36812fb37..cdb7df57c 100644 --- a/src/pydata_sphinx_theme/locale/sphinx.pot +++ b/src/pydata_sphinx_theme/locale/sphinx.pot @@ -169,3 +169,4 @@ msgstr "" #: src/pydata_sphinx_theme/theme/pydata_sphinx_theme/sections/header.html:3 msgid "Site navigation" msgstr "" + diff --git a/src/pydata_sphinx_theme/locale/zh/LC_MESSAGES/sphinx.po b/src/pydata_sphinx_theme/locale/zh/LC_MESSAGES/sphinx.po index 2ea18920a..c153fef31 100644 --- a/src/pydata_sphinx_theme/locale/zh/LC_MESSAGES/sphinx.po +++ b/src/pydata_sphinx_theme/locale/zh/LC_MESSAGES/sphinx.po @@ -183,3 +183,4 @@ msgstr "网页导航" #~ msgid "© Copyright %(copyright)s." #~ msgstr "© Copyright %(copyright)s." + diff --git a/src/pydata_sphinx_theme/logo.py b/src/pydata_sphinx_theme/logo.py index a106a300f..d5ba236cb 100644 --- a/src/pydata_sphinx_theme/logo.py +++ b/src/pydata_sphinx_theme/logo.py @@ -56,11 +56,9 @@ def setup_logo_path( def copy_logo_images(app: Sphinx, exception=None) -> None: - """ - Copy logo image to the _static directory. + """Copy logo image to the _static directory. - If logo image paths are given, copy them to the `_static` folder. - Then we can link to them directly in an html_page_context event. + If logo image paths are given, copy them to the `_static` folder Then we can link to them directly in an html_page_context event. """ warning = partial(maybe_warn, app) logo = get_theme_options_dict(app).get("logo", {}) @@ -78,8 +76,7 @@ def copy_logo_images(app: Sphinx, exception=None) -> None: assert full_logo_path.is_absolute() if not full_logo_path.exists(): warning(f"Path to {kind} image logo does not exist: {path_image}") - # Ensure templates cannot be passed for logo path to avoid security - # vulnerability + # Ensure templates cannot be passed for logo path to avoid security vulnerability if path_image.lower().endswith("_t"): raise ExtensionError( f"The {kind} logo path '{path_image}' looks like a Sphinx template; " diff --git a/src/pydata_sphinx_theme/short_link.py b/src/pydata_sphinx_theme/short_link.py index 34db161e4..ca5d265c6 100644 --- a/src/pydata_sphinx_theme/short_link.py +++ b/src/pydata_sphinx_theme/short_link.py @@ -11,24 +11,20 @@ class ShortenLinkTransform(SphinxPostTransform): - """ - Shorten link when they are coming from github or gitlab and add an extra class to - the tag for further styling. + """Shorten link when they are coming from github or gitlab and add an extra class to the tag for further styling. Before: .. code-block:: html - - https://github.com/2i2c-org/infrastructure/issues/1329 + + https://github.com/2i2c-org/infrastructure/issues/1329 After: .. code-block:: html - - 2i2c-org/infrastructure#1329 + + 2i2c-org/infrastructure#1329 """ diff --git a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/components/search-button-field.html b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/components/search-button-field.html index f93a5f7c6..e6cb44f7d 100644 --- a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/components/search-button-field.html +++ b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/components/search-button-field.html @@ -1,5 +1,5 @@ {# Displays a search field image that opens a search overlay when clicked. #} -{# +{# As this function will only work when JavaScript is enabled, we add a class that will hide it if js is disable. #} diff --git a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/layout.html b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/layout.html index e062c1806..39e1c7a6f 100644 --- a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/layout.html +++ b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/layout.html @@ -17,8 +17,8 @@ document.documentElement.dataset.mode = localStorage.getItem("mode") || "{{ default_mode }}"; document.documentElement.dataset.theme = localStorage.getItem("theme") || "{{ default_mode }}"; -