import type { Answerable } from '../Answerable';
import type { QuestionAdapter } from '../Question';
import type { MetaQuestion } from './MetaQuestion';
/**
 * Provides methods to perform calculations on numeric values returned by other [questions](https://serenity-js.org/api/core/class/Question/).
 *
 * ## Example
 *
 * The examples in this section demonstrate interacting with an HTML widget representing a price list.
 *
 * ```html
 * <ul id="price-list">
 *     <li class="item">
 *         <span class="name">apples</span>
 *         <span class="quantity">5</span>
 *         <span class="price">£2.25</span>
 *     </li>
 *     <li class="item">
 *         <span class="name">apricots</span>
 *         <span class="quantity">4</span>
 *         <span class="price">£3.70</span>
 *     </li>
 *     <li class="item">
 *         <span class="name">bananas</span>
 *         <span class="quantity">2</span>
 *         <span class="price">£1.50</span>
 *     </li>
 * </ul>
 * ```
 *
 * ### Lean Page Objects
 *
 * To represent our example HTML widget,
 * we follow the [Lean Page Objects pattern](https://serenity-js.org/handbook/web-testing/page-objects-pattern/)
 * to define the `PriceList` and `PriceListItem` classes
 * and use the Serenity/JS [Page Element Query Language (PEQL)](https://serenity-js.org/handbook/web-testing/page-element-query-language/)
 * to identify the elements of interest.
 *
 * ```ts
 * // ui/price-list.ts
 *
 * import { PageElement, PageElements, By } from '@serenity-js/web'
 *
 * export class PriceList {
 *   static container = () =>
 *      PageElement.located(By.id('price-list'))
 *          .describedAs('price list')
 *
 *   static items = () =>
 *      PageElements.located(PriceListItem.containerSelector())
 *          .of(this.container())
 *          .describedAs('items')
 * }
 *
 * export class PriceListItem {
 *   static containerSelector = () =>
 *     By.css('.item')
 *
 *   static container = () =>
 *     PageElement.located(this.containerSelector())
 *       .describedAs('item')
 *
 *   static name = () =>
 *     PageElement.located(By.css('.name'))
 *       .of(this.container())
 *       .describedAs('name')
 *
 *   static quantity = () =>
 *     PageElement.located(By.css('.quantity'))
 *       .of(this.container())
 *       .describedAs('quantity')
 *
 *   static price = () =>
 *     PageElement.located(By.css('.price'))
 *       .of(this.container())
 *       .describedAs('price')
 * }
 * ```
 *
 * @group Questions
 */
export declare class Numeric {
    /**
     * Returns a [`Question`](https://serenity-js.org/api/core/class/Question/) that sums up the values provided
     * and throws if any of the values is not a `number`.
     *
     * #### Adding static numbers
     *
     * The most basic example of using the `Numeric.sum` method is to add up a few numbers.
     *
     * ```ts
     * import { actorCalled, Numeric } from '@serenity-js/core'
     * import { Ensure, equals } from '@serenity-js/assertions'
     *
     * await actorCalled('Zoé').attemptsTo(
     *   Ensure.that(
     *     Numeric.sum(1, 2, 3),
     *     equals(6),
     *   )
     * )
     * ```
     *
     * The numbers can be provided individually, as an array, or as a combination of both.
     *
     * ```ts
     * import { actorCalled, Numeric } from '@serenity-js/core'
     * import { Ensure, equals } from '@serenity-js/assertions'
     *
     * await actorCalled('Zoé').attemptsTo(
     *   Ensure.that(
     *     Numeric.sum([ 1, 2 ], 3, [ 4, 5 ]),
     *     equals(15),
     *   )
     * )
     * ```
     *
     * #### Adding numbers returned by other questions
     *
     * Apart from adding static numbers, you can also add numbers returned by other questions.
     * This is particularly useful when you need to calculate the sum of numbers extracted from a list of UI elements
     * or from an API response.
     *
     * ```ts
     * import { actorCalled, Numeric, Question } from '@serenity-js/core'
     * import { Ensure, equals } from '@serenity-js/assertions'
     *
     * const myNumber = () =>
     *   Question.about('my number', actor => 42)
     *
     * const myArrayOfNumbers = () =>
     *   Question.about('my array of numbers', actor => [ 1, 2, 3 ])
     *
     * const myObjectWithNumbers = () =>
     *   Question.about('my object with numbers', actor => ({ a: 1, b: 2, c: 3 }))
     *
     * await actorCalled('Zoé').attemptsTo(
     *   Ensure.that(
     *     Numeric.sum(
     *       myNumber(),            // a question returning a number
     *       myArrayOfNumbers(),    // a question returning an array of numbers
     *     ),
     *     equals(48),
     *   ),
     *   Ensure.that(
     *     Numeric.sum(
     *       myObjectWithNumbers()  // a question returning an object with numbers
     *          .as(Object.values), // from which we extract the numeric values
     *     ),
     *     equals(6),
     *   ),
     * )
     * ```
     *
     * Of course, you can also mix and match static numbers with numbers returned by questions.
     *
     * ```ts
     * import { actorCalled, Numeric, Question } from '@serenity-js/core'
     * import { Ensure, equals } from '@serenity-js/assertions'
     *
     * const myObjectWithNumbers = () =>
     *   Question.about('my object with numbers', actor => ({ a: 1, b: 2, c: 3 }))
     *
     * await actorCalled('Zoé').attemptsTo(
     *   Ensure.that(
     *     Numeric.sum(
     *       myObjectWithNumbers().as(Object.values),
     *       [ 4, 5 ],
     *       6,
     *     ),
     *     equals(21),
     *   ),
     * )
     * ```
     *
     * #### Adding numbers extracted from a UI
     *
     * To add numbers extracted from a UI:
     * - use the [`PageElement`](https://serenity-js.org/api/web/class/PageElement) and [`PageElements`](https://serenity-js.org/api/web/class/PageElements) classes to identify the elements of interest,
     * - use the [`Text.of`](https://serenity-js.org/api/web/class/Text/) or [`Text.ofAll`](https://serenity-js.org/api/web/class/Text/) questions to extract the text of the element or elements,
     * - and then interpret this text as number using either the [`.as(Number)`](https://serenity-js.org/api/core/class/Question/#as) mapping function,
     *   or the [`Numeric.intValue()`](https://serenity-js.org/api/core/class/Numeric/#intValue) or [`Numeric.floatValue()`](https://serenity-js.org/api/core/class/Numeric/#floatValue) meta-questions.
     *
     * For example, we could calculate the sum of quantities of items in our example price list by specifying each element explicitly
     * and mapping its text to [`Number`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number):
     *
     * ```ts
     * import { actorCalled, Numeric } from '@serenity-js/core'
     * import { Ensure, equals } from '@serenity-js/assertions'
     * import { Text } from '@serenity-js/web'
     * import { PriceList, PriceListItem } from './ui/price-list'
     *
     * await actorCalled('Zoé').attemptsTo(
     *   Ensure.that(
     *     Numeric.sum(
     *       Text.of(PriceListItem.quantity().of(PriceList.items().first())).as(Number),
     *       Text.of(PriceListItem.quantity().of(PriceList.items().at(1))).as(Number),
     *       Text.of(PriceListItem.quantity().of(PriceList.items().last())).as(Number),
     *     ),
     *     equals(11),
     *   ),
     * )
     * ```
     *
     * A more elegant approach would be to use the Serenity/JS [Page Element Query Language (PEQL)](https://serenity-js.org/handbook/web-testing/page-element-query-language/#mapping-page-elements-in-a-collection)
     * to map each item in the collection to its quantity and then calculate the sum.
     *
     * ```ts
     * import { actorCalled, Numeric } from '@serenity-js/core'
     * import { Ensure, equals } from '@serenity-js/assertions'
     * import { Text } from '@serenity-js/web'
     * import { PriceList, PriceListItem } from './ui/price-list'
     *
     * await actorCalled('Zoé').attemptsTo(
     *   Ensure.that(
     *     Numeric.sum(
     *       PriceList.items()                      // get all the li.item elements
     *         .eachMappedTo(
     *           Text.of(PriceListItem.quantity())  // extract the text of the .quantity element
     *         )
     *         .eachMappedTo(                       // interpret the quantity as an integer value
     *           Numeric.intValue(),
     *         ),
     *     ),
     *     equals(11),                              // 5 apples, 4 apricots, 2 bananas
     *   )
     * )
     * ```
     *
     * Using PEQL allows us to express the intent more concisely and, for example,
     * introduce helper functions that limit the scope of the operation to a subset of elements.
     *
     * ```ts
     * import { actorCalled, Expectation, Numeric, the } from '@serenity-js/core'
     * import { Ensure, equals, startsWith } from '@serenity-js/assertions'
     * import { PriceList, PriceListItem } from './ui/price-list'
     *
     * const quantitiesOfItemsWhichName = (expectation: Expectation<string>) =>
     *   PriceList.items()                      // get all the li.item elements
     *     .where(                              // leave only those which name matches the expectation
     *        Text.of(PriceListItem.name()),
     *        expectation
     *     )
     *     .eachMappedTo(
     *       Text.of(PriceListItem.quantity())  // extract the text of the .quantity element
     *     )
     *     .eachMappedTo(                       // interpret the quantity as an integer value
     *       Numeric.intValue(),
     *     )
     *     .describedAs(the`quantities of items which name does ${ expectation }`)
     *
     * await actorCalled('Zoé').attemptsTo(
     *   Ensure.that(
     *     Numeric.sum(
     *       quantitiesOfItemsWhichName(startsWith('ap')),  // apples and apricots
     *     ),
     *     equals(9),                                       // 5 apples, 4 apricots
     *   )
     * )
     * ```
     *
     * #### Learn more
     *
     * View the [`Numeric` API documentation](https://serenity-js.org/api/core/class/Numeric) for more details
     * and examples.
     *
     * @param values
     */
    static sum(...values: Array<Answerable<number | number[]>>): QuestionAdapter<number>;
    /**
     * Returns a [`Question`](https://serenity-js.org/api/core/class/Question/)  that calculates the difference between
     * two numbers and throws if any of the values is not a `number`.
     *
     * #### Subtracting numbers
     *
     * ```ts
     * import { actorCalled, Numeric } from '@serenity-js/core'
     * import { Ensure, equals } from '@serenity-js/assertions'
     * import { Text } from '@serenity-js/web'
     * import { PriceList, PriceListItem } from './ui/price-list'
     *
     * await actorCalled('Zoé').attemptsTo(
     *   Ensure.that(
     *     Numeric.difference(
     *       Text.of(PriceListItem.quantity().of(PriceList.items().first())).as(Number),    // 5 (apples)
     *       2,                                                                             // - 2
     *     ),
     *     equals(3),
     *   ),
     * )
     * ```
     *
     * #### Learn more
     *
     * View the [`Numeric` API documentation](https://serenity-js.org/api/core/class/Numeric) for more details
     * and examples.
     *
     * @param minuend
     * @param subtrahend
     */
    static difference(minuend: Answerable<number>, subtrahend: Answerable<number>): QuestionAdapter<number>;
    /**
     * Returns a [`MetaQuestion`](https://serenity-js.org/api/core/interface/MetaQuestion/) that calculates
     * the ceiling of a number and throws if the value is not a `number`.
     *
     * #### Calculating the ceiling of a number
     *
     * ```ts
     * import { actorCalled, Numeric } from '@serenity-js/core'
     * import { Ensure, equals } from '@serenity-js/assertions'
     * import { Text } from '@serenity-js/web'
     * import { PriceList, PriceListItem } from './ui/price-list'
     *
     * await actorCalled('Zoé').attemptsTo(
     *   Ensure.that(
     *     Numeric.ceiling().of(
     *       Text.of(PriceListItem.price().of(PriceList.items().first()))   // '£2.25' (apples)
     *          .replace('£', '')                                           // '2.25'
     *          .as(Number.parseFloat),                                     // 2.25
     *     ),
     *     equals(3),
     *   ),
     * )
     * ```
     *
     * #### Learn more
     *
     * View the [`Numeric` API documentation](https://serenity-js.org/api/core/class/Numeric) for more details
     * and examples.
     */
    static ceiling(): MetaQuestion<number, QuestionAdapter<number>>;
    /**
     * Returns a [`MetaQuestion`](https://serenity-js.org/api/core/interface/MetaQuestion/) that calculates
     * the floor of a number and throws if the value is not a `number`.
     *
     * #### Calculating the floor of a number
     *
     * ```ts
     * import { actorCalled, Numeric } from '@serenity-js/core'
     * import { Ensure, equals } from '@serenity-js/assertions'
     * import { Text } from '@serenity-js/web'
     * import { PriceList, PriceListItem } from './ui/price-list'
     *
     * await actorCalled('Zoé').attemptsTo(
     *   Ensure.that(
     *     Numeric.floor().of(
     *       Text.of(PriceListItem.price().of(PriceList.items().first()))   // '£2.25' (apples)
     *          .replace('£', '')                                           // '2.25'
     *          .as(Number.parseFloat),                                     // 2.25
     *     ),
     *     equals(2),
     *   ),
     * )
     * ```
     *
     * #### Learn more
     *
     * View the [`Numeric` API documentation](https://serenity-js.org/api/core/class/Numeric) for more details
     * and examples.
     */
    static floor(): MetaQuestion<number, QuestionAdapter<number>>;
    /**
     * Returns a [`Question`](https://serenity-js.org/api/core/class/Question/) that calculates
     * the maximum value in the lists of numbers provided and throws if any of the values is not a `number`.
     *
     * #### Calculating the maximum value
     *
     * ```ts
     * import { actorCalled, Numeric } from '@serenity-js/core'
     * import { Ensure, equals } from '@serenity-js/assertions'
     * import { Text } from '@serenity-js/web'
     * import { PriceList, PriceListItem } from './ui/price-list'
     *
     * await actorCalled('Zoé').attemptsTo(
     *   Ensure.that(
     *     Numeric.max(
     *       PriceList.items()                      // get all the li.item elements
     *         .eachMappedTo(
     *           Text.of(PriceListItem.quantity())  // extract the text of the .quantity element
     *         )
     *         .eachMappedTo(                       // interpret the quantity as an integer value
     *           Numeric.intValue(),
     *         ),
     *     ),
     *     equals(5),                               // 5 (apples)
     *   )
     * )
     * ```
     *
     * #### Learn more
     *
     * View the [`Numeric` API documentation](https://serenity-js.org/api/core/class/Numeric) for more details
     * and examples.
     *
     * @param values
     */
    static max(...values: Array<Answerable<number | number[]>>): QuestionAdapter<number>;
    /**
     * Returns a [`Question`](https://serenity-js.org/api/core/class/Question/) that calculates
     * the minimum value in the lists of numbers provided and throws if any of the values is not a `number`.
     *
     * #### Calculating the minimum value
     *
     * ```ts
     * import { actorCalled, Numeric } from '@serenity-js/core'
     * import { Ensure, equals } from '@serenity-js/assertions'
     * import { Text } from '@serenity-js/web'
     * import { PriceList, PriceListItem } from './ui/price-list'
     *
     * await actorCalled('Zoé').attemptsTo(
     *   Ensure.that(
     *     Numeric.min(
     *       PriceList.items()                      // get all the li.item elements
     *         .eachMappedTo(
     *           Text.of(PriceListItem.quantity())  // extract the text of the .quantity element
     *         )
     *         .eachMappedTo(                       // interpret the quantity as an integer value
     *           Numeric.intValue(),
     *         ),
     *     ),
     *     equals(2),                               // 2 (bananas)
     *   )
     * )
     * ```
     *
     * #### Learn more
     *
     * View the [`Numeric` API documentation](https://serenity-js.org/api/core/class/Numeric) for more details
     * and examples.
     *
     * @param values
     */
    static min(...values: Array<Answerable<number | number[]>>): QuestionAdapter<number>;
    /**
     * Returns a [`MetaQuestion`](https://serenity-js.org/api/core/interface/MetaQuestion/) that parses a string `value`
     * and returns an integer of the specified `base`.
     * Leading whitespace in the value to parse argument is ignored.
     *
     * #### Parsing a string as an integer
     *
     * ```ts
     * import { actorCalled, Numeric } from '@serenity-js/core'
     * import { Ensure, equals } from '@serenity-js/assertions'
     * import { Text } from '@serenity-js/web'
     * import { PriceList, PriceListItem } from './ui/price-list'
     *
     * await actorCalled('Zoé').attemptsTo(
     *   Ensure.that(
     *     Numeric.intValue().of(
     *       Text.of(                           // '5' (apples)
     *         PriceListItem.quantity().of(
     *           PriceList.items().first()
     *         )
     *       )
     *     ),
     *     equals(5),
     *   ),
     * )
     * ```
     *
     * #### Learn more
     *
     * View the [`Numeric` API documentation](https://serenity-js.org/api/core/class/Numeric) for more details
     * and examples.
     *
     * @param base
     *  An integer between 2 and 36 that represents the base in mathematical numeral systems of the string.
     *  If base is undefined or 0, it is assumed to be 10 except when the number begins with the code unit pairs 0x or 0X, in which case a radix of 16 is assumed.
     */
    static intValue(base?: Answerable<number>): MetaQuestion<string, QuestionAdapter<number>>;
    /**
     * Returns a [`MetaQuestion`](https://serenity-js.org/api/core/interface/MetaQuestion/) that parses a string `value`
     * and returns a [`BigInt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt).
     * Leading whitespace in the value to parse argument is ignored.
     *
     * #### Parsing a string as a bigint
     *
     * ```ts
     * import { actorCalled, Numeric } from '@serenity-js/core'
     * import { Ensure, equals } from '@serenity-js/assertions'
     * import { Text } from '@serenity-js/web'
     * import { PriceList, PriceListItem } from './ui/price-list'
     *
     * await actorCalled('Zoé').attemptsTo(
     *   Ensure.that(
     *     Numeric.bigIntValue().of(
     *       Text.of(                                                  // '5' (apples)
     *         PriceListItem.quantity().of(PriceList.items().first())
     *       )
     *     ),
     *     equals(BigInt('5')),
     *   ),
     * )
     * ```
     *
     * #### Learn more
     *
     * View the [`Numeric` API documentation](https://serenity-js.org/api/core/class/Numeric) for more details
     * and examples.
     */
    static bigIntValue(): MetaQuestion<string, QuestionAdapter<bigint>>;
    /**
     * Returns a [`MetaQuestion`](https://serenity-js.org/api/core/interface/MetaQuestion/) that parses a string `value`
     * and returns a floating-point number.
     *
     * #### Parsing a string as a floating point number
     *
     * ```ts
     * import { actorCalled, Numeric } from '@serenity-js/core'
     * import { Ensure, equals } from '@serenity-js/assertions'
     * import { Text } from '@serenity-js/web'
     * import { PriceList, PriceListItem } from './ui/price-list'
     *
     * await actorCalled('Zoé').attemptsTo(
     *   Ensure.that(
     *     Numeric.floatValue().of(
     *       Text.of(                                                  // '£2.25'
     *           PriceListItem.price().of(PriceList.items().first())
     *       ).replace('£', '')                                        // '2.25'
     *     ),
     *     equals(2.25),
     *   ),
     * )
     * ```
     *
     * #### Learn more
     *
     * View the [`Numeric` API documentation](https://serenity-js.org/api/core/class/Numeric) for more details
     * and examples.
     */
    static floatValue(): MetaQuestion<string, QuestionAdapter<number>>;
    private static flatten;
    private static descriptionOf;
}
//# sourceMappingURL=Numeric.d.ts.map