text: /* ************************************************************************************************
   *                                                                                                *
   * Please read the following tutorial before implementing tasks:                                   *
   * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise       *
   *                                                                                                *
   ************************************************************************************************ */
  
  
  /**
   * Return Promise object that is resolved with string value === 'Hooray!!! She said "Yes"!',
   * if boolean value === true is passed, resolved with string value === 'Oh no, she said "No".',
   * if boolean value === false is passed, and rejected
   * with error message === 'Wrong parameter is passed! Ask her again.',
   * if is not boolean value passed
   *
   * @param {boolean} isPositiveAnswer
   * @return {Promise}
   *
   * @example
   *    const p1 = willYouMarryMe(true);
   *    p1.then(answer => console.log(answer)) // 'Hooray!!! She said "Yes"!'
   *
   *    const p2 = willYouMarryMe(false);
   *    p2.then(answer => console.log(answer)) // 'Oh no, she said "No".';
   *
   *    const p3 = willYouMarryMe();
   *    p3.then(answer => console.log(answer))
   *      .catch((error) => console.log(error.message)) // 'Error: Wrong parameter is passed!
   *                                                    //  Ask her again.';
   */
  
  function willYouMarryMe(isPositiveAnswer) {
    return new Promise((res, rej) => {
      if (typeof isPositiveAnswer !== 'boolean') rej(new Error('Wrong parameter is passed! Ask her again.'));
      if (isPositiveAnswer) res('Hooray!!! She said "Yes"!');
      else res('Oh no, she said "No".');
    });
  }
  
  /**
   * Return Promise object that should be resolved with array containing plain values.
   * Function receive an array of Promise objects.
   *
   * @param {Promise[]} array
   * @return {Promise}
   *
   * @example
   *    const promises = [Promise.resolve(1), Promise.resolve(3), Promise.resolve(12)]
   *    const p = processAllPromises(promises);
   *    p.then((res) => {
   *      console.log(res) // => [1, 2, 3]
   *    })
   *
   */
  function processAllPromises(array) {
    return Promise.all(array);
  }
  
  /**
   * Return Promise object that should be resolved with value received from
   * Promise object that will be resolved first.
   * Function receive an array of Promise objects.
   *
   * @param {Promise[]} array
   * @return {Promise}
   *
   * @example
   *    const promises = [
   *      Promise.resolve('first'),
   *      new Promise(resolve => setTimeout(() => resolve('second'), 500)),
   *    ];
   *    const p = processAllPromises(promises);
   *    p.then((res) => {
   *      console.log(res) // => [first]
   *    })
   *
   */
  function getFastestPromise(array) {
    return Promise.race(array);
  }
  
  /**
   * Return Promise object that should be resolved with value that is
   * a result of action with values of all the promises that exists in array.
   * If some of promise is rejected you should catch it and process the next one.
   *
   * @param {Promise[]} array
   * @param {Function} action
   * @return {Promise}
   *
   * @example
   *    const promises = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)];
   *    const p = chainPromises(promises, (a, b) => a + b);
   *    p.then((res) => {
   *      console.log(res) // => 6
   *    });
   *
   */
  
  function chainPromises(array, action) {
    return new Promise((resolve) => {
      const arr = [];
      array.forEach((p) => {
        p.then((res) => arr.push(res));
      });
      resolve(arr);
    }).then((result) => result.reduce((acc, cur) => {
      const final = action(acc, cur);
      return final;
    }), 0);
  }
  
  module.exports = {
    willYouMarryMe,
    processAllPromises,
    getFastestPromise,
    chainPromises,
  };
  