diff --git a/src/accounting/account/forms.py b/src/accounting/account/forms.py index c15940f..9772bb8 100644 --- a/src/accounting/account/forms.py +++ b/src/accounting/account/forms.py @@ -168,7 +168,9 @@ class AccountReorderForm: :param base: The base account. """ self.base: BaseAccount = base + """The base account.""" self.is_modified: bool = False + """Whether the order is modified.""" def save_order(self) -> None: """Saves the order of the account. diff --git a/src/accounting/forms.py b/src/accounting/forms.py index 5c83bf6..64e8d9e 100644 --- a/src/accounting/forms.py +++ b/src/accounting/forms.py @@ -65,6 +65,7 @@ class IsDebitAccount: :param message: The error message. """ self.__message: str | LazyString = message + """The error message.""" def __call__(self, form: FlaskForm, field: StringField) -> None: if field.data is None: @@ -85,6 +86,7 @@ class IsCreditAccount: :param message: The error message. """ self.__message: str | LazyString = message + """The error message.""" def __call__(self, form: FlaskForm, field: StringField) -> None: if field.data is None: diff --git a/src/accounting/journal_entry/forms/reorder.py b/src/accounting/journal_entry/forms/reorder.py index b148a58..2c0932d 100644 --- a/src/accounting/journal_entry/forms/reorder.py +++ b/src/accounting/journal_entry/forms/reorder.py @@ -54,7 +54,9 @@ class JournalEntryReorderForm: :param date: The date. """ self.date: dt.date = date + """The date.""" self.is_modified: bool = False + """Whether the order is modified.""" def save_order(self) -> None: """Saves the order of the account. diff --git a/src/accounting/journal_entry/utils/description_editor.py b/src/accounting/journal_entry/utils/description_editor.py index b3ad773..5a79ad6 100644 --- a/src/accounting/journal_entry/utils/description_editor.py +++ b/src/accounting/journal_entry/utils/description_editor.py @@ -166,8 +166,11 @@ class DescriptionRecurring: :param account: The account. """ self.name: str = name + """The name.""" self.account: DescriptionAccount = DescriptionAccount(account, 0) + """The account.""" self.description_template: str = description_template + """The description template.""" @property def account_codes(self) -> list[str]: diff --git a/src/accounting/locale.py b/src/accounting/locale.py index 1b16580..4a479c5 100644 --- a/src/accounting/locale.py +++ b/src/accounting/locale.py @@ -25,8 +25,10 @@ from flask_babel import LazyString, Domain from flask_babel_js import JAVASCRIPT, c2js translation_dir: Path = Path(__file__).parent / "translations" +"""The directory of the translation files.""" domain: Domain = Domain(translation_directories=[translation_dir], domain="accounting") +"""The message domain.""" def gettext(string, **variables) -> str: @@ -120,6 +122,5 @@ def init_app(app: Flask, bp: Blueprint) -> None: :param bp: The blueprint of the accounting application. :return: None. """ - bp.add_url_rule("/_jstrans.js", "babel_catalog", - __babel_js_catalog_view) + bp.add_url_rule("/_jstrans.js", "babel_catalog", __babel_js_catalog_view) app.jinja_env.globals["A_"] = domain.gettext diff --git a/src/accounting/report/reports/balance_sheet.py b/src/accounting/report/reports/balance_sheet.py index 4e0a011..9fc2321 100644 --- a/src/accounting/report/reports/balance_sheet.py +++ b/src/accounting/report/reports/balance_sheet.py @@ -145,6 +145,7 @@ class AccountCollector: .filter(sa.or_(Account.id.in_({x.id for x in account_balances}), Account.base_code == "3351", Account.base_code == "3353")).all() + """The accounts.""" account_by_id: dict[int, Account] \ = {x.id: x for x in self.__all_accounts} self.accounts: list[ReportAccount] \ @@ -154,6 +155,7 @@ class AccountCollector: account_by_id[x.id], self.__period)) for x in account_balances] + """The accounts on the balance sheet.""" self.__add_accumulated() self.__add_current_period() self.accounts.sort(key=lambda x: (x.account.base_code, x.account.no)) diff --git a/src/accounting/report/reports/income_statement.py b/src/accounting/report/reports/income_statement.py index ccaa360..72b451c 100644 --- a/src/accounting/report/reports/income_statement.py +++ b/src/accounting/report/reports/income_statement.py @@ -106,6 +106,7 @@ class Section: """The subsections in the section.""" self.accumulated: AccumulatedTotal \ = AccumulatedTotal(accumulated_title) + """The accumulated total.""" @property def total(self) -> Decimal: diff --git a/src/accounting/utils/options.py b/src/accounting/utils/options.py index 6e14deb..9e032b6 100644 --- a/src/accounting/utils/options.py +++ b/src/accounting/utils/options.py @@ -39,8 +39,11 @@ class RecurringItem: :param description_template: The description template. """ self.name: str = name + """The name.""" self.account_code: str = account_code + """The account code.""" self.description_template: str = description_template + """The description template.""" @property def account_text(self) -> str: @@ -61,8 +64,10 @@ class Recurring: """ self.expenses: list[RecurringItem] \ = [RecurringItem(x[0], x[1], x[2]) for x in data["expense"]] + """The recurring expenses.""" self.incomes: list[RecurringItem] \ = [RecurringItem(x[0], x[1], x[2]) for x in data["income"]] + """The recurring incomes.""" @property def codes(self) -> set[str]: diff --git a/src/accounting/utils/pagination.py b/src/accounting/utils/pagination.py index 1dc375a..67ea050 100644 --- a/src/accounting/utils/pagination.py +++ b/src/accounting/utils/pagination.py @@ -63,6 +63,7 @@ DEFAULT_PAGE_SIZE: int = 10 """The default page size.""" T = TypeVar("T") +"""The pagination item type.""" class Pagination(Generic[T]): diff --git a/src/accounting/utils/user.py b/src/accounting/utils/user.py index b5d8583..a0168e4 100644 --- a/src/accounting/utils/user.py +++ b/src/accounting/utils/user.py @@ -27,6 +27,7 @@ from flask import g, Response from flask_sqlalchemy.model import Model T = TypeVar("T", bound=Model) +"""The user data model data type.""" class UserUtilityInterface(Generic[T], ABC): diff --git a/tests/babel-utils-test-site.py b/tests/babel-utils-test-site.py index acda463..0bcb064 100755 --- a/tests/babel-utils-test-site.py +++ b/tests/babel-utils-test-site.py @@ -28,8 +28,11 @@ from babel.messages.frontend import CommandLineInterface from opencc import OpenCC root_dir: Path = Path(__file__).parent.parent +"""The project root directory.""" translation_dir: Path = root_dir / "tests" / "test_site" / "translations" +"""The directory of the translation files.""" domain: str = "messages" +"""The message domain.""" @click.group() diff --git a/tests/babel-utils.py b/tests/babel-utils.py index fb9c801..f999116 100755 --- a/tests/babel-utils.py +++ b/tests/babel-utils.py @@ -28,8 +28,11 @@ from babel.messages.frontend import CommandLineInterface from opencc import OpenCC root_dir: Path = Path(__file__).parent.parent +"""The project root directory.""" translation_dir: Path = root_dir / "src" / "accounting" / "translations" +"""The directory of the translation files.""" domain: str = "accounting" +"""The message domain.""" @click.group() diff --git a/tests/test_account.py b/tests/test_account.py index a8304ff..b486262 100644 --- a/tests/test_account.py +++ b/tests/test_account.py @@ -73,6 +73,7 @@ class AccountTestCase(unittest.TestCase): :return: None. """ self.app: Flask = create_test_app() + """The Flask application.""" with self.app.app_context(): from accounting.models import Account, AccountL10n @@ -80,6 +81,7 @@ class AccountTestCase(unittest.TestCase): Account.query.delete() db.session.commit() self.encoded_next_uri: str = encode_next(NEXT_URI) + """The encoded next URI.""" self.client, self.csrf_token = get_client(self.app, "editor") response: httpx.Response diff --git a/tests/test_base_account.py b/tests/test_base_account.py index 71c5e47..9728044 100644 --- a/tests/test_base_account.py +++ b/tests/test_base_account.py @@ -40,6 +40,7 @@ class BaseAccountTestCase(unittest.TestCase): :return: None. """ self.app: Flask = create_test_app() + """The Flask application.""" def test_nobody(self) -> None: """Test the permission as nobody. diff --git a/tests/test_commands.py b/tests/test_commands.py index bf32fbe..f786114 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -41,6 +41,7 @@ class ConsoleCommandTestCase(unittest.TestCase): :return: None. """ self.app: Flask = create_test_app() + """The Flask application.""" with self.app.app_context(): # Drop every accounting table, to see if accounting-init recreates diff --git a/tests/test_currency.py b/tests/test_currency.py index c47e44e..e04b40d 100644 --- a/tests/test_currency.py +++ b/tests/test_currency.py @@ -66,6 +66,7 @@ class CurrencyTestCase(unittest.TestCase): :return: None. """ self.app: Flask = create_test_app() + """The Flask application.""" with self.app.app_context(): from accounting.models import Currency, CurrencyL10n diff --git a/tests/test_description_editor.py b/tests/test_description_editor.py index ed34769..9a5d227 100644 --- a/tests/test_description_editor.py +++ b/tests/test_description_editor.py @@ -37,12 +37,14 @@ class DescriptionEditorTestCase(unittest.TestCase): :return: None. """ self.app: Flask = create_test_app() + """The Flask application.""" with self.app.app_context(): from accounting.models import JournalEntry, JournalEntryLineItem JournalEntry.query.delete() JournalEntryLineItem.query.delete() self.encoded_next_uri: str = encode_next(NEXT_URI) + """The encoded next URI.""" self.client, self.csrf_token = get_client(self.app, "editor") diff --git a/tests/test_journal_entry.py b/tests/test_journal_entry.py index 12f100e..2fb2338 100644 --- a/tests/test_journal_entry.py +++ b/tests/test_journal_entry.py @@ -49,12 +49,14 @@ class CashReceiptJournalEntryTestCase(unittest.TestCase): :return: None. """ self.app: Flask = create_test_app() + """The Flask application.""" with self.app.app_context(): from accounting.models import JournalEntry, JournalEntryLineItem JournalEntry.query.delete() JournalEntryLineItem.query.delete() self.encoded_next_uri: str = encode_next(NEXT_URI) + """The encoded next URI.""" self.client, self.csrf_token = get_client(self.app, "editor") @@ -665,12 +667,14 @@ class CashDisbursementJournalEntryTestCase(unittest.TestCase): :return: None. """ self.app: Flask = create_test_app() + """The Flask application.""" with self.app.app_context(): from accounting.models import JournalEntry, JournalEntryLineItem JournalEntry.query.delete() JournalEntryLineItem.query.delete() self.encoded_next_uri: str = encode_next(NEXT_URI) + """The encoded next URI.""" self.client, self.csrf_token = get_client(self.app, "editor") @@ -1256,6 +1260,7 @@ class TransferJournalEntryTestCase(unittest.TestCase): :return: None. """ self.app: Flask = create_test_app() + """The Flask application.""" with self.app.app_context(): from accounting.models import JournalEntry, \ @@ -1263,6 +1268,7 @@ class TransferJournalEntryTestCase(unittest.TestCase): JournalEntry.query.delete() JournalEntryLineItem.query.delete() self.encoded_next_uri: str = encode_next(NEXT_URI) + """The encoded next URI.""" self.client, self.csrf_token = get_client(self.app, "editor") @@ -2128,12 +2134,14 @@ class JournalEntryReorderTestCase(unittest.TestCase): :return: None. """ self.app: Flask = create_test_app() + """The Flask application.""" with self.app.app_context(): from accounting.models import JournalEntry, JournalEntryLineItem JournalEntry.query.delete() JournalEntryLineItem.query.delete() self.encoded_next_uri: str = encode_next(NEXT_URI) + """The encoded next URI.""" self.client, self.csrf_token = get_client(self.app, "editor") diff --git a/tests/test_offset.py b/tests/test_offset.py index 81ee9d7..41b3bb7 100644 --- a/tests/test_offset.py +++ b/tests/test_offset.py @@ -46,15 +46,18 @@ class OffsetTestCase(unittest.TestCase): :return: None. """ self.app: Flask = create_test_app() + """The Flask application.""" with self.app.app_context(): from accounting.models import JournalEntry, JournalEntryLineItem JournalEntry.query.delete() JournalEntryLineItem.query.delete() self.encoded_next_uri: str = encode_next(NEXT_URI) + """The encoded next URI.""" self.client, self.csrf_token = get_client(self.app, "editor") self.data: OffsetTestData = OffsetTestData(self.app, "editor") + """The offset test data.""" self.data.populate() def test_add_receivable_offset(self) -> None: @@ -807,18 +810,22 @@ class OffsetTestData(BaseTestData): 50, [JournalEntryCurrencyData( "USD", [self.l_r_or1d, self.l_r_or4d], [self.l_r_or1c, self.l_r_or4c])]) + """The receivable original journal entry #1.""" self.j_r_or2: JournalEntryData = JournalEntryData( 30, [JournalEntryCurrencyData( "USD", [self.l_r_or2d, self.l_r_or3d], [self.l_r_or2c, self.l_r_or3c])]) + """The receivable original journal entry #2.""" self.j_p_or1: JournalEntryData = JournalEntryData( 40, [JournalEntryCurrencyData( "USD", [self.l_p_or1d, self.l_p_or4d], [self.l_p_or1c, self.l_p_or4c])]) + """The payable original journal entry #1.""" self.j_p_or2: JournalEntryData = JournalEntryData( 20, [JournalEntryCurrencyData( "USD", [self.l_p_or2d, self.l_p_or3d], [self.l_p_or2c, self.l_p_or3c])]) + """The payable original journal entry #2.""" self._add_journal_entry(self.j_r_or1) self._add_journal_entry(self.j_r_or2) @@ -863,23 +870,29 @@ class OffsetTestData(BaseTestData): self.j_r_of1: JournalEntryData = JournalEntryData( 25, [JournalEntryCurrencyData( "USD", [self.l_r_of1d], [self.l_r_of1c])]) + """The offset journal entry to the receivable #1.""" self.j_r_of2: JournalEntryData = JournalEntryData( 20, [JournalEntryCurrencyData( "USD", [self.l_r_of2d, self.l_r_of3d, self.l_r_of4d], [self.l_r_of2c, self.l_r_of3c, self.l_r_of4c])]) + """The offset journal entry to the receivable #2.""" self.j_r_of3: JournalEntryData = JournalEntryData( 15, [JournalEntryCurrencyData( "USD", [self.l_r_of5d], [self.l_r_of5c])]) + """The offset journal entry to the receivable #3.""" self.j_p_of1: JournalEntryData = JournalEntryData( 15, [JournalEntryCurrencyData( "USD", [self.l_p_of1d], [self.l_p_of1c])]) + """The offset journal entry to the payable #1.""" self.j_p_of2: JournalEntryData = JournalEntryData( 10, [JournalEntryCurrencyData( "USD", [self.l_p_of2d, self.l_p_of3d, self.l_p_of4d], [self.l_p_of2c, self.l_p_of3c, self.l_p_of4c])]) + """The offset journal entry to the payable #2.""" self.j_p_of3: JournalEntryData = JournalEntryData( 5, [JournalEntryCurrencyData( "USD", [self.l_p_of5d], [self.l_p_of5c])]) + """The offset journal entry to the payable #3.""" self._add_journal_entry(self.j_r_of1) self._add_journal_entry(self.j_r_of2) diff --git a/tests/test_option.py b/tests/test_option.py index 9946ad9..bad1798 100644 --- a/tests/test_option.py +++ b/tests/test_option.py @@ -41,11 +41,13 @@ class OptionTestCase(unittest.TestCase): :return: None. """ self.app: Flask = create_test_app() + """The Flask application.""" with self.app.app_context(): from accounting.models import Option Option.query.delete() self.encoded_next_uri: str = encode_next(NEXT_URI) + """The encoded next URI.""" self.client, self.csrf_token = get_client(self.app, "admin") diff --git a/tests/test_report.py b/tests/test_report.py index e391e56..ce5ec79 100644 --- a/tests/test_report.py +++ b/tests/test_report.py @@ -42,6 +42,7 @@ class ReportTestCase(unittest.TestCase): :return: None. """ self.app: Flask = create_test_app() + """The Flask application.""" with self.app.app_context(): from accounting.models import JournalEntry, JournalEntryLineItem diff --git a/tests/test_site/lib.py b/tests/test_site/lib.py index 2f925f2..ea460d2 100644 --- a/tests/test_site/lib.py +++ b/tests/test_site/lib.py @@ -57,13 +57,20 @@ class JournalEntryLineItemData: :param original_line_item: The original journal entry line item. """ self.journal_entry: JournalEntryData | None = None + """The journal entry data.""" self.id: int = -1 + """The journal entry line item ID.""" self.no: int = -1 + """The line item number under the journal entry and debit or credit.""" self.original_line_item: JournalEntryLineItemData | None \ = original_line_item + """The original journal entry line item.""" self.account: str = account + """The account code.""" self.description: str | None = description + """The description.""" self.amount: Decimal = Decimal(amount) + """The amount.""" def form(self, prefix: str, debit_credit: str, index: int, is_update: bool) -> dict[str, str]: @@ -101,8 +108,11 @@ class JournalEntryCurrencyData: :param credit: The credit line items. """ self.code: str = currency + """The currency code.""" self.debit: list[JournalEntryLineItemData] = debit + """The debit line items.""" self.credit: list[JournalEntryLineItemData] = credit + """The credit line items.""" def form(self, index: int, is_update: bool) -> dict[str, str]: """Returns the currency as form data. @@ -131,9 +141,13 @@ class JournalEntryData: :param currencies: The journal entry currency data. """ self.id: int = -1 + """The journal entry ID.""" self.days: int = days + """The number of days before today.""" self.currencies: list[JournalEntryCurrencyData] = currencies + """The journal entry currency data.""" self.note: str | None = None + """The note.""" for currency in self.currencies: for line_item in currency.debit: line_item.journal_entry = self @@ -190,13 +204,17 @@ class BaseTestData(ABC): :param username: The username. """ self._app: Flask = app + """The Flask application.""" with self._app.app_context(): current_user: User | None = User.query\ .filter(User.username == username).first() assert current_user is not None self.__current_user_id: int = current_user.id + """The current user ID.""" self.__journal_entries: list[dict[str, Any]] = [] + """The data of the journal entries.""" self.__line_items: list[dict[str, Any]] = [] + """The data of the journal entry line items.""" self._init_data() @abstractmethod diff --git a/tests/test_site/locale.py b/tests/test_site/locale.py index 202a50e..abf152c 100644 --- a/tests/test_site/locale.py +++ b/tests/test_site/locale.py @@ -26,6 +26,7 @@ from werkzeug.datastructures import LanguageAccept from accounting.utils.next_uri import or_next bp: Blueprint = Blueprint("locale", __name__, url_prefix="/") +"""The blueprint for the localization.""" def get_locale(): diff --git a/tests/test_site/reset.py b/tests/test_site/reset.py index 36c020c..72c7512 100644 --- a/tests/test_site/reset.py +++ b/tests/test_site/reset.py @@ -29,6 +29,7 @@ from .lib import Accounts, JournalEntryLineItemData, JournalEntryData, \ JournalEntryCurrencyData, BaseTestData bp: Blueprint = Blueprint("reset", __name__, url_prefix="/") +"""The blueprint for the data reset.""" @bp.get("reset", endpoint="reset-page") diff --git a/tests/test_unmatched_offset.py b/tests/test_unmatched_offset.py index 500b440..0f5c20f 100644 --- a/tests/test_unmatched_offset.py +++ b/tests/test_unmatched_offset.py @@ -42,12 +42,14 @@ class UnmatchedOffsetTestCase(unittest.TestCase): :return: None. """ self.app: Flask = create_test_app() + """The Flask application.""" with self.app.app_context(): from accounting.models import JournalEntry, JournalEntryLineItem JournalEntry.query.delete() JournalEntryLineItem.query.delete() self.encoded_next_uri: str = encode_next(NEXT_URI) + """The encoded next URI.""" self.client, self.csrf_token = get_client(self.app, "editor") @@ -410,18 +412,22 @@ class DifferentTestData(BaseTestData): 50, [JournalEntryCurrencyData( "USD", [self.l_r_or1d, self.l_r_or4d], [self.l_r_or1c, self.l_r_or4c])]) + """The receivable original journal entry #1.""" self.j_r_or2: JournalEntryData = JournalEntryData( 30, [JournalEntryCurrencyData( "USD", [self.l_r_or2d, self.l_r_or3d], [self.l_r_or2c, self.l_r_or3c])]) + """The receivable original journal entry #2""" self.j_p_or1: JournalEntryData = JournalEntryData( 40, [JournalEntryCurrencyData( "USD", [self.l_p_or1d, self.l_p_or4d], [self.l_p_or1c, self.l_p_or4c])]) + """The payable original journal entry #1.""" self.j_p_or2: JournalEntryData = JournalEntryData( 20, [JournalEntryCurrencyData( "USD", [self.l_p_or2d, self.l_p_or3d], [self.l_p_or2c, self.l_p_or3c])]) + """The payable original journal entry #2.""" self._add_journal_entry(self.j_r_or1) self._add_journal_entry(self.j_r_or2) @@ -456,23 +462,29 @@ class DifferentTestData(BaseTestData): self.j_r_of1: JournalEntryData = JournalEntryData( 25, [JournalEntryCurrencyData( "USD", [self.l_r_of1d], [self.l_r_of1c])]) + """The offset journal entry to the receivable #1.""" self.j_r_of2: JournalEntryData = JournalEntryData( 20, [JournalEntryCurrencyData( "USD", [self.l_r_of2d, self.l_r_of3d, self.l_r_of4d], [self.l_r_of2c, self.l_r_of3c, self.l_r_of4c])]) + """The offset journal entry to the receivable #2.""" self.j_r_of3: JournalEntryData = JournalEntryData( 15, [JournalEntryCurrencyData( "USD", [self.l_r_of5d], [self.l_r_of5c])]) + """The offset journal entry to the receivable #3.""" self.j_p_of1: JournalEntryData = JournalEntryData( 15, [JournalEntryCurrencyData( "USD", [self.l_p_of1d], [self.l_p_of1c])]) + """The offset journal entry to the payable #1.""" self.j_p_of2: JournalEntryData = JournalEntryData( 10, [JournalEntryCurrencyData( "USD", [self.l_p_of2d, self.l_p_of3d, self.l_p_of4d], [self.l_p_of2c, self.l_p_of3c, self.l_p_of4c])]) + """The offset journal entry to the payable #2.""" self.j_p_of3: JournalEntryData = JournalEntryData( 5, [JournalEntryCurrencyData( "USD", [self.l_p_of5d], [self.l_p_of5c])]) + """The offset journal entry to the payable #3.""" self._add_journal_entry(self.j_r_of1) self._add_journal_entry(self.j_r_of2) diff --git a/tests/test_utils.py b/tests/test_utils.py index 7b59b4e..a550941 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -41,6 +41,7 @@ class NextUriTestCase(unittest.TestCase): :return: None. """ self.app: Flask = create_test_app() + """The Flask application.""" def test_next_uri(self) -> None: """Tests the next URI utilities with the next URI. @@ -177,7 +178,7 @@ class PaginationTestCase(unittest.TestCase): """The test case for pagination.""" class Params: - """The testing parameters.""" + """The testing pagination parameters.""" def __init__(self, items: list[int], is_reversed: bool | None, result: list[int], is_paged: bool): @@ -189,9 +190,13 @@ class PaginationTestCase(unittest.TestCase): :param is_paged: Whether we need pagination. """ self.items: list[int] = items + """All the items in the list.""" self.is_reversed: bool | None = is_reversed + """Whether the default page is the last page.""" self.result: list[int] = result + """The expected items on the page.""" self.is_paged: bool = is_paged + """Whether we need pagination.""" def setUp(self) -> None: """Sets up the test. @@ -200,7 +205,9 @@ class PaginationTestCase(unittest.TestCase): :return: None. """ self.app: Flask = create_test_app() - self.params = self.Params([], None, [], True) + """The Flask application.""" + self.params: PaginationTestCase.Params = self.Params([], None, [], True) + """The testing pagination parameters.""" @self.app.get("/test-pagination") def test_pagination_view() -> str: @@ -215,7 +222,9 @@ class PaginationTestCase(unittest.TestCase): self.assertEqual(pagination.list, self.params.result) return "" - self.client = httpx.Client(app=self.app, base_url=TEST_SERVER) + self.client: httpx.Client = httpx.Client(app=self.app, + base_url=TEST_SERVER) + """The user client.""" self.client.headers["Referer"] = TEST_SERVER def __test_success(self, query: str, items: range,