<commit_before>angular.module('leukemiapp').controller('painController', PainController);

function PainController($scope, $reactive, $ionicScrollDelegate) {
   $reactive(this).attach($scope);
   var vm = this;

   //Init
   vm.registration = Session.get('registration');

   if (vm.registration.flaccvalue === undefined) {
      vm.registration.flaccvalue = [undefined, undefined, undefined, undefined, undefined];
      vm.registration.painScore = 0;
   }
   //vm.selectedSmiley;
   vm.show = true;
   vm.painScale = 'FLACC skala';
   validateData();

   vm.helpers({
      isSmallScreen: () => {
         return window.innerWidth < 768;
      }
   });

   function validateMorphine() {
      var isValidMorphine = true;
      console.log('registration.morphineType: ', vm.registration.morphineType);
      if (vm.registration.morphineType !== undefined) { //if there is a selected morphine type
         // check there is valid dose
         console.log(vm.registration.morphineDose);
         if (vm.registration.morphineDose === undefined || vm.registration.morphineDose == null || vm.registration.morphineDose < 0)
            isValidMorphine = false;
      } else { //if there is no selected morphine type
         // check if there is valid dose
         // to avoid confusion, if there is valid dose but no valid type do not validate until type is chosen or dose deleted
         console.log('registration.morphineDose: ', vm.registration.morphineDose, 'when vm.registration.morphineType === undefined');
         if (vm.registration.morphineDose != null) {
            isValidMorphine = false;
         }
      }
      return isValidMorphine;
   }

   function validateData() {
      var validated = Session.get('regValidated');
      if (validated === undefined)
         validated = [];
      validated[0] = vm.registration.timestamp !== undefined;
      validated[1] = validateMorphine();
      validated[2] = vm.registration.painType !== undefined;
      validated[3] = (vm.registration.flaccvalue != null &&
         vm.registration.flaccvalue[0] != null &&
         vm.registration.flaccvalue[1] != null &&
         vm.registration.flaccvalue[2] != null &&
         vm.registration.flaccvalue[3] != null &&
         vm.registration.flaccvalue[4] != null) || (vm.selectedSmiley != null);
      Session.set('regValidated', validated);
      console.log('regValidated session variable updated: ', validated);
      console.log('validated[3] part one: ', vm.registration.flaccvalue);
      console.log('validated[3] part two: ', vm.selectedSmiley);
   }

   vm.updateRegistration = () => {
      validateData();

      Session.set('registration', vm.registration);
      console.log('Registration updated');
      console.log(vm.registration);
   };

   vm.selectPainType = (value) => {
      vm.registration.painType = value;
      vm.updateRegistration();
   };

   //flacc selection
   vm.selectFlacc = function (flaccnumber, newvalue) {
      if (vm.registration.painScore === undefined) {
         vm.registration.painScore = 0;
      } else if (vm.registration.flaccvalue[flaccnumber] !== undefined) {
         vm.registration.painScore -= vm.registration.flaccvalue[flaccnumber];
      }
      vm.registration.flaccvalue[flaccnumber] = newvalue;
      vm.registration.painScore += newvalue;
      vm.updateRegistration();
   };

   vm.changeScale = () => {
      vm.show = !vm.show;
      vm.show ? vm.painScale = 'FLACC skala' : vm.painScale = 'Wong-Baker skala';
      vm.registration.painScore = 0;
      vm.selectedSmiley = undefined;
      vm.registration.flaccvalue = [undefined, undefined, undefined, undefined, undefined];
      vm.smileyDescription = "";
      $ionicScrollDelegate.resize();
      $ionicScrollDelegate.$getByHandle('smiley-scroll').scrollTop();
   };

   vm.smileySliderChanged = () => {
      var painScore = vm.registration.painScore;
      if (painScore % 2 == 0) {
         vm.selectSmiley(parseInt(painScore));
      }
      vm.updateRegistration();
   };

   //smiley selection
   vm.selectedSmiley = undefined;
   vm.smileyDescription = "";

   vm.selectSmiley = (smileynumber) => {
      console.log('smileynumber is: ', smileynumber);
      vm.selectedSmiley = smileynumber;
      vm.registration.painScore = smileynumber;
      switch (smileynumber) {
         case 0:
            vm.smileyDescription = "Man kan gøre fuldstændig, som man plejer uden at tænke på, at det gør ondt.";
            break;
         case 2:
            vm.smileyDescription = "Man kan gøre, som man plejer, men af og til må man standse op, fordi det gør ondt.";
            break;
         case 4:
            vm.smileyDescription = "Man har mest lyst til at sidde stille og få læst en historie eller se fjernsyn, fordi det gør ondt.";
            break;
         case 6:
            vm.smileyDescription = "Man tænker på, at det gør ondt hele tiden.";
            break;
         case 8:
            vm.smileyDescription = "Man har så ondt, at man har lyst til at græde, fordi det gør ondt.";
            break;
         case 10:
            vm.smileyDescription = "Man har så ondt, at man slet ikke kan holde det ud."
            break;
         default:
            vm.smileyDescription = "";
      }
      if (vm.isSmallScreen) {
         var smileyWidth = 130;
         var currentX = $ionicScrollDelegate.$getByHandle('smiley-scroll').getScrollPosition().left;
         var threshold = smileyWidth * 3;
         var x = vm.registration.painScore / 2 * smileyWidth;
         console.log('currentX: ', currentX, 'threshold: ', threshold, 'x: ', x);
         if (x < currentX || x >= threshold + currentX) {
            $ionicScrollDelegate.$getByHandle('smiley-scroll').scrollTo(x, 0, true);
         }
      }
      vm.updateRegistration();
   };
}<commit_msg>Minor change to previous commit<commit_after>angular.module('leukemiapp').controller('painController', PainController);

function PainController($scope, $reactive, $ionicScrollDelegate) {
   $reactive(this).attach($scope);
   var vm = this;

   //Init
   vm.registration = Session.get('registration');

   if (vm.registration.flaccvalue === undefined) {
      vm.registration.flaccvalue = [undefined, undefined, undefined, undefined, undefined];
      vm.registration.painScore = 0;
   }
   //vm.selectedSmiley;
   vm.show = true;
   vm.painScale = 'FLACC score';
   validateData();

   vm.helpers({
      isSmallScreen: () => {
         return window.innerWidth < 768;
      }
   });

   function validateMorphine() {
      var isValidMorphine = true;
      console.log('registration.morphineType: ', vm.registration.morphineType);
      if (vm.registration.morphineType !== undefined) { //if there is a selected morphine type
         // check there is valid dose
         console.log(vm.registration.morphineDose);
         if (vm.registration.morphineDose === undefined || vm.registration.morphineDose == null || vm.registration.morphineDose < 0)
            isValidMorphine = false;
      } else { //if there is no selected morphine type
         // check if there is valid dose
         // to avoid confusion, if there is valid dose but no valid type do not validate until type is chosen or dose deleted
         console.log('registration.morphineDose: ', vm.registration.morphineDose, 'when vm.registration.morphineType === undefined');
         if (vm.registration.morphineDose != null) {
            isValidMorphine = false;
         }
      }
      return isValidMorphine;
   }

   function validateData() {
      var validated = Session.get('regValidated');
      if (validated === undefined)
         validated = [];
      validated[0] = vm.registration.timestamp !== undefined;
      validated[1] = validateMorphine();
      validated[2] = vm.registration.painType !== undefined;
      validated[3] = (vm.registration.flaccvalue != null &&
         vm.registration.flaccvalue[0] != null &&
         vm.registration.flaccvalue[1] != null &&
         vm.registration.flaccvalue[2] != null &&
         vm.registration.flaccvalue[3] != null &&
         vm.registration.flaccvalue[4] != null) || (vm.selectedSmiley != null);
      Session.set('regValidated', validated);
      console.log('regValidated session variable updated: ', validated);
      console.log('validated[3] part one: ', vm.registration.flaccvalue);
      console.log('validated[3] part two: ', vm.selectedSmiley);
   }

   vm.updateRegistration = () => {
      validateData();

      Session.set('registration', vm.registration);
      console.log('Registration updated');
      console.log(vm.registration);
   };

   vm.selectPainType = (value) => {
      vm.registration.painType = value;
      vm.updateRegistration();
   };

   //flacc selection
   vm.selectFlacc = function (flaccnumber, newvalue) {
      if (vm.registration.painScore === undefined) {
         vm.registration.painScore = 0;
      } else if (vm.registration.flaccvalue[flaccnumber] !== undefined) {
         vm.registration.painScore -= vm.registration.flaccvalue[flaccnumber];
      }
      vm.registration.flaccvalue[flaccnumber] = newvalue;
      vm.registration.painScore += newvalue;
      vm.updateRegistration();
   };

   vm.changeScale = () => {
      vm.show = !vm.show;
      vm.show ? vm.painScale = 'FLACC score' : vm.painScale = 'Wong-Baker score';
      vm.registration.painScore = 0;
      vm.selectedSmiley = undefined;
      vm.registration.flaccvalue = [undefined, undefined, undefined, undefined, undefined];
      vm.smileyDescription = "";
      $ionicScrollDelegate.resize();
      $ionicScrollDelegate.$getByHandle('smiley-scroll').scrollTop();
   };

   vm.smileySliderChanged = () => {
      var painScore = vm.registration.painScore;
      if (painScore % 2 == 0) {
         vm.selectSmiley(parseInt(painScore));
      }
      vm.updateRegistration();
   };

   //smiley selection
   vm.selectedSmiley = undefined;
   vm.smileyDescription = "";

   vm.selectSmiley = (smileynumber) => {
      console.log('smileynumber is: ', smileynumber);
      vm.selectedSmiley = smileynumber;
      vm.registration.painScore = smileynumber;
      switch (smileynumber) {
         case 0:
            vm.smileyDescription = "Man kan gøre fuldstændig, som man plejer uden at tænke på, at det gør ondt.";
            break;
         case 2:
            vm.smileyDescription = "Man kan gøre, som man plejer, men af og til må man standse op, fordi det gør ondt.";
            break;
         case 4:
            vm.smileyDescription = "Man har mest lyst til at sidde stille og få læst en historie eller se fjernsyn, fordi det gør ondt.";
            break;
         case 6:
            vm.smileyDescription = "Man tænker på, at det gør ondt hele tiden.";
            break;
         case 8:
            vm.smileyDescription = "Man har så ondt, at man har lyst til at græde, fordi det gør ondt.";
            break;
         case 10:
            vm.smileyDescription = "Man har så ondt, at man slet ikke kan holde det ud."
            break;
         default:
            vm.smileyDescription = "";
      }
      if (vm.isSmallScreen) {
         var smileyWidth = 130;
         var currentX = $ionicScrollDelegate.$getByHandle('smiley-scroll').getScrollPosition().left;
         var threshold = smileyWidth * 3;
         var x = vm.registration.painScore / 2 * smileyWidth;
         console.log('currentX: ', currentX, 'threshold: ', threshold, 'x: ', x);
         if (x < currentX || x >= threshold + currentX) {
            $ionicScrollDelegate.$getByHandle('smiley-scroll').scrollTo(x, 0, true);
         }
      }
      vm.updateRegistration();
   };
}<|endoftext|>


<commit_before>import moment from "moment";

export function closestByClass(element, className) {
	while (!element.classList || !element.classList.contains(className)) {
		element = element.parentNode;
		if (!element) {
			return null;
		}
	}

	return element;
};

export function relativeDate(due) {
	var dueText = due.calendar().split(" at ")[0];
	var daysTo = Math.ceil(due.diff(moment()) / 1000 / 60 / 60 / 24);

	if (dueText.indexOf(" ") > -1) {
		dueText = dueText[0].toLowerCase() + dueText.substr(1);
	}

	if (daysTo > 7 && daysTo < 14) {
		dueText = "a week from " + due.format("dddd");
	} else if (daysTo == 7) {
		dueText = "a week from today";
	}

	return dueText;
};<commit_msg>dashboard: say "a week from tomorrow" instead of day name<commit_after>import moment from "moment";

export function closestByClass(element, className) {
	while (!element.classList || !element.classList.contains(className)) {
		element = element.parentNode;
		if (!element) {
			return null;
		}
	}

	return element;
};

export function relativeDate(due) {
	var dueText = due.calendar().split(" at ")[0];
	var daysTo = Math.ceil(due.diff(moment()) / 1000 / 60 / 60 / 24);

	if (dueText.indexOf(" ") > -1) {
		dueText = dueText[0].toLowerCase() + dueText.substr(1);
	}

	if (daysTo > 8 && daysTo < 14) {
		dueText = "a week from " + due.format("dddd");
	} else if (daysTo == 8) {
		dueText = "a week from tomorrow";
	} else if (daysTo == 7) {
		dueText = "a week from today";
	}

	return dueText;
};<|endoftext|>


<commit_before>/**
 * Block-Element-Modifier (BEM) builder.
 *
 * Created by Serhii Maksymchuk from Ubrainians for imCode
 * 24.07.17.
 */

const $ = require('jquery');

const MODIFIER_SEPARATOR = "--";
const BLOCK_SEPARATOR = "__";

function getOriginClass(attributesObj) {
    return attributesObj["class"] ? " " + attributesObj["class"] : "";
}

function getElementClassWithModifiers(elementClass, modifiersArr) {
    return elementClass + getModifiersClass(elementClass, modifiersArr);
}

function getModifiersClass(baseClass, modifiersArr) {
    let modifiers = "";

    (modifiersArr || []).forEach(function (modifier) {
        modifiers += " " + baseClass + MODIFIER_SEPARATOR + modifier;
    });

    return modifiers;
}

function createBlocKElement(element, elementName) {
    const blockElement = {};
    this.elements[elementName] = element["class"] || "";

    if (element.modifiers) {
        blockElement.modifiers = element.modifiers;
    }

    blockElement[elementName] = (element.length) // means jquery, not simple array
        ? element
        : this.buildElement(elementName, element.tag, element.attributes, element.modifiers);

    return blockElement;
}

function createBlockElements(elements, elementName) {
    return elements.map(function (element) {
        return createBlocKElement.call(this, element, elementName);
    }.bind(this));
}

module.exports = class BemBuilder {
    constructor(options) {
        this.elements = options.elements;
        this.block = options.block;
    };

    /**
     * Build BEM-styled class with needed separators
     *
     * Usage:
     *

     *     var bemClass = BEM.buildClass("one", "two", "three"); // = "one__two--three"
     *

     *
     * @param block {null|string}
     * @param element {null|string?}
     * @param modifier {string?}
     * @returns {string} BEM-styled class
     */
    static buildClass(block, element, modifier) {
        modifier = (modifier) ? MODIFIER_SEPARATOR + modifier : "";
        element = (block && element) ? BLOCK_SEPARATOR + element : (element) ? element : "";
        block = (block || "");
        return block + element + modifier;
    }

    /**
     * Build selector for BEM-styled class
     *
     * Usage:
     *

     *     var bemClassSelector = BEM.buildClassSelector("one", "two", "three"); // = ".one__two--three"
     *

     *
     * @param block {*|string}
     * @param element {null|string?}
     * @param modifier {string?}
     * @returns {string} selector for BEM-styled class
     */
    static buildClassSelector(block, element, modifier) {
        return "." + this.buildClass.apply(this, arguments);
    };

    /**
     * Adds BEM-styled class to element
     *
     * Usage:
     *

     *     var exampleBEM = new BEM({
     *          block: "the-block",
     *          elements: {
     *              "some-element": "some-element-class"
     *          }
     *     });
     *     var $element = exampleBEM.makeBlockElement("some-element", $(".some-class"), ["mod-1", "mod-2"]);
     *     // $element will have class "the-block__some-element the-block__some-element--mod-1 the-block__some-element--mod-2"
     *

     *
     * @param elementName {string} name of element in current BEM-builder
     * @param $baseElement {object} jquery-element to be modified
     * @param modifiersArr {array?} array of modifiers
     * @returns {*} modified jquery-element
     */
    makeBlockElement(elementName, $baseElement, modifiersArr) {
        const blockClass = this.block + BLOCK_SEPARATOR + elementName,
            modifiersClass = getElementClassWithModifiers(blockClass, modifiersArr)
        ;

        return $baseElement.addClass(blockClass).addClass(modifiersClass);
    }

    /**
     * Builds an BEM-styled jquery-element.
     *
     * Usage:
     *

     *     var exampleBEM = new BEM({
     *          block: "the-block",
     *          elements: {
     *              "some-element": "some-element-class"
     *          }
     *     });
     *     var $element = exampleBEM.buildBlockElement(
     *          "some-element", "<div>", {"name":"some-name"}, ["mod-1", "mod-2"]
     *     );
     *     // $element will be:
     *     <div name="some-name" class="some-element-class some-element-class--mod-1 some-element-class--mod-2 the-block__some-element"></div>
     *

     *
     * @param elementName {string}
     * @param tag {string}
     * @param attributes {object?}
     * @param modifiersArr {array?}
     * @returns {*}
     *
     * @see buildElement
     */
    buildBlockElement(elementName, tag, attributes, modifiersArr) {
        return this.buildElement.apply(this, arguments).addClass(this.block + BLOCK_SEPARATOR + elementName);
    }

    /**
     * Builds an BEM-styled jquery-element without block__element class.
     *
     * Usage:
     *

     *     var exampleBEM = new BEM({
     *          block: "the-block",
     *          elements: {
     *              "some-element": "some-element-class"
     *          }
     *     });
     *     var $element = exampleBEM.buildElement(
     *          "some-element", "<div>", {"name":"some-name"}, ["mod-1", "mod-2"]
     *     );
     *     // $element will be:
     *     <div name="some-name" class="some-element-class some-element-class--mod-1 some-element-class--mod-2"></div>
     *

     *
     * @param elementName {string}
     * @param tag {string}
     * @param attributes {object?}
     * @param modifiersArr {array?}
     * @returns {*}
     *
     * @see buildElement
     */
    buildElement(elementName, tag, attributes, modifiersArr) {
        const modifiersClass = getElementClassWithModifiers(this.elements[elementName], modifiersArr);

        attributes = $.extend({}, attributes);
        attributes["class"] = modifiersClass + getOriginClass(attributes);

        return $(tag, attributes);
    }

    /**
     * Builds block element.
     *
     * Usage:
     *

     *     var panelButtonsBEM = new BEM({
     *         block: "imcms-menu"
     *     });
     *
     *     var $block = panelButtonsBEM.buildBlock("<div>", [{"items": $("<ul>")}], {name: "some-name"});
     *
     *     // $block will be:

     *     <div class="imcms-menu" name="some-name">
     *       <ul class="imcms-menu__items"></ul>
     *     </div>
     *
     *     // or the same result with this:
     *     var $block = panelButtonsBEM.buildBlock("<div>", [$("<ul>")], {name: "some-name"}, "items");
     *
     *

     *
     * @param tag {string}
     * @param elements {array?}
     * @param attributes {object?}
     * @param blockNameForEach {string?}
     * @returns {*} build block with elements inside
     */
    buildBlock(tag, elements, attributes, blockNameForEach) {
        attributes = attributes || {};
        attributes["class"] = this.block + getOriginClass(attributes);

        elements = (elements || []).map(function (element) {
            let elementName, $element;

            if (blockNameForEach) {
                elementName = blockNameForEach;
                $element = element;

            } else {
                const elementKeys = Object.keys(element);
                elementName = elementKeys[0];

                if (elementName === "modifiers") {
                    elementName = elementKeys[1];
                }

                $element = element[elementName];
            }

            const blockClass = this.block + BLOCK_SEPARATOR + elementName;

            if (element.modifiers) {
                const modifiersClass = getModifiersClass(blockClass, element.modifiers);
                $element.addClass(modifiersClass);
            }

            return $element.addClass(blockClass);

        }.bind(this));

        return $(tag, attributes).append(elements);
    }

    /**
     * Builds block using elements from constructor.
     *
     * Usage:
     *

     *
     *     var $block = new BEM({
     *         block: "imcms-list",
     *         elements: {
     *             "imcms-list-item": [$("<li>"), $("<li>")]
     *         }
     *     }).buildBlockStructure("<ul>", {id: "the-id"});
     *
     *     // $block will be:

     *     <ul id="the-id" class="imcms-list">
     *       <li class="imcms-list__imcms-list-item"></li>
     *       <li class="imcms-list__imcms-list-item"></li>
     *     </ul>
     *
     *

     *
     * @param tag {string}
     * @param attributes {object?}
     * @returns {*}
     */
    buildBlockStructure(tag, attributes) {
        const isArrayElements = (this.elements.constructor === Array);
        let blockElements = [];
        const elements = $.extend({}, this.elements);

        (isArrayElements ? this.elements : Object.keys(elements)).forEach(function (elementOrName) {
            let elementName, $element;

            if (isArrayElements) {
                const element = elementOrName;
                const elementKeys = Object.keys(element);

                elementName = elementKeys[0];

                if (elementName === "modifiers") {
                    elementName = elementKeys[1];
                }

                $element = element[elementName];
                $element.modifiers = element.modifiers;

            } else {
                elementName = elementOrName;
                $element = elements[elementName];
            }

            if ($element.constructor === Array) {
                blockElements = blockElements.concat(createBlockElements.call(this, $element, elementName));
                return;
            }

            const blockElement = createBlocKElement.call(this, $element, elementName);
            blockElements.push(blockElement);

        }.bind(this));

        return this.buildBlock(tag, blockElements, attributes);
    }
};
<commit_msg>IMCMS-371 - Image crop and size: - BEM class updated.<commit_after>/**
 * Block-Element-Modifier (BEM) builder.
 *
 * Created by Serhii Maksymchuk from Ubrainians for imCode
 * 24.07.17.
 */

const $ = require('jquery');

const MODIFIER_SEPARATOR = "--";
const BLOCK_SEPARATOR = "__";

function getOriginClass(attributesObj) {
    return attributesObj["class"] ? " " + attributesObj["class"] : "";
}

function getElementClassWithModifiers(elementClass, modifiersArr) {
    return elementClass + getModifiersClass(elementClass, modifiersArr);
}

function getModifiersClass(baseClass, modifiersArr) {
    let modifiers = "";

    (modifiersArr || []).forEach(function (modifier) {
        modifiers += " " + baseClass + MODIFIER_SEPARATOR + modifier;
    });

    return modifiers;
}

function createBlocKElement(element, elementName) {
    const blockElement = {};
    this.elements[elementName] = element["class"] || "";

    if (element.modifiers) {
        blockElement.modifiers = element.modifiers;
    }

    blockElement[elementName] = (element.length) // means jquery, not simple array
        ? element
        : this.buildElement(elementName, element.tag, element.attributes, element.modifiers);

    return blockElement;
}

function createBlockElements(elements, elementName) {
    return elements.map(function (element) {
        return createBlocKElement.call(this, element, elementName);
    }.bind(this));
}

module.exports = class BemBuilder {
    constructor(options) {
        this.elements = options.elements;
        this.block = options.block;
    };

    /**
     * Build BEM-styled class with needed separators
     *
     * @example
     *     var bemClass = BEM.buildClass("one", "two", "three"); // = "one__two--three"
     *
     * @param block {null|string}
     * @param element {null|string?}
     * @param modifier {string?}
     * @returns {string} BEM-styled class
     */
    static buildClass(block, element, modifier) {
        modifier = (modifier) ? MODIFIER_SEPARATOR + modifier : "";
        element = (block && element) ? BLOCK_SEPARATOR + element : (element) ? element : "";
        block = (block || "");
        return block + element + modifier;
    }

    /**
     * Build selector for BEM-styled class
     *
     * @example
     *     var bemClassSelector = BEM.buildClassSelector("one", "two", "three"); // = ".one__two--three"
     *
     * @param block {*|string}
     * @param element {null|string?}
     * @param modifier {string?}
     * @returns {string} selector for BEM-styled class
     */
    static buildClassSelector(block, element, modifier) {
        return "." + this.buildClass.apply(this, arguments);
    };

    /**
     * Adds BEM-styled class to element
     *
     * @example
     *     var exampleBEM = new BEM({
     *          block: "the-block",
     *          elements: {
     *              "some-element": "some-element-class"
     *          }
     *     });
     *     var $element = exampleBEM.makeBlockElement("some-element", $(".some-class"), ["mod-1", "mod-2"]);
     *     // $element will have class "the-block__some-element the-block__some-element--mod-1 the-block__some-element--mod-2"
     *
     * @param elementName {string} name of element in current BEM-builder
     * @param $baseElement {object} jquery-element to be modified
     * @param modifiersArr {array?} array of modifiers
     * @returns {*} modified jquery-element
     */
    makeBlockElement(elementName, $baseElement, modifiersArr) {
        const blockClass = this.block + BLOCK_SEPARATOR + elementName,
            modifiersClass = getElementClassWithModifiers(blockClass, modifiersArr)
        ;

        return $baseElement.addClass(blockClass).addClass(modifiersClass);
    }

    /**
     * Builds an BEM-styled jquery-element.
     *
     * @example
     *     var exampleBEM = new BEM({
     *          block: "the-block",
     *          elements: {
     *              "some-element": "some-element-class"
     *          }
     *     });
     *     var $element = exampleBEM.buildBlockElement(
     *          "some-element", "
", {"name":"some-name"}, ["mod-1", "mod-2"]
     *     );
     *     // $element will be:
     *

     *
     * @param elementName {string}
     * @param tag {string}
     * @param attributes {object?}
     * @param modifiersArr {array?}
     * @returns {*}
     *
     * @see buildElement
     */
    buildBlockElement(elementName, tag, attributes, modifiersArr) {
        return this.buildElement.apply(this, arguments).addClass(this.block + BLOCK_SEPARATOR + elementName);
    }

    /**
     * Builds an BEM-styled jquery-element without block__element class.
     *
     * @example
     *     var exampleBEM = new BEM({
     *          block: "the-block",
     *          elements: {
     *              "some-element": "some-element-class"
     *          }
     *     });
     *     var $element = exampleBEM.buildElement(
     *          "some-element", "
", {"name":"some-name"}, ["mod-1", "mod-2"]
     *     );
     *     // $element will be:
     *

     *
     * @param elementName {string}
     * @param tag {string}
     * @param attributes {object?}
     * @param modifiersArr {array?}
     * @returns {*}
     *
     * @see buildElement
     */
    buildElement(elementName, tag, attributes, modifiersArr) {
        const modifiersClass = getElementClassWithModifiers(this.elements[elementName], modifiersArr);

        attributes = $.extend({}, attributes);
        attributes["class"] = modifiersClass + getOriginClass(attributes);

        return $(tag, attributes);
    }

    /**
     * Builds block element.
     *
     * @example
     *     var panelButtonsBEM = new BEM({
     *         block: "imcms-menu"
     *     });
     *
     *     var $block = panelButtonsBEM.buildBlock("
", [{"items": $("
")}], {name: "some-name"});
     *
     *     // $block will be:

     *

     *

     *

     *
     *     // or the same result with this:
     *     var $block = panelButtonsBEM.buildBlock("
", [$("
")], {name: "some-name"}, "items");
     *
     *
     * @param tag {string}
     * @param elements {array?}
     * @param attributes {object?}
     * @param blockNameForEach {string?}
     * @returns {*} build block with elements inside
     */
    buildBlock(tag, elements, attributes, blockNameForEach) {
        attributes = attributes || {};
        attributes["class"] = this.block + getOriginClass(attributes);

        elements = (elements || []).map(function (element) {
            let elementName, $element;

            if (blockNameForEach) {
                elementName = blockNameForEach;
                $element = element;

            } else {
                const elementKeys = Object.keys(element);
                elementName = elementKeys[0];

                if (elementName === "modifiers") {
                    elementName = elementKeys[1];
                }

                $element = element[elementName];
            }

            const blockClass = this.block + BLOCK_SEPARATOR + elementName;

            if (element.modifiers) {
                const modifiersClass = getModifiersClass(blockClass, element.modifiers);
                $element.addClass(modifiersClass);
            }

            return $element.addClass(blockClass);

        }.bind(this));

        return $(tag, attributes).append(elements);
    }

    /**
     * Builds block using elements from constructor.
     *
     * @example
     *     var $block = new BEM({
     *         block: "imcms-list",
     *         elements: {
     *             "imcms-list-item": [$("
"), $("
")]
     *         }
     *     }).buildBlockStructure("
", {id: "the-id"});
     *
     *     // $block will be:

     *

     *

     *

     *

     *
     * @param tag {string}
     * @param attributes {object?}
     * @returns {*}
     */
    buildBlockStructure(tag, attributes) {
        const isArrayElements = (this.elements.constructor === Array);
        let blockElements = [];
        const elements = $.extend({}, this.elements);

        (isArrayElements ? this.elements : Object.keys(elements)).forEach(function (elementOrName) {
            let elementName, $element;

            if (isArrayElements) {
                const element = elementOrName;
                const elementKeys = Object.keys(element);

                elementName = elementKeys[0];

                if (elementName === "modifiers") {
                    elementName = elementKeys[1];
                }

                $element = element[elementName];
                $element.modifiers = element.modifiers;

            } else {
                elementName = elementOrName;
                $element = elements[elementName];
            }

            if ($element.constructor === Array) {
                blockElements = blockElements.concat(createBlockElements.call(this, $element, elementName));
                return;
            }

            const blockElement = createBlocKElement.call(this, $element, elementName);
            blockElements.push(blockElement);

        }.bind(this));

        return this.buildBlock(tag, blockElements, attributes);
    }
};
<|endoftext|>


<commit_before>/* jshint mocha: true */
/*test commit*/
var assert = require('assert');
var fs = require('fs');
var path = require('path');

var pkg = require('./../package.json');
var dirs = pkg['h5bp-configs'].directories;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

function checkString(file, string, done) {

    var character = '';
    var matchFound = false;
    var matchedPositions = 0;
    var readStream = fs.createReadStream(file, { 'encoding': 'utf8' });

    readStream.on('close', done);
    readStream.on('error', done);
    readStream.on('readable', function () {

        // Read file until the string is found
        // or the whole file has been read
        while (matchFound !== true &&
                (character = readStream.read(1)) !== null) {

            if (character === string.charAt(matchedPositions)) {
                matchedPositions += 1;
            } else {
                matchedPositions = 0;
            }

            if (matchedPositions === string.length) {
                matchFound = true;
            }

        }

        assert.equal(true, matchFound);
        this.close();

    });

}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

function runTests() {

    var dir = dirs.dist;

    describe('Test if the files from the "' + dir + '" directory have the expected content', function () {

        it('".htaccess" should have the "ErrorDocument..." line uncommented', function (done) {
            var string = '\n\nErrorDocument 404 /404.html\n\n';
            checkString(path.resolve(dir, '.htaccess'), string, done);
        });

        it('"index.html" should contain the correct jQuery version in the CDN URL', function (done) {
            var string = 'code.jquery.com/jquery-' + pkg.devDependencies.jquery + '.min.js';
            checkString(path.resolve(dir, 'index.html'), string, done);
        });

        it('"index.html" should contain the correct jQuery version in the local URL', function (done) {
            var string = 'js/vendor/jquery-' + pkg.devDependencies.jquery + '.min.js';
            checkString(path.resolve(dir, 'index.html'), string, done);
        });

        it('"main.css" should contain a custom banner', function (done) {
            var string = '/*! HTML5 Boilerplate v' + pkg.version +
                         ' | ' + pkg.license.type + ' License' +
                         ' | ' + pkg.homepage + ' */\n\n/*\n';
            checkString(path.resolve(dir, 'css/main.css'), string, done);
        });

    });

}

runTests();
<commit_msg>another test<commit_after>/* jshint mocha: true */
/*another test*/
var assert = require('assert');
var fs = require('fs');
var path = require('path');

var pkg = require('./../package.json');
var dirs = pkg['h5bp-configs'].directories;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

function checkString(file, string, done) {

    var character = '';
    var matchFound = false;
    var matchedPositions = 0;
    var readStream = fs.createReadStream(file, { 'encoding': 'utf8' });

    readStream.on('close', done);
    readStream.on('error', done);
    readStream.on('readable', function () {

        // Read file until the string is found
        // or the whole file has been read
        while (matchFound !== true &&
                (character = readStream.read(1)) !== null) {

            if (character === string.charAt(matchedPositions)) {
                matchedPositions += 1;
            } else {
                matchedPositions = 0;
            }

            if (matchedPositions === string.length) {
                matchFound = true;
            }

        }

        assert.equal(true, matchFound);
        this.close();

    });

}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

function runTests() {

    var dir = dirs.dist;

    describe('Test if the files from the "' + dir + '" directory have the expected content', function () {

        it('".htaccess" should have the "ErrorDocument..." line uncommented', function (done) {
            var string = '\n\nErrorDocument 404 /404.html\n\n';
            checkString(path.resolve(dir, '.htaccess'), string, done);
        });

        it('"index.html" should contain the correct jQuery version in the CDN URL', function (done) {
            var string = 'code.jquery.com/jquery-' + pkg.devDependencies.jquery + '.min.js';
            checkString(path.resolve(dir, 'index.html'), string, done);
        });

        it('"index.html" should contain the correct jQuery version in the local URL', function (done) {
            var string = 'js/vendor/jquery-' + pkg.devDependencies.jquery + '.min.js';
            checkString(path.resolve(dir, 'index.html'), string, done);
        });

        it('"main.css" should contain a custom banner', function (done) {
            var string = '/*! HTML5 Boilerplate v' + pkg.version +
                         ' | ' + pkg.license.type + ' License' +
                         ' | ' + pkg.homepage + ' */\n\n/*\n';
            checkString(path.resolve(dir, 'css/main.css'), string, done);
        });

    });

}

runTests();
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import TextField from 'material-ui/TextField';
import SelectField from 'material-ui/SelectField';
import MenuItem from 'material-ui/MenuItem';
import Avatar from 'material-ui/Avatar';
import Chip from 'material-ui/Chip';
import * as MColors from 'material-ui/styles/colors';

import { RaisedButton, FlatButton } from 'material-ui'
import {
  Step,
  Stepper,
  StepLabel,
} from 'material-ui/Stepper';
import {betState, stepperState} from './betStates';

class BetController extends Component {
  constructor(props) {
    super(props);
    this.state = {
      selectedTeam: null,
      amountToBet: 0,
      isArbiter: false
    }
  }

  setTeam = (event, index, value) => {
    this.setState({selectedTeam: value});
  };

  setBetValue = (event, newValue) => {
    this.setState({amountToBet : parseInt(newValue)});
  };

  Steps = () => {
    var BetDecision = () => {
      if (this.props.currentBetState <= betState.shouldCallArbiter ||
        this.props.currentBetState === betState.calledArbiter)
        return 'Result';
      else if (this.props.currentBetState === betState.team0Won)
        return `${this.props.team0Name} won`;
      else if (this.props.currentBetState === betState.arbiterUndecided)
        return 'Undecided';
      else if (this.props.currentBetState === betState.team1Won)
        return `${this.props.team1Name} won`;
      else if (this.props.currentBetState === betState.draw)
        return 'Draw';
      return null;
    };
    var CallArbiter = () => {
      if (this.props.currentBetState === betState.calledArbiter)
        return 'Called Arbiter';
      else
        return 'Call Arbiter';
    };

    // TODO: I don't think BetDecision() works
    // TODO: Change Call Arbiter to Arbiter Called when the arbiter is called
    return (
        <Stepper activeStep={this.props.stepperState}>
          <Step>
            <StepLabel>Place your bet!</StepLabel>
          </Step>
          <Step>
            <StepLabel>Match running</StepLabel>
          </Step>
          <Step>
            <StepLabel>{CallArbiter()}</StepLabel>
          </Step>
          <Step>
            <StepLabel>{BetDecision()}</StepLabel>
          </Step>
          <Step>
            <StepLabel>Payout</StepLabel>
          </Step>
        </Stepper>
      );
  }

  DynamicBetButton = () => {
    if (this.props.currentBetState === betState.shouldCallArbiter ||
        this.props.currentBetState === betState.calledArbiter) {
      return (
      <RaisedButton
        disabled={this.props.currentBetState === betState.calledArbiter}
        secondary={true}
        className="betBtn"
        onTouchTap={this.callArbiter}
      >Call Arbiter
      </RaisedButton>
      )
    }
    else if ((this.props.currentBetState >= betState.team0Won &&
                this.props.currentBetState <= betState.draw) ||
              this.props.stepperState === stepperState.payout) {
      var gain = this.FinalGain();
      return (
      <RaisedButton
        className="betBtn"
        primary={true}
        onTouchTap={this.betOnTeam}
        disabled={(this.props.stepperState === stepperState.payout) || (gain.lte(0))}
      >Withdraw Ξ{gain.toString()}
      </RaisedButton>
      )
    }
    return (
      <RaisedButton
        disabled={(this.props.currentBetState !== betState.matchOpen)}
        className="betBtn"
        primary={true}
        onTouchTap={() => this.props.betOnTeamFunction(this.state.selectedTeam, this.state.amountToBet)}
      >Bet
      </RaisedButton>
      )
  }

  ArbiterButton = () => {
    return (
    <RaisedButton
      disabled={this.props.currentBetState !== betState.calledArbiter}
      secondary={true}
      className="betBtn"
      onTouchTap={this.callArbiter}
    >Vote
    </RaisedButton>
    )
  }

  ComputeGain = (amount, winnerPool, loserPool, tax) => {
    var BigNumber = require('bignumber.js');
    var profit = amount.dividedBy(winnerPool).times(loserPool);
    if (profit.gt(0))
      profit = profit.minus(profit.times(new BigNumber(tax)))
    return amount.plus(profit);
  }

  ExpectedGain = () => {
    var BigNumber = require('bignumber.js');
    var expectedIncome;
    var amount;
    var winnerPool;
    var loserPool;

    if (this.state.selectedTeam === null || this.props.currentBetState !== betState.matchOpen)
      return null;

    if (this.state.amountToBet <= 0)
      return null;

    amount = new BigNumber(this.state.amountToBet);
    if (this.state.selectedTeam === false) {
      loserPool = this.props.team1BetSum;
      winnerPool = this.props.team0BetSum;
    }
    else {
      loserPool = this.props.team0BetSum;
      winnerPool = this.props.team1BetSum;
    }
    winnerPool = winnerPool.plus(amount);
    expectedIncome = this.ComputeGain(amount, winnerPool, loserPool, this.props.tax);

    if (amount.isZero(0) || isNaN(amount))
      return null;
    else
      return (
      <Chip backgroundColor={MColors.yellow500}>
        <Avatar size={32} backgroundColor={MColors.yellow800}>Ξ</Avatar>
        Win {parseFloat(expectedIncome.toString()).toFixed(2)}
      </Chip>
      );
  }

  FinalGain = () => {
    var BigNumber = require('bignumber.js');
    var amount;
    var winnerPool;
    var loserPool;
    const tax = 0.1; //FIXME get from contract

    if (this.props.currentBetState < betState.team0Won || this.props.currentBetState > betState.draw)
      return new BigNumber(0);

    if (this.props.hasBetOnTeam === null)
      return new BigNumber(0);

    amount = this.props.hasBetOnTeam.amount;
    if (this.props.currentBetState === betState.draw)
      return amount.toNumber();

    var hasBetTeam0 = !this.props.hasBetOnTeam.team;
    var hasBetTeam1 = this.props.hasBetOnTeam.team;
    var team0BetSum = this.props.team0BetSum;
    var team1BetSum = this.props.team1BetSum;

    if ((this.props.currentBetState === betState.team0Won && hasBetTeam1) ||
        (this.props.currentBetState === betState.team1Won && hasBetTeam0))
      return 0;

    if (this.props.currentBetState === betState.team0Won) {
      winnerPool = team0BetSum;
      loserPool = team1BetSum;
    }
    else if (this.props.currentBetState === betState.team1Won) {
      winnerPool = team1BetSum;
      loserPool = team0BetSum;
    }
    return this.ComputeGain(amount, winnerPool, loserPool, tax);
  }

  render() {
    if (this.props.isExpanded) {
      if (this.props.isArbiter) {
        return (

            <Chip backgroundColor={MColors.cyan500} labelColor={MColors.white}>
            Vote on match outcome:
          </Chip>
          <SelectField style={{ width: 160 }} className='test'
            floatingLabelText='Team'
            value={this.state.selectedTeam}
            onChange={this.setTeam}
            disabled={this.props.currentBetState !== betState.calledArbiter}
          >
            <MenuItem value={0} primaryText={this.props.team0Name} />
            <MenuItem value={1} primaryText={this.props.team1Name} />
            <MenuItem value={2} primaryText='Draw' />
          </SelectField>
          <this.ArbiterButton />

      )
      }
      return (

          <SelectField style={{ width: 160 }} className='test'
            floatingLabelText='Team'
            value={(this.props.hasBetOnTeam !== null) ? this.props.hasBetOnTeam.team : this.state.selectedTeam}
            onChange={this.setTeam}
            disabled={this.props.hasBetOnTeam !== null || this.props.currentBetState >= betState.matchRunning}
          >
            <MenuItem value={false} primaryText={this.props.team0Name} />
            <MenuItem value={true} primaryText={this.props.team1Name} />
          </SelectField>
          <TextField
            disabled={(this.props.currentBetState >= betState.matchRunning)}
            style={{ width: 80 }}
            id='betAmount'
            type='number'
            onChange={this.setBetValue}
            />
          <this.DynamicBetButton />
          <this.ExpectedGain/>

          <this.Steps />

      )
    }
    return null;
  }
}

export default BetController;
<commit_msg>TAX divided by 100<commit_after>import React, { Component } from 'react';
import TextField from 'material-ui/TextField';
import SelectField from 'material-ui/SelectField';
import MenuItem from 'material-ui/MenuItem';
import Avatar from 'material-ui/Avatar';
import Chip from 'material-ui/Chip';
import * as MColors from 'material-ui/styles/colors';

import { RaisedButton, FlatButton } from 'material-ui'
import {
  Step,
  Stepper,
  StepLabel,
} from 'material-ui/Stepper';
import {betState, stepperState} from './betStates';

class BetController extends Component {
  constructor(props) {
    super(props);
    this.state = {
      selectedTeam: null,
      amountToBet: 0,
      isArbiter: false
    }
  }

  setTeam = (event, index, value) => {
    this.setState({selectedTeam: value});
  };

  setBetValue = (event, newValue) => {
    this.setState({amountToBet : parseInt(newValue)});
  };

  Steps = () => {
    var BetDecision = () => {
      if (this.props.currentBetState <= betState.shouldCallArbiter ||
        this.props.currentBetState === betState.calledArbiter)
        return 'Result';
      else if (this.props.currentBetState === betState.team0Won)
        return `${this.props.team0Name} won`;
      else if (this.props.currentBetState === betState.arbiterUndecided)
        return 'Undecided';
      else if (this.props.currentBetState === betState.team1Won)
        return `${this.props.team1Name} won`;
      else if (this.props.currentBetState === betState.draw)
        return 'Draw';
      return null;
    };
    var CallArbiter = () => {
      if (this.props.currentBetState === betState.calledArbiter)
        return 'Called Arbiter';
      else
        return 'Call Arbiter';
    };

    // TODO: I don't think BetDecision() works
    // TODO: Change Call Arbiter to Arbiter Called when the arbiter is called
    return (
        <Stepper activeStep={this.props.stepperState}>
          <Step>
            <StepLabel>Place your bet!</StepLabel>
          </Step>
          <Step>
            <StepLabel>Match running</StepLabel>
          </Step>
          <Step>
            <StepLabel>{CallArbiter()}</StepLabel>
          </Step>
          <Step>
            <StepLabel>{BetDecision()}</StepLabel>
          </Step>
          <Step>
            <StepLabel>Payout</StepLabel>
          </Step>
        </Stepper>
      );
  }

  DynamicBetButton = () => {
    if (this.props.currentBetState === betState.shouldCallArbiter ||
        this.props.currentBetState === betState.calledArbiter) {
      return (
      <RaisedButton
        disabled={this.props.currentBetState === betState.calledArbiter}
        secondary={true}
        className="betBtn"
        onTouchTap={this.callArbiter}
      >Call Arbiter
      </RaisedButton>
      )
    }
    else if ((this.props.currentBetState >= betState.team0Won &&
                this.props.currentBetState <= betState.draw) ||
              this.props.stepperState === stepperState.payout) {
      var gain = this.FinalGain();
      return (
      <RaisedButton
        className="betBtn"
        primary={true}
        onTouchTap={this.betOnTeam}
        disabled={(this.props.stepperState === stepperState.payout) || (gain.lte(0))}
      >Withdraw Ξ{gain.toString()}
      </RaisedButton>
      )
    }
    return (
      <RaisedButton
        disabled={(this.props.currentBetState !== betState.matchOpen)}
        className="betBtn"
        primary={true}
        onTouchTap={() => this.props.betOnTeamFunction(this.state.selectedTeam, this.state.amountToBet)}
      >Bet
      </RaisedButton>
      )
  }

  ArbiterButton = () => {
    return (
    <RaisedButton
      disabled={this.props.currentBetState !== betState.calledArbiter}
      secondary={true}
      className="betBtn"
      onTouchTap={this.callArbiter}
    >Vote
    </RaisedButton>
    )
  }

  ComputeGain = (amount, winnerPool, loserPool, tax) => {
    var BigNumber = require('bignumber.js');
    var profit = amount.dividedBy(winnerPool).times(loserPool);
    if (profit.gt(0))
      profit = profit.minus(profit.times(new BigNumber(tax)))
    return amount.plus(profit);
  }

  ExpectedGain = () => {
    var BigNumber = require('bignumber.js');
    var expectedIncome;
    var amount;
    var winnerPool;
    var loserPool;
    var tax = new BigNumber(this.props.tax);
    tax = tax.dividedBy(100);

    if (this.state.selectedTeam === null || this.props.currentBetState !== betState.matchOpen)
      return null;

    if (this.state.amountToBet <= 0)
      return null;

    amount = new BigNumber(this.state.amountToBet);
    if (this.state.selectedTeam === false) {
      loserPool = this.props.team1BetSum;
      winnerPool = this.props.team0BetSum;
    }
    else {
      loserPool = this.props.team0BetSum;
      winnerPool = this.props.team1BetSum;
    }
    winnerPool = winnerPool.plus(amount);
    expectedIncome = this.ComputeGain(amount, winnerPool, loserPool, tax);

    if (amount.isZero(0) || isNaN(amount))
      return null;
    else
      return (
      <Chip backgroundColor={MColors.yellow500}>
        <Avatar size={32} backgroundColor={MColors.yellow800}>Ξ</Avatar>
        Win {parseFloat(expectedIncome.toString()).toFixed(2)}
      </Chip>
      );
  }

  FinalGain = () => {
    var BigNumber = require('bignumber.js');
    var amount;
    var winnerPool;
    var loserPool;
    var tax = new BigNumber(this.props.tax);
    tax = tax.dividedBy(100);

    if (this.props.currentBetState < betState.team0Won || this.props.currentBetState > betState.draw)
      return new BigNumber(0);

    if (this.props.hasBetOnTeam === null)
      return new BigNumber(0);

    amount = this.props.hasBetOnTeam.amount;
    if (this.props.currentBetState === betState.draw)
      return amount;

    var hasBetTeam0 = !this.props.hasBetOnTeam.team;
    var hasBetTeam1 = this.props.hasBetOnTeam.team;
    var team0BetSum = this.props.team0BetSum;
    var team1BetSum = this.props.team1BetSum;

    if ((this.props.currentBetState === betState.team0Won && hasBetTeam1) ||
        (this.props.currentBetState === betState.team1Won && hasBetTeam0))
      return 0;

    if (this.props.currentBetState === betState.team0Won) {
      winnerPool = team0BetSum;
      loserPool = team1BetSum;
    }
    else if (this.props.currentBetState === betState.team1Won) {
      winnerPool = team1BetSum;
      loserPool = team0BetSum;
    }
    return this.ComputeGain(amount, winnerPool, loserPool, tax);
  }

  render() {
    if (this.props.isExpanded) {
      if (this.props.isArbiter) {
        return (

            <Chip backgroundColor={MColors.cyan500} labelColor={MColors.white}>
            Vote on match outcome:
          </Chip>
          <SelectField style={{ width: 160 }} className='test'
            floatingLabelText='Team'
            value={this.state.selectedTeam}
            onChange={this.setTeam}
            disabled={this.props.currentBetState !== betState.calledArbiter}
          >
            <MenuItem value={0} primaryText={this.props.team0Name} />
            <MenuItem value={1} primaryText={this.props.team1Name} />
            <MenuItem value={2} primaryText='Draw' />
          </SelectField>
          <this.ArbiterButton />

      )
      }
      return (

          <SelectField style={{ width: 160 }} className='test'
            floatingLabelText='Team'
            value={(this.props.hasBetOnTeam !== null) ? this.props.hasBetOnTeam.team : this.state.selectedTeam}
            onChange={this.setTeam}
            disabled={this.props.hasBetOnTeam !== null || this.props.currentBetState >= betState.matchRunning}
          >
            <MenuItem value={false} primaryText={this.props.team0Name} />
            <MenuItem value={true} primaryText={this.props.team1Name} />
          </SelectField>
          <TextField
            disabled={(this.props.currentBetState >= betState.matchRunning)}
            style={{ width: 80 }}
            id='betAmount'
            type='number'
            onChange={this.setBetValue}
            />
          <this.DynamicBetButton />
          <this.ExpectedGain/>

          <this.Steps />

      )
    }
    return null;
  }
}

export default BetController;
<|endoftext|>


<commit_before>const fountain = require('fountain-generator');

module.exports = fountain.Base.extend({
  configuring() {
    this.mergeJson('package.json', {
      dependencies: {
        '@ngrx/store': '^1.5.0'
      },
      devDependencies: {
        'todomvc-app-css': '^2.0.4'
      }
    });
    if (this.options.js === 'js') {
      this.mergeJson('package.json', {
        dependencies: {'object-assign': '^4.1.0'}
      });
    }
  },

  writing: {
    src() {
      [
        'src/index.html',
        'src/index.js',
        'src/index.css',

        'src/app/actions/index.js',
        'src/app/components/Footer.js',
        'src/app/components/Footer.spec.js',
        'src/app/components/Header.js',
        'src/app/components/Header.spec.js',
        'src/app/components/MainSection.js',
        'src/app/components/MainSection.spec.js',
        'src/app/components/TodoItem.js',
        'src/app/components/TodoItem.spec.js',
        'src/app/components/TodoTextInput.js',
        'src/app/components/TodoTextInput.spec.js',

        'src/app/constants/ActionTypes.js',
        'src/app/constants/TodoFilters.js',

        'src/app/containers/App.js',

        'src/app/reducers/todos.js',
        'src/app/reducers/todos.spec.js'

      ].map(file => this.copyTemplate(file, file));
    }
  }
});
<commit_msg>Move todomvc-app-css into dep<commit_after>const fountain = require('fountain-generator');

module.exports = fountain.Base.extend({
  configuring() {
    this.mergeJson('package.json', {
      dependencies: {
        '@ngrx/store': '^1.5.0',
        'todomvc-app-css': '^2.0.4'
      }
    });
    if (this.options.js === 'js') {
      this.mergeJson('package.json', {
        dependencies: {'object-assign': '^4.1.0'}
      });
    }
  },

  writing: {
    src() {
      [
        'src/index.html',
        'src/index.js',
        'src/index.css',

        'src/app/actions/index.js',
        'src/app/components/Footer.js',
        'src/app/components/Footer.spec.js',
        'src/app/components/Header.js',
        'src/app/components/Header.spec.js',
        'src/app/components/MainSection.js',
        'src/app/components/MainSection.spec.js',
        'src/app/components/TodoItem.js',
        'src/app/components/TodoItem.spec.js',
        'src/app/components/TodoTextInput.js',
        'src/app/components/TodoTextInput.spec.js',

        'src/app/constants/ActionTypes.js',
        'src/app/constants/TodoFilters.js',

        'src/app/containers/App.js',

        'src/app/reducers/todos.js',
        'src/app/reducers/todos.spec.js'

      ].map(file => this.copyTemplate(file, file));
    }
  }
});
<|endoftext|>


<commit_before>$(function() {

	// chat aliases
	var you = 'You';
	var robot = 'Robin';

	// slow reply by 400 to 800 ms
	var delayStart = 400;
	var delayEnd = 800;

	// initialize
	var bot = new chatBot();
	var chat = $('.chat');
	var waiting = 0;
	$('.busy').text(robot + ' is typing...');

	// submit user input and get chat-bot's reply
	var submitChat = function() {

		var input = $('.input input').val();
		if(input == '') return;

		$('.input input').val('');
		updateChat(you, input);

		var reply = bot.respondTo(input);
		if(reply == null) return;

		speak(reply);
		ping();

		var latency = Math.floor((Math.random() * (delayEnd - delayStart)) + delayStart);
		$('.busy').css('display', 'block');
		waiting++;
		setTimeout( function() {
			if(typeof reply === 'string') {
				updateChat(robot, reply);
			} else {
				for(var r in reply) {
					updateChat(robot, reply[r]);
				}
			}
			if(--waiting == 0) $('.busy').css('display', 'none');
		}, latency);
	}

	var speak = function(texts){
		if(window.speechSynthesis){
	        for(var i=0; i < texts.length; i++){
	            var utterance = new SpeechSynthesisUtterance(texts[i]);
	            utterance.lang = 'en-US';
	            window.speechSynthesis.speak(utterance);
	        }
		}
    }

    var ping = function(){

    	var payload = {
            "value1": "demo",
            "value2": "demo2"
        };

		var data = new FormData();
		data.append( "json", JSON.stringify( payload ) );

		var ifttt = "https://maker.ifttt.com/trigger/winter-games-game1/with/key/dvHJXlCso1laUplLipy7LT";
        //fetch("http://anyorigin.com/go?url=https://maker.ifttt.com/trigger/winter-games-game1/with/key/dvHJXlCso1laUplLipy7LT",
        fetch("http://whateverorigin.org/get?url=" + encodeURIComponent(ifttt),
        {
        	method: "POST",
        	mode: 'cors',
        	headers: new Headers({
				"Content-Type": "application/json"
			}),
            //body: JSON.stringify({"value1": "demo", "value2": "demo2"})
            body : data
        })
        .then(function(res){ console.log(res); })
        // $.post({
        //     url: 'https://crossorigin.me/https://maker.ifttt.com/trigger/winter-games-game1/with/key/dvHJXlCso1laUplLipy7LT',
        //     contentType : "application/json",
        //     dataType: "jsonp",
        //     //dataType: 'json',
        //     //jsonpCallback: "logResults",
        //     data: JSON.stringify({ value1: "demo" })
        // });
    }

	// add a new line to the chat
	var updateChat = function(party, text) {

		var style = 'you';
		if(party != you) {
			style = 'other';
		}

		var line = $('

');
		line.find('.party').addClass(style).text(party + ':');
		line.find('.text').text(text);

		chat.append(line);

		chat.stop().animate({ scrollTop: chat.prop("scrollHeight")});

	}

	// event binding
	$('.input').bind('keydown', function(e) {
		if(e.keyCode == 13) {
			submitChat();
		}
	});
	$('.input a').bind('click', submitChat);

	// initial chat state
	updateChat(robot, 'Hi buddy, Can I help you?');
	$('#chatbar').focus();

});<commit_msg>minor change<commit_after>$(function() {

	// chat aliases
	var you = 'You';
	var robot = 'Robin';

	// slow reply by 400 to 800 ms
	var delayStart = 400;
	var delayEnd = 800;

	// initialize
	var bot = new chatBot();
	var chat = $('.chat');
	var waiting = 0;
	$('.busy').text(robot + ' is typing...');

	// submit user input and get chat-bot's reply
	var submitChat = function() {

		var input = $('.input input').val();
		if(input == '') return;

		$('.input input').val('');
		updateChat(you, input);

		var reply = bot.respondTo(input);
		if(reply == null) return;

		speak(reply);
		ping();

		var latency = Math.floor((Math.random() * (delayEnd - delayStart)) + delayStart);
		$('.busy').css('display', 'block');
		waiting++;
		setTimeout( function() {
			if(typeof reply === 'string') {
				updateChat(robot, reply);
			} else {
				for(var r in reply) {
					updateChat(robot, reply[r]);
				}
			}
			if(--waiting == 0) $('.busy').css('display', 'none');
		}, latency);
	}

	var speak = function(texts){
		if(window.speechSynthesis){
	        for(var i=0; i < texts.length; i++){
	            var utterance = new SpeechSynthesisUtterance(texts[i]);
	            utterance.lang = 'en-US';
	            window.speechSynthesis.speak(utterance);
	        }
		}
    }

    var ping = function(){

    	var payload = {
            "value1": "demo",
            "value2": "demo2"
        };

		var data = new FormData();
		data.append( "json", JSON.stringify( payload ) );

		var ifttt = "https://maker.ifttt.com/trigger/winter-games-game1/with/key/dvHJXlCso1laUplLipy7LT";
        //fetch("http://anyorigin.com/go?url=https://maker.ifttt.com/trigger/winter-games-game1/with/key/dvHJXlCso1laUplLipy7LT",
        //fetch("http://whateverorigin.org/get?url=" + encodeURIComponent(ifttt),
        fetch("https://crossorigin.me/https://maker.ifttt.com/trigger/winter-games-game1/with/key/dvHJXlCso1laUplLipy7LT",
        {
        	method: "POST",
        	mode: 'cors',
        	headers: new Headers({
				"Content-Type": "application/json"
			}),
            //body: JSON.stringify({"value1": "demo", "value2": "demo2"})
            body : data
        })
        .then(function(res){ console.log(res); })
        // $.post({
        //     url: 'https://crossorigin.me/https://maker.ifttt.com/trigger/winter-games-game1/with/key/dvHJXlCso1laUplLipy7LT',
        //     contentType : "application/json",
        //     dataType: "jsonp",
        //     //dataType: 'json',
        //     //jsonpCallback: "logResults",
        //     data: JSON.stringify({ value1: "demo" })
        // });
    }

	// add a new line to the chat
	var updateChat = function(party, text) {

		var style = 'you';
		if(party != you) {
			style = 'other';
		}

		var line = $('

');
		line.find('.party').addClass(style).text(party + ':');
		line.find('.text').text(text);

		chat.append(line);

		chat.stop().animate({ scrollTop: chat.prop("scrollHeight")});

	}

	// event binding
	$('.input').bind('keydown', function(e) {
		if(e.keyCode == 13) {
			submitChat();
		}
	});
	$('.input a').bind('click', submitChat);

	// initial chat state
	updateChat(robot, 'Hi buddy, Can I help you?');
	$('#chatbar').focus();

});<|endoftext|>


<commit_before>/*
 * Copyright 2014-2015 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

define([
    'js-whatever/js/base-page',
    'find/app/model/entity-collection',
    'find/app/model/documents-collection',
    'find/app/model/indexes-collection',
    'find/app/router',
    'find/app/vent',
    'i18n!find/nls/bundle',
    'jquery',
    'underscore',
    'text!find/templates/app/page/find-search.html',
    'text!find/templates/app/page/results-container.html',
    'text!find/templates/app/page/suggestions-container.html',
    'text!find/templates/app/page/loading-spinner.html',
    'text!find/templates/app/page/colorbox-controls.html',
    'text!find/templates/app/page/index-popover.html',
    'text!find/templates/app/page/index-popover-contents.html',
    'text!find/templates/app/page/top-results-popover-contents.html',
    'colorbox'
], function(BasePage, EntityCollection, DocumentsCollection, IndexesCollection, router, vent, i18n, $, _, template, resultsTemplate,
            suggestionsTemplate, loadingSpinnerTemplate, colorboxControlsTemplate, indexPopover, indexPopoverContents, topResultsPopoverContents) {

    return BasePage.extend({

        template: _.template(template),
        resultsTemplate: _.template(resultsTemplate),
        noResultsTemplate: _.template('
<%- i18n["search.noResults"] %>
'),
        suggestionsTemplate: _.template(suggestionsTemplate),
        indexPopover: _.template(indexPopover),
        indexPopoverContents: _.template(indexPopoverContents),
        topResultsPopoverContents: _.template(topResultsPopoverContents),

        events: {
            'keyup .find-input': 'keyupAnimation',
            'click .list-indexes': _.debounce(function(){
                this.$('.popover-content label').html('');

                this.indexesCollection.fetch();
            }, 500, true),
            'change .indexCheckbox': function(e) {
                var toggledIndex = $(e.currentTarget).val();
                var checked = $(e.currentTarget).is(':checked');

                this.indexes[toggledIndex] = checked;

                if(this.$('.find-input').val()){
                    this.searchRequest(this.$('.find-input').val());
                }
            },
            'mouseover .suggestions-content a': _.debounce(function(e) {
                this.$('.suggestions-content  .popover-content').append(_.template(loadingSpinnerTemplate));

                this.topResultsCollection.fetch({
                    data: {
                        text: $(e.currentTarget).html(),
                        max_results: 3,
                        summary: 'quick',
                        index: this.index
                    }
                });
            }, 800),
            'mouseover .entity-to-summary': function(e) {
                var title = $(e.currentTarget).find('a').html();
                this.$('[data-title="'+ title +'"]').addClass('label label-primary entity-to-summary').removeClass('label-info');
            },
            'mouseleave .entity-to-summary': function() {
                this.$('.suggestions-content li a').removeClass('label label-primary entity-to-summary');
                this.$('.main-results-content .entity-to-summary').removeClass('label-primary').addClass('label-info');
            }
        },

        initialize: function() {
            this.entityCollection = new EntityCollection();
            this.documentsCollection = new DocumentsCollection();
            this.topResultsCollection = new DocumentsCollection();
            this.indexesCollection = new IndexesCollection();

            router.on('route:search', function(text) {
                this.entityCollection.reset();
                this.documentsCollection.set([]);

                if (text) {
                    this.$('.find-input').val(text); //when clicking one of the suggested search links
                    this.keyupAnimation();
                } else {
                    this.reverseAnimation(); //when clicking the small 'find' logo
                }
            }, this);

            this.indexesCollection.once('sync', function() {
                // Default to searching against all indexes
                this.indexesCollection.forEach(_.bind(function(indexModel) {
                    this.indexes[indexModel.get('index')] = true;
                }, this))
            }, this);

            this.indexes = {};
            this.indexesCollection.fetch();
        },

        render: function() {
            this.$el.html(this.template);

            this.$('.find-form').submit(function(e){ //preventing input form submit and page reload
                e.preventDefault();
            });

            this.$('.list-indexes').popover({
                html: true,
                content: this.indexPopover(),
                placement: 'bottom'
            });

            /*indices popover*/
            this.listenTo(this.indexesCollection, 'request', function(){
                if(this.$('.find-form .popover-content').length === 1) {
                    this.$('.find-form  .popover-content').append(_.template(loadingSpinnerTemplate));
                }
            });

            this.listenTo(this.indexesCollection, 'add', function(model){
                this.$('.find-form  .popover-content .loading-spinner').remove();

                var htmlTemplateOutput = $(this.indexPopoverContents({
                    index: model.get('index')
                }));

                this.$('.find-form .popover-content ul').append(htmlTemplateOutput);

                if (this.indexes[model.get('index')]) { // If index is selected, set the checkbox to checked
                    htmlTemplateOutput.find('input').prop('checked', true);
                }
            });

            /*top 3 results popover*/
            this.listenTo(this.topResultsCollection, 'add', function(model){
                this.$('.suggestions-content .popover-content .loading-spinner').remove();

                this.$('.suggestions-content .popover-content').append(this.topResultsPopoverContents({
                    title: model.get('title'),
                    summary: model.get('summary').trim().substring(0, 100) + "..."
                }));
            });

            /*suggested links*/
            this.listenTo(this.entityCollection, 'request', function() {
                if(!this.$('.suggestions-content ul').length) {
                    this.$('.suggestions-content').append(_.template(loadingSpinnerTemplate));
                }

                this.$('.suggested-links-header').removeClass('hide')
            });

            this.listenTo(this.entityCollection, 'reset', function() {
                this.$('.suggestions-content').empty();

                if (this.entityCollection.isEmpty()) {
                    this.$('.suggested-links-header').addClass('hide')
                }
                else {
                    var clusters = this.entityCollection.groupBy('cluster');

                    _.each(clusters, function(entities) {
                        this.$('.suggestions-content').append(this.suggestionsTemplate({
                            entities: entities
                        }));

                        this.$('.suggestions-content li a').popover({
                            html: true,
                            content: '
Top Results
',
                            placement: 'right',
                            trigger: 'hover'
                        })
                    }, this);

                    this.documentsCollection.each(function(document) {
                        var summary = this.addLinksToSummary(document.get('summary'));

                        this.$('[data-reference="' + document.get('reference') + '"] .result-summary').html(summary);
                    }, this);
                }
            });

            /*main results content*/
            this.listenTo(this.documentsCollection, 'request', function() {
                this.$('.main-results-content').empty();
                this.$('.main-results-content').append(_.template(loadingSpinnerTemplate));
            });

            this.listenTo(this.documentsCollection, 'add', function(model) {
                var reference = model.get('reference');
                var summary = model.get('summary');

                summary = this.addLinksToSummary(summary);

                this.$('.main-results-content .loading-spinner').remove();

                var $newResult = $(_.template(resultsTemplate ,{
                    title: model.get('title'),
                    reference: reference,
                    index: model.get('index'),
                    summary: summary
                }));

                this.$('.main-results-content').append($newResult);

                $newResult.find('.result-header').colorbox({
                    iframe: true,
                    width:'70%',
                    height:'70%',
                    href: reference,
                    rel: 'results',
                    current: '{current} of {total}',
                    onComplete: _.bind(function() {
                        $('#cboxPrevious, #cboxNext').remove(); //removing default colorbox nav buttons
                    }, this)
                });

                $newResult.find('.dots').click(function (e) {
                    e.preventDefault();
                    $newResult.find('.result-header').trigger('click'); //dot-dot-dot triggers the colorbox event
                });
            });

            this.listenTo(this.documentsCollection, 'sync', function() {
                if(this.documentsCollection.isEmpty()) {
                    this.$('.main-results-content .loading-spinner').remove();
                    this.$('.main-results-content').append(this.noResultsTemplate({i18n: i18n}));
                }
            });

            /*colorbox fancy button override*/
            $('#colorbox').append(_.template(colorboxControlsTemplate));
            $('.nextBtn').on('click', this.handleNextResult);
            $('.prevBtn').on('click', this.handlePrevResult);
        },

        addLinksToSummary: function(summary) {
            //creating an array of the entity titles, longest first
            var entities = this.entityCollection.map(function(entity) {
                return {
                    text: entity.get('text'),
                    id:  _.uniqueId('Find-IOD-Entity-Placeholder')
                }
            }).sort(function(a,b) {
                return b.text.length - a.text.length;
            });

            _.each(entities, function(entity) {
                summary = summary.replace(new RegExp('(^|\\s|[,.-:;?\'"!\\(\\)\\[\\]{}])' + entity.text + '($|\\s|[,.-:;?\'"!\\(\\)\\[\\]{}])', 'gi'), '$1' + entity.id + '$2');
            });

            _.each(entities, function(entity) {
                summary = summary.replace(new RegExp(entity.id, 'g'), '' + entity.text + '');
            });

            return summary;
        },

        keyupAnimation: _.debounce(function() {
            /*fancy animation*/
            if($.trim(this.$('.find-input').val()).length) { // input has at least one non whitespace character
                this.$('.find').addClass('animated-container').removeClass('reverse-animated-container');

                this.$('.suggested-links-container.span2').show();
                this.searchRequest(this.$('.find-input').val());
            } else {
                this.reverseAnimation();
                vent.navigate('find/search', {trigger: false});
            }
            this.$('.popover').remove();
        }, 500),

        handlePrevResult: function() {
            $.colorbox.prev();
        },

        handleNextResult: function() {
            $.colorbox.next();
        },

        reverseAnimation: function() {
            /*fancy reverse animation*/
            this.$('.find').removeClass('animated-container').addClass('reverse-animated-container');

            this.$('.main-results-content').empty();
            this.$('.suggested-links-container.span2').hide();
            this.$('.find-input').val('');
            this.$('.popover').remove();
        },

        searchRequest: function(input) {
            if (this.indexes) { // Do we have the list of indexes yet?
                var selectedIndexes = _.chain(this.indexes).map(function(value, key) {
                    return (value ? key : undefined); // Return names of selected indexes and undefined for unselected ones
                }).compact().value();

                this.documentsCollection.fetch({
                    data: {
                        text: input,
                        max_results: 30,
                        summary: 'quick',
                        index: selectedIndexes
                    }
                }, this);

                this.entityCollection.fetch({
                    data: {
                        text: input,
                        index: selectedIndexes
                    }
                });

                vent.navigate('find/search/' + encodeURIComponent(input), {trigger: false});
            }
            else {
                this.indexesCollection.once('sync', function() {
                    this.searchRequest(input);
                }, this);
            }
        }
    });
});
<commit_msg>Fix: suggested results preview panel wasn't showing results as hadn't been updated to work with multiple indexes<commit_after>/*
 * Copyright 2014-2015 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

define([
    'js-whatever/js/base-page',
    'find/app/model/entity-collection',
    'find/app/model/documents-collection',
    'find/app/model/indexes-collection',
    'find/app/router',
    'find/app/vent',
    'i18n!find/nls/bundle',
    'jquery',
    'underscore',
    'text!find/templates/app/page/find-search.html',
    'text!find/templates/app/page/results-container.html',
    'text!find/templates/app/page/suggestions-container.html',
    'text!find/templates/app/page/loading-spinner.html',
    'text!find/templates/app/page/colorbox-controls.html',
    'text!find/templates/app/page/index-popover.html',
    'text!find/templates/app/page/index-popover-contents.html',
    'text!find/templates/app/page/top-results-popover-contents.html',
    'colorbox'
], function(BasePage, EntityCollection, DocumentsCollection, IndexesCollection, router, vent, i18n, $, _, template, resultsTemplate,
            suggestionsTemplate, loadingSpinnerTemplate, colorboxControlsTemplate, indexPopover, indexPopoverContents, topResultsPopoverContents) {

    return BasePage.extend({

        template: _.template(template),
        resultsTemplate: _.template(resultsTemplate),
        noResultsTemplate: _.template('
<%- i18n["search.noResults"] %>
'),
        suggestionsTemplate: _.template(suggestionsTemplate),
        indexPopover: _.template(indexPopover),
        indexPopoverContents: _.template(indexPopoverContents),
        topResultsPopoverContents: _.template(topResultsPopoverContents),

        events: {
            'keyup .find-input': 'keyupAnimation',
            'click .list-indexes': _.debounce(function(){
                this.$('.popover-content label').html('');

                this.indexesCollection.fetch();
            }, 500, true),
            'change .indexCheckbox': function(e) {
                var toggledIndex = $(e.currentTarget).val();
                var checked = $(e.currentTarget).is(':checked');

                this.indexes[toggledIndex] = checked;

                if(this.$('.find-input').val()){
                    this.searchRequest(this.$('.find-input').val());
                }
            },
            'mouseover .suggestions-content a': _.debounce(function(e) {
                this.$('.suggestions-content  .popover-content').append(_.template(loadingSpinnerTemplate));

                this.topResultsCollection.fetch({
                    data: {
                        text: $(e.currentTarget).html(),
                        max_results: 3,
                        summary: 'quick',
                        index: this.selectedIndexes()
                    }
                });
            }, 800),
            'mouseover .entity-to-summary': function(e) {
                var title = $(e.currentTarget).find('a').html();
                this.$('[data-title="'+ title +'"]').addClass('label label-primary entity-to-summary').removeClass('label-info');
            },
            'mouseleave .entity-to-summary': function() {
                this.$('.suggestions-content li a').removeClass('label label-primary entity-to-summary');
                this.$('.main-results-content .entity-to-summary').removeClass('label-primary').addClass('label-info');
            }
        },

        initialize: function() {
            this.entityCollection = new EntityCollection();
            this.documentsCollection = new DocumentsCollection();
            this.topResultsCollection = new DocumentsCollection();
            this.indexesCollection = new IndexesCollection();

            router.on('route:search', function(text) {
                this.entityCollection.reset();
                this.documentsCollection.set([]);

                if (text) {
                    this.$('.find-input').val(text); //when clicking one of the suggested search links
                    this.keyupAnimation();
                } else {
                    this.reverseAnimation(); //when clicking the small 'find' logo
                }
            }, this);

            this.indexesCollection.once('sync', function() {
                // Default to searching against all indexes
                this.indexesCollection.forEach(_.bind(function(indexModel) {
                    this.indexes[indexModel.get('index')] = true;
                }, this))
            }, this);

            this.indexes = {};
            this.indexesCollection.fetch();
        },

        render: function() {
            this.$el.html(this.template);

            this.$('.find-form').submit(function(e){ //preventing input form submit and page reload
                e.preventDefault();
            });

            this.$('.list-indexes').popover({
                html: true,
                content: this.indexPopover(),
                placement: 'bottom'
            });

            /*indices popover*/
            this.listenTo(this.indexesCollection, 'request', function(){
                if(this.$('.find-form .popover-content').length === 1) {
                    this.$('.find-form  .popover-content').append(_.template(loadingSpinnerTemplate));
                }
            });

            this.listenTo(this.indexesCollection, 'add', function(model){
                this.$('.find-form  .popover-content .loading-spinner').remove();

                var htmlTemplateOutput = $(this.indexPopoverContents({
                    index: model.get('index')
                }));

                this.$('.find-form .popover-content ul').append(htmlTemplateOutput);

                if (this.indexes[model.get('index')]) { // If index is selected, set the checkbox to checked
                    htmlTemplateOutput.find('input').prop('checked', true);
                }
            });

            /*top 3 results popover*/
            this.listenTo(this.topResultsCollection, 'add', function(model){
                this.$('.suggestions-content .popover-content .loading-spinner').remove();

                this.$('.suggestions-content .popover-content').append(this.topResultsPopoverContents({
                    title: model.get('title'),
                    summary: model.get('summary').trim().substring(0, 100) + "..."
                }));
            });

            /*suggested links*/
            this.listenTo(this.entityCollection, 'request', function() {
                if(!this.$('.suggestions-content ul').length) {
                    this.$('.suggestions-content').append(_.template(loadingSpinnerTemplate));
                }

                this.$('.suggested-links-header').removeClass('hide')
            });

            this.listenTo(this.entityCollection, 'reset', function() {
                this.$('.suggestions-content').empty();

                if (this.entityCollection.isEmpty()) {
                    this.$('.suggested-links-header').addClass('hide')
                }
                else {
                    var clusters = this.entityCollection.groupBy('cluster');

                    _.each(clusters, function(entities) {
                        this.$('.suggestions-content').append(this.suggestionsTemplate({
                            entities: entities
                        }));

                        this.$('.suggestions-content li a').popover({
                            html: true,
                            content: '
Top Results
',
                            placement: 'right',
                            trigger: 'hover'
                        })
                    }, this);

                    this.documentsCollection.each(function(document) {
                        var summary = this.addLinksToSummary(document.get('summary'));

                        this.$('[data-reference="' + document.get('reference') + '"] .result-summary').html(summary);
                    }, this);
                }
            });

            /*main results content*/
            this.listenTo(this.documentsCollection, 'request', function() {
                this.$('.main-results-content').empty();
                this.$('.main-results-content').append(_.template(loadingSpinnerTemplate));
            });

            this.listenTo(this.documentsCollection, 'add', function(model) {
                var reference = model.get('reference');
                var summary = model.get('summary');

                summary = this.addLinksToSummary(summary);

                this.$('.main-results-content .loading-spinner').remove();

                var $newResult = $(_.template(resultsTemplate ,{
                    title: model.get('title'),
                    reference: reference,
                    index: model.get('index'),
                    summary: summary
                }));

                this.$('.main-results-content').append($newResult);

                $newResult.find('.result-header').colorbox({
                    iframe: true,
                    width:'70%',
                    height:'70%',
                    href: reference,
                    rel: 'results',
                    current: '{current} of {total}',
                    onComplete: _.bind(function() {
                        $('#cboxPrevious, #cboxNext').remove(); //removing default colorbox nav buttons
                    }, this)
                });

                $newResult.find('.dots').click(function (e) {
                    e.preventDefault();
                    $newResult.find('.result-header').trigger('click'); //dot-dot-dot triggers the colorbox event
                });
            });

            this.listenTo(this.documentsCollection, 'sync', function() {
                if(this.documentsCollection.isEmpty()) {
                    this.$('.main-results-content .loading-spinner').remove();
                    this.$('.main-results-content').append(this.noResultsTemplate({i18n: i18n}));
                }
            });

            /*colorbox fancy button override*/
            $('#colorbox').append(_.template(colorboxControlsTemplate));
            $('.nextBtn').on('click', this.handleNextResult);
            $('.prevBtn').on('click', this.handlePrevResult);
        },

        addLinksToSummary: function(summary) {
            //creating an array of the entity titles, longest first
            var entities = this.entityCollection.map(function(entity) {
                return {
                    text: entity.get('text'),
                    id:  _.uniqueId('Find-IOD-Entity-Placeholder')
                }
            }).sort(function(a,b) {
                return b.text.length - a.text.length;
            });

            _.each(entities, function(entity) {
                summary = summary.replace(new RegExp('(^|\\s|[,.-:;?\'"!\\(\\)\\[\\]{}])' + entity.text + '($|\\s|[,.-:;?\'"!\\(\\)\\[\\]{}])', 'gi'), '$1' + entity.id + '$2');
            });

            _.each(entities, function(entity) {
                summary = summary.replace(new RegExp(entity.id, 'g'), '' + entity.text + '');
            });

            return summary;
        },

        keyupAnimation: _.debounce(function() {
            /*fancy animation*/
            if($.trim(this.$('.find-input').val()).length) { // input has at least one non whitespace character
                this.$('.find').addClass('animated-container').removeClass('reverse-animated-container');

                this.$('.suggested-links-container.span2').show();
                this.searchRequest(this.$('.find-input').val());
            } else {
                this.reverseAnimation();
                vent.navigate('find/search', {trigger: false});
            }
            this.$('.popover').remove();
        }, 500),

        handlePrevResult: function() {
            $.colorbox.prev();
        },

        handleNextResult: function() {
            $.colorbox.next();
        },

        reverseAnimation: function() {
            /*fancy reverse animation*/
            this.$('.find').removeClass('animated-container').addClass('reverse-animated-container');

            this.$('.main-results-content').empty();
            this.$('.suggested-links-container.span2').hide();
            this.$('.find-input').val('');
            this.$('.popover').remove();
        },

        searchRequest: function(input) {
            if (this.indexes) { // Do we have the list of indexes yet?
                var selectedIndexes = this.selectedIndexes();

                this.documentsCollection.fetch({
                    data: {
                        text: input,
                        max_results: 30,
                        summary: 'quick',
                        index: selectedIndexes
                    }
                }, this);

                this.entityCollection.fetch({
                    data: {
                        text: input,
                        index: selectedIndexes
                    }
                });

                vent.navigate('find/search/' + encodeURIComponent(input), {trigger: false});
            }
            else {
                this.indexesCollection.once('sync', function() {
                    this.searchRequest(input);
                }, this);
            }
        },

        selectedIndexes: function() {
            return _.chain(this.indexes).map(function(value, key) {
                return (value ? key : undefined); // Return names of selected indexes and undefined for unselected ones
            }).compact().value();
        }
    });
});
<|endoftext|>