<commit_before>import _ from 'lodash'

const DOT_SAFE = '__dotSafe__'
const dotSafeWrap = unsafePath => ({[DOT_SAFE]: unsafePath})
const dotSafeUnwrap = safePath => safePath[DOT_SAFE]

export const dotSafe = dotSafeWrap

export const toPathList = (path, safe = false) => {
    if (_.isArray(path)) {
        return _.chain(path)
            .map(pathElement => toPathList(pathElement, safe))
            .filter(_.identity)
            .flatten()
            .value()
    }
    if (_.isObject(path)) {
        const unwrapped = dotSafeUnwrap(path)
        return _.isUndefined(unwrapped)
            ? path
            : toPathList([unwrapped], true)
    }
    if (_.isString(path)) {
        return safe ? [path] : path.split('.')
    }
    if (_.isNumber(path)) {
        return [path.toString()]
    }
    if (_.isUndefined(path)) {
        return null
    }
    if (_.isNull(path)) {
        return null
    }
    throw new Error(`Unsupported path element type: '${path}'`)
}

export const resolve = (object, path, createTemplates = false) =>
    toPathList(path)
        .reduce((value, pathElement, _index, pathElements) => {
            if (_.isString(pathElement)) {
                if (_.isArray(value)) {
                    // match array item by index
                    const index = parseInt(pathElement)
                    if (isNaN(index)) {
                        throw new Error('Cannot match array item with non-numeric index.')
                    }
                    return value[index]
                }
                if (_.isObjectLike(value)) {
                    // match object property
                    if (value[pathElement] !== undefined) {
                        return value[pathElement]
                    }
                }
            }
            if (_.isPlainObject(pathElement) && _.isArray(value)) {
                // match array item by template
                const item = _.find(value,
                    item => _.isEqual(_.merge({}, item, pathElement), item)
                )
                if (item) {
                    return item
                }
                if (createTemplates) {
                    return pathElement
                }
            }
            pathElements.splice(1) // break out of reduce
            return undefined
        }, object)

// export const resolve = (object, pathToResolve, createTemplates = false) =>
//     toPathList(pathToResolve)
//         .reduce(({path, value}, part) => {
//             if (_.isString(part)) {
//                 if (_.isArray(value)) {
//                     // match array item by index
//                     const index = parseInt(part)
//                     if (isNaN(index)) {
//                         throw new Error('Cannot match array item with non-numeric index.')
//                     }
//                     return {
//                         path: [...path, index],
//                         value: value[index]
//                     }
//                 }
//                 if (_.isPlainObject(value)) {
//                     // match object property
//                     if (value[part] !== undefined) {
//                         return {
//                             path: [...path, part],
//                             value: value[part]
//                         }
//                     }
//                 }
//                 const index = parseInt(part)
//                 if (!path) {
//                     console.error('Invalid path', {pathToResolve, object})
//                     throw new Error('Invalid path')
//                 }
//                 return {
//                     path: [...path, isNaN(index) ? part : index],
//                     value: undefined
//                 }
//             }
//             if (_.isPlainObject(part) && (_.isArray(value) || !value)) {
//                 // match array item by template
//                 const index = _.findIndex(value, item => _.isEqual(_.merge({}, item, part), item))
//                 return index === -1
//                     ? {
//                         path: [...path, value ? value.length : 0],
//                         value: createTemplates ? part : undefined
//                     }
//                     : {
//                         path: [...path, index],
//                         value: value[index]
//                     }
//             }
//             return {
//                 path: undefined,
//                 value: undefined
//             }
//         }, {path: [], value: object}).value

export const selectFrom = (object, path) => resolve(object, path)

export class Mutator {
    constructor(state, path) {
        this.state = {
            root: state
        }
        this.path = toPathList(['root', path])
    }

    getKey(pathState, pathElement) {
        if (_.isPlainObject(pathElement)) {
            return _.findIndex(pathState, item => _.isEqual(_.merge({}, item, pathElement), item))
        }
        return pathElement
    }

    getNext(next, index) {
        const isPositiveInt = str => {
            var n = Math.floor(Number(str))
            return n !== Infinity && String(n) === str && n >= 0
        }
        if (next === undefined) {
            const nextPathElement = this.path[index + 1]
            const isArray = v => (_.isString(v) && isPositiveInt(v)) || _.isPlainObject(v)
            return isArray(nextPathElement) ? [] : {}
        } else {
            return _.clone(next || {})
        }
    }

    mutate(func) {
        const parentPath = _.initial(this.path)
        const pathElement = _.last(this.path)
        const stateElements = _.chain(parentPath)
            .transform(
                (stateElements, pathElement, index, pathElements) => {
                    const stateElement = _.last(stateElements)
                    const key = this.getKey(stateElement, pathElement)
                    if (key === -1) {
                        const next = _.clone(pathElement)
                        if (stateElement) {
                            // add to array
                            stateElement.push(next)
                        } else {
                            // create array
                            const previousElement = _.nth(stateElements, -2)
                            previousElement[pathElements[index - 1]] = [next]
                        }
                        stateElements.push(next)
                    } else {
                        const next = this.getNext(stateElement[key], index)
                        stateElement[key] = next
                        stateElements.push(next)
                    }
                }, [this.state])
            .tail() // drop the synthetic root
            .value()
        const state = _.first(stateElements)
        const pathState = _.last(stateElements)
        const key = this.getKey(pathState, pathElement)
        const pathKey = key === -1
            ? pathState.length
            : key
        func(pathState, pathKey)
        return state
    }

    set(value) {
        return this.mutate((pathState, pathKey) => {
            pathState[pathKey] = _.cloneDeep(value)
        })
    }

    sort(key) {
        return this.mutate((pathState, pathKey) => {
            pathState[pathKey] = _.orderBy(pathState[pathKey], key)
        })
    }

    unique() {
        return this.mutate((pathState, pathKey) => {
            pathState[pathKey] = _.uniq(pathState[pathKey])
        })
    }

    assign(value) {
        return this.mutate((pathState, pathKey) => {
            pathState[pathKey] = _.assign({}, pathState[pathKey], _.cloneDeep(value))
        })
    }

    merge(value) {
        return this.mutate((pathState, pathKey) => {
            pathState[pathKey] = _.merge({}, pathState[pathKey], _.cloneDeep(value))
        })
    }

    push(value) {
        return this.mutate((pathState, pathKey) => {
            if (!pathState[pathKey]) {
                pathState[pathKey] = []
            }
            pathState[pathKey] = [...pathState[pathKey], _.cloneDeep(value)]
        })
    }

    pushUnique(value, key) {
        return this.mutate((pathState, pathKey) => {
            const finder = key
                ? item => resolve(item, key, true) === resolve(value, key, true)
                : item => item === value
            const array = pathState[pathKey]
            if (!array || !_.find(array, finder)) {
                if (!array) {
                    pathState[pathKey] = []
                }
                pathState[pathKey] = [...pathState[pathKey], _.cloneDeep(value)]
            }
        })
    }

    del() {
        return this.mutate((pathState, pathKey) => {
            if (_.isPlainObject(pathState)) {
                delete pathState[pathKey]
            } else if (_.isArray(pathState)) {
                pathState.splice(pathKey, 1)
            } else {
                console.error('Unsupported type to delete from', {pathState, pathKey})
                throw new Error('Unsupported type to delete from')
            }
        })
    }
}
<commit_msg>Cleanup (removed old resolve).<commit_after>import _ from 'lodash'

const DOT_SAFE = '__dotSafe__'
const dotSafeWrap = unsafePath => ({[DOT_SAFE]: unsafePath})
const dotSafeUnwrap = safePath => safePath[DOT_SAFE]

export const dotSafe = dotSafeWrap

export const toPathList = (path, safe = false) => {
    if (_.isArray(path)) {
        return _.chain(path)
            .map(pathElement => toPathList(pathElement, safe))
            .filter(_.identity)
            .flatten()
            .value()
    }
    if (_.isObject(path)) {
        const unwrapped = dotSafeUnwrap(path)
        return _.isUndefined(unwrapped)
            ? path
            : toPathList([unwrapped], true)
    }
    if (_.isString(path)) {
        return safe ? [path] : path.split('.')
    }
    if (_.isNumber(path)) {
        return [path.toString()]
    }
    if (_.isUndefined(path)) {
        return null
    }
    if (_.isNull(path)) {
        return null
    }
    throw new Error(`Unsupported path element type: '${path}'`)
}

export const resolve = (object, path, createTemplates = false) =>
    toPathList(path)
        .reduce((value, pathElement, _index, pathElements) => {
            if (_.isString(pathElement)) {
                if (_.isArray(value)) {
                    // match array item by index
                    const index = parseInt(pathElement)
                    if (isNaN(index)) {
                        throw new Error('Cannot match array item with non-numeric index.')
                    }
                    return value[index]
                }
                if (_.isObjectLike(value)) {
                    // match object property
                    if (value[pathElement] !== undefined) {
                        return value[pathElement]
                    }
                }
            }
            if (_.isPlainObject(pathElement) && _.isArray(value)) {
                // match array item by template
                const item = _.find(value,
                    item => _.isEqual(_.merge({}, item, pathElement), item)
                )
                if (item) {
                    return item
                }
                if (createTemplates) {
                    return pathElement
                }
            }
            pathElements.splice(1) // break out of reduce
            return undefined
        }, object)

export const selectFrom = (object, path) => resolve(object, path)

export class Mutator {
    constructor(state, path) {
        this.state = {
            root: state
        }
        this.path = toPathList(['root', path])
    }

    getKey(pathState, pathElement) {
        if (_.isPlainObject(pathElement)) {
            return _.findIndex(pathState, item => _.isEqual(_.merge({}, item, pathElement), item))
        }
        return pathElement
    }

    getNext(next, index) {
        const isPositiveInt = str => {
            var n = Math.floor(Number(str))
            return n !== Infinity && String(n) === str && n >= 0
        }
        if (next === undefined) {
            const nextPathElement = this.path[index + 1]
            const isArray = v => (_.isString(v) && isPositiveInt(v)) || _.isPlainObject(v)
            return isArray(nextPathElement) ? [] : {}
        } else {
            return _.clone(next || {})
        }
    }

    mutate(func) {
        const parentPath = _.initial(this.path)
        const pathElement = _.last(this.path)
        const stateElements = _.chain(parentPath)
            .transform(
                (stateElements, pathElement, index, pathElements) => {
                    const stateElement = _.last(stateElements)
                    const key = this.getKey(stateElement, pathElement)
                    if (key === -1) {
                        const next = _.clone(pathElement)
                        if (stateElement) {
                            // add to array
                            stateElement.push(next)
                        } else {
                            // create array
                            const previousElement = _.nth(stateElements, -2)
                            previousElement[pathElements[index - 1]] = [next]
                        }
                        stateElements.push(next)
                    } else {
                        const next = this.getNext(stateElement[key], index)
                        stateElement[key] = next
                        stateElements.push(next)
                    }
                }, [this.state])
            .tail() // drop the synthetic root
            .value()
        const state = _.first(stateElements)
        const pathState = _.last(stateElements)
        const key = this.getKey(pathState, pathElement)
        const pathKey = key === -1
            ? pathState.length
            : key
        func(pathState, pathKey)
        return state
    }

    set(value) {
        return this.mutate((pathState, pathKey) => {
            pathState[pathKey] = _.cloneDeep(value)
        })
    }

    sort(key) {
        return this.mutate((pathState, pathKey) => {
            pathState[pathKey] = _.orderBy(pathState[pathKey], key)
        })
    }

    unique() {
        return this.mutate((pathState, pathKey) => {
            pathState[pathKey] = _.uniq(pathState[pathKey])
        })
    }

    assign(value) {
        return this.mutate((pathState, pathKey) => {
            pathState[pathKey] = _.assign({}, pathState[pathKey], _.cloneDeep(value))
        })
    }

    merge(value) {
        return this.mutate((pathState, pathKey) => {
            pathState[pathKey] = _.merge({}, pathState[pathKey], _.cloneDeep(value))
        })
    }

    push(value) {
        return this.mutate((pathState, pathKey) => {
            if (!pathState[pathKey]) {
                pathState[pathKey] = []
            }
            pathState[pathKey] = [...pathState[pathKey], _.cloneDeep(value)]
        })
    }

    pushUnique(value, key) {
        return this.mutate((pathState, pathKey) => {
            const finder = key
                ? item => resolve(item, key, true) === resolve(value, key, true)
                : item => item === value
            const array = pathState[pathKey]
            if (!array || !_.find(array, finder)) {
                if (!array) {
                    pathState[pathKey] = []
                }
                pathState[pathKey] = [...pathState[pathKey], _.cloneDeep(value)]
            }
        })
    }

    del() {
        return this.mutate((pathState, pathKey) => {
            if (_.isPlainObject(pathState)) {
                delete pathState[pathKey]
            } else if (_.isArray(pathState)) {
                pathState.splice(pathKey, 1)
            } else {
                console.error('Unsupported type to delete from', {pathState, pathKey})
                throw new Error('Unsupported type to delete from')
            }
        })
    }
}
<|endoftext|>


<commit_before>import _ from "../util/index";
import { JSCRIPT_VERSION } from "../const";
import { $Document, DOM } from "../types";

// Inspired by the article written by Daniel Buchner:
// http://www.backalleycoder.com/2014/04/18/element-queries-from-the-feet-up/

// IE8 fails with about:blank, use better-dom-legacy.html instead
var SANDBOX_URL = JSCRIPT_VERSION < 9 ? _.getLegacyFile("html") : "about:blank";

// NOTE: Chrome/Safari have issue with focusing on the <object>:
// https://code.google.com/p/chromium/issues/detail?id=255150

_.register({
    context(name, callback) {
        var node = this[0],
            doc = node.ownerDocument,
            contexts = this._["<%= prop('context') %>"];

        if (name in contexts) {
            let rec = contexts[name];

            if (typeof callback === "function") {
                _.safeCall(this, callback, rec[1]);
            }

            return rec[0];
        }

        var ctx = DOM.create("div[style=overflow:hidden]", [name]);
        var wrapper = ctx[0];
        var record = [ctx];
        var object, subtree;
        var ready = () => {
            // apply user-defined styles for the context
            // need to add class in ready callback because of IE8
            ctx.addClass(name);

            record[1] = new $Document(subtree || object.contentDocument);

            if (typeof callback === "function") {
                callback.call(this, record[1]);
            }
        };
        /* istanbul ignore if */
        if (JSCRIPT_VERSION < 9) {
            // IE8 is buggy, use innerHTML and better-dom-legacy.html
            // use overflow and extra size to get rid of the frame
            wrapper.innerHTML = DOM.emmet("object[data=`{0}` type=`text/html` style=`left:-2px;top:-2px`]", [SANDBOX_URL]);

            object = wrapper.firstChild;
            // IE8 does not support onload - use timeout instead
            DOM.requestFrame(function repeat() {
                try {
                    subtree = object.contentDocument;
                } catch (err) {
                    return DOM.requestFrame(repeat);
                }
                // use the trick below to hide frame border in IE8
                wrapper.onresize = function resizing() {
                    wrapper.onresize = null;

                    object.width = wrapper.offsetWidth + 4;
                    object.height = wrapper.offsetHeight + 4;

                    DOM.requestFrame(() => {
                        wrapper.onresize = resizing;
                    });
                };

                ready();
            });
        } else {
            object = doc.createElement("object");
            object.type = "text/html";
            object.onload = ready;

            if (!JSCRIPT_VERSION) {
                object.data = SANDBOX_URL;
            }

            wrapper.appendChild(object);
        }

        object.style.position = "absolute";
        object.width = "100%";
        object.height = "100%";

        this.before(ctx);

        if (JSCRIPT_VERSION > 8) {
            // IE needs doesn't work if set data attribute before
            // appending element to the DOM
            object.data = SANDBOX_URL;
            // use calc to add extra sizes to cut the black border
            object.style.cssText += "width:calc(100% + 4px);height:calc(100% + 4px);left:-2px;top:-2px";
        }

        if (ctx.css("position") === "static") {
            ctx.css("position", "relative");
        }

        return contexts[name] = record;
    }
});
<commit_msg>minor improvements in the context method<commit_after>import _ from "../util/index";
import { JSCRIPT_VERSION } from "../const";
import { $Document, DOM } from "../types";

// Inspired by the article written by Daniel Buchner:
// http://www.backalleycoder.com/2014/04/18/element-queries-from-the-feet-up/

// IE8 fails with about:blank, use better-dom-legacy.html instead
var SANDBOX_URL = JSCRIPT_VERSION < 9 ? _.getLegacyFile("html") : "about:blank";

// Chrome/Safari serious bug with focusing on the <object>:
// https://code.google.com/p/chromium/issues/detail?id=255150

_.register({
    context(name, callback) {
        var node = this[0],
            doc = node.ownerDocument,
            contexts = this._["<%= prop('context') %>"];

        if (name in contexts) {
            let rec = contexts[name];

            if (typeof callback === "function") {
                _.safeCall(this, callback, rec[1]);
            }

            return rec[0];
        }

        var ctx = DOM.create("div[style=overflow:hidden]", [name]);
        var wrapper = ctx[0];
        var record = [ctx];
        var object, subtree;
        var ready = () => {
            // apply user-defined styles for the context
            // need to add class in ready callback because of IE8
            ctx.addClass(name);

            record[1] = new $Document(subtree || object.contentDocument);

            if (typeof callback === "function") {
                callback.call(this, record[1]);
            }
        };
        /* istanbul ignore if */
        if (JSCRIPT_VERSION < 9) {
            // IE8 is buggy, use innerHTML and better-dom-legacy.html
            wrapper.innerHTML = DOM.emmet("object[data=`{0}` type=`text/html`]", [SANDBOX_URL]);

            object = wrapper.firstChild;
            // IE8 does not support onload - use timeout instead
            DOM.requestFrame(function repeat() {
                try {
                    subtree = object.contentDocument;
                } catch (err) {
                    return DOM.requestFrame(repeat);
                }
                var frameId;
                // add extra sizes and cut the frame border
                wrapper.attachEvent("onresize", () => {
                    frameId = frameId || DOM.requestFrame(() => {
                        object.width = wrapper.offsetWidth + 4;
                        object.height = wrapper.offsetHeight + 4;

                        frameId = null;
                    });
                });

                ready();
            });
        } else {
            object = doc.createElement("object");
            object.type = "text/html";
            object.onload = ready;

            if (!JSCRIPT_VERSION) {
                object.data = SANDBOX_URL;
            }

            wrapper.appendChild(object);
        }

        object.style.position = "absolute";
        object.width = "100%";
        object.height = "100%";

        this.before(ctx);

        if (JSCRIPT_VERSION) {
            // IE doesn't work if to set the data attribute before
            // appending element to the DOM
            object.data = SANDBOX_URL;
            // use calc to add extra sizes and cut the frame border
            object.style.cssText = "width:calc(100% + 4px);height:calc(100% + 4px);left:-2px;top:-2px;position:absolute";
        }

        if (ctx.css("position") === "static") {
            ctx.css("position", "relative");
        }

        return contexts[name] = record;
    }
});
<|endoftext|>


<commit_before>/*jslint maxlen:256, browser:true*/
/*global ko, $, jasmine, describe, it, beforeEach, afterEach, spyOn, expect, runs, waitsFor, getMajorMinorVersion, testWidgetOptions*/
(function () {
    'use strict';

    if (getMajorMinorVersion($.ui.version) === '1.8') {
        // spinner was introduced in 1.9
        return;
    }

    describe('The spinner binding', function () {
        it('should handle each option of the widget', function () {
            testWidgetOptions('spinner', {
                culture: [null, 'fr'],
                disabled: [false, true],
                icons: [{ down: 'ui-icon-triangle-1-s', up: 'ui-icon-triangle-1-n' }, { down: 'custom-down-icon', up: 'custom-up-icon'}],
                incremental: [true, false],
                max: [null, 50],
                min: [null, 10],
                numberFormat: [null, 'n'],
                page: [10, 5],
                step: [1, 2]
            });
        });

        it('should handle each event of the widget', function () {
            var $element, vm;

            $element = $('

').appendTo('body');
            vm = { createEventHandler: jasmine.createSpy() };

            ko.applyBindings(vm, $element[0]);

            expect(vm.createEventHandler).toHaveBeenCalled();

            ko.removeNode($element[0]);
        });

        it('should write the widget\'s value to the viewmodel\'s bound property when it changes.', function () {
            var $element, flag = false, vm;

            $element = $('<input data-bind="spinner: { value: value }" />').appendTo('body');

            vm = { value: ko.observable(1) };
            ko.applyBindings(vm, $element[0]);

            expect(vm.value.peek()).toEqual(1);
            $element.spinner('value', 55);
            expect(vm.value.peek()).toEqual(55);
            $element.spinner('stepUp');
            expect(vm.value.peek()).toEqual(56);

            // This spec tests that the view model's bound property is only updated when
            // the spinner's input is blurred.
            // The spinner widget ensures that the focus is set to the input when the up-
            // or down button is clicked, but IE raises the focus event asynchronously,
            // so we also have to test it asynchronously.
            runs(function () {
                $element.spinner('widget').find('.ui-spinner-up')
                    .mousedown()
                    .mouseup();
                setTimeout(function () {
                    expect($element.spinner('value')).toEqual(57);
                    expect(vm.value.peek()).toEqual(56); // Focus is still on the input, so the spinner hasn't fired spinchange yet.
                    $element.blur();
                    flag = true; // open the latch
                }, 50);
            });

            waitsFor(function () {
                return flag;
            }, 'latch wasn\'t opened', 1000);

            runs(function () {
                expect(vm.value.peek()).toEqual(57); // *Now* the observable should be mutated.

                ko.removeNode($element[0]);
            });
        });

        it('should write the widget\'s value immediately to the viewmodel\'s bound property when it changes if "valueUpdate" binding is also used on the input.', function () {
            var $element, vm;

            $element = $('<input data-bind="valueUpdate: \'afterkeydown\', spinner: { value: value }" />').appendTo('body');

            vm = { value: ko.observable(100) };
            ko.applyBindings(vm, $element[0]);
            $element.spinner('widget').find('.ui-spinner-up')
                .mousedown()
                .mouseup();
            expect(vm.value.peek()).toEqual(101);

            ko.removeNode($element[0]);
        });

        it('should write the element to the widget observable', function () {
            var $element, vm, disabled;

            $element = $('

').appendTo('body');
            vm = { widget: ko.observable() };
            ko.applyBindings(vm, $element[0]);

            expect(vm.widget()).toBeDefined();

            disabled = vm.widget().spinner('option', 'disabled');

            expect(disabled).toBe(true);

            ko.removeNode($element[0]);
        });
    });
}());<commit_msg>Fixed the failing spinner spec.<commit_after>/*jslint maxlen:256, browser:true*/
/*global ko, $, jasmine, describe, it, beforeEach, afterEach, spyOn, expect, runs, waitsFor, getMajorMinorVersion, testWidgetOptions*/
(function () {
    'use strict';

    if (getMajorMinorVersion($.ui.version) === '1.8') {
        // spinner was introduced in 1.9
        return;
    }

    describe('The spinner binding', function () {
        it('should handle each option of the widget', function () {
            testWidgetOptions('spinner', {
                culture: [null, 'fr'],
                disabled: [false, true],
                icons: [{ down: 'ui-icon-triangle-1-s', up: 'ui-icon-triangle-1-n' }, { down: 'custom-down-icon', up: 'custom-up-icon'}],
                incremental: [true, false],
                max: [null, 50],
                min: [null, 10],
                numberFormat: [null, 'n'],
                page: [10, 5],
                step: [1, 2]
            });
        });

        it('should handle each event of the widget', function () {
            var $element, vm;

            $element = $('

').appendTo('body');
            vm = { createEventHandler: jasmine.createSpy() };

            ko.applyBindings(vm, $element[0]);

            expect(vm.createEventHandler).toHaveBeenCalled();

            ko.removeNode($element[0]);
        });

        it('should write the widget\'s value to the viewmodel\'s bound property when it changes.', function () {
            var $element, flag = false, vm;

            $element = $('<input data-bind="spinner: { value: value }" />').appendTo('body');

            vm = { value: ko.observable(1) };
            ko.applyBindings(vm, $element[0]);

            expect(vm.value.peek()).toEqual(1);
            $element.spinner('value', 55);
            expect(vm.value.peek()).toEqual(55);
            $element.spinner('stepUp');
            expect(vm.value.peek()).toEqual(56);

            // This spec tests that the view model's bound property is only updated when
            // the spinner's input is blurred.
            // The spinner widget ensures that the focus is set to the input when the up-
            // or down button is clicked, but IE raises the focus/blur events
            // asynchronously, so we also have to test it asynchronously.
            runs(function () {
                $element.spinner('widget').find('.ui-spinner-up')
                    .mousedown()
                    .mouseup();
                setTimeout(function () {
                    expect($element.spinner('value')).toEqual(57);
                    expect(vm.value.peek()).toEqual(56); // Focus is still on the input, so the spinner hasn't fired spinchange yet.
                    $element.blur();
                    setTimeout(function () { flag = true; }, 150); // open the latch
                }, 150);
            });

            waitsFor(function () {
                return flag;
            }, 'latch wasn\'t opened', 1000);

            runs(function () {
                expect(vm.value.peek()).toEqual(57); // *Now* the observable should be mutated.

                ko.removeNode($element[0]);
            });
        });

        it('should write the widget\'s value immediately to the viewmodel\'s bound property when it changes if "valueUpdate" binding is also used on the input.', function () {
            var $element, vm;

            $element = $('<input data-bind="valueUpdate: \'afterkeydown\', spinner: { value: value }" />').appendTo('body');

            vm = { value: ko.observable(100) };
            ko.applyBindings(vm, $element[0]);
            $element.spinner('widget').find('.ui-spinner-up')
                .mousedown()
                .mouseup();
            expect(vm.value.peek()).toEqual(101);

            ko.removeNode($element[0]);
        });

        it('should write the element to the widget observable', function () {
            var $element, vm, disabled;

            $element = $('

').appendTo('body');
            vm = { widget: ko.observable() };
            ko.applyBindings(vm, $element[0]);

            expect(vm.widget()).toBeDefined();

            disabled = vm.widget().spinner('option', 'disabled');

            expect(disabled).toBe(true);

            ko.removeNode($element[0]);
        });
    });
}());<|endoftext|>


<commit_before>
function updateQueryStringParameter(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
  var separator = uri.indexOf('?') !== -1 ? "&" : "?";
  if (uri.match(re)) {
    return uri.replace(re, '$1' + key + "=" + value + '$2');
  }
  else {
    return uri + separator + key + "=" + value;
  }
}

var QueryString = function () {
  // This function is anonymous, is executed immediately and
  // the return value is assigned to QueryString!
  var query_string = {};
  var query = window.location.search.substring(1);
  var vars = query.split("&");
  for (var i=0;i<vars.length;i++) {
    var pair = vars[i].split("=");
        // If first entry with this name
    if (typeof query_string[pair[0]] === "undefined") {
      query_string[pair[0]] = decodeURIComponent(pair[1]);
        // If second entry with this name
    } else if (typeof query_string[pair[0]] === "string") {
      var arr = [ query_string[pair[0]],decodeURIComponent(pair[1]) ];
      query_string[pair[0]] = arr;
        // If third or later entry with this name
    } else {
      query_string[pair[0]].push(decodeURIComponent(pair[1]));
    }
  }
    return query_string;
}();

function isNumber(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

var defaultColors = [
  '#113F8C',
  '#01A4A4',
  '#00A1CB',
  '#61AE24',
  '#D0D102',
  '#32742C',
  '#D70060',
  '#E54028',
  '#F18D05'
];

var channel = QueryString.channel || 'pubnub-sensor-network';
var subscribe_key = QueryString.subscribe_key || 'sub-c-5f1b7c8e-fbee-11e3-aa40-02ee2ddab7fe';

var builder = function(params) {

  var self = this;

  self.cols = [];
  self.labels = {};
  self.colors = {};

  self.refresh = function(params) {

    var params = params || {};

    self.type = params.type || self.type || 'spline';
    self.limit = params.limit || self.limit || 5;
    self.xlabel = params.xlabel || self.xlabel || '';
    self.ylabel = params.ylabel || self.ylabel || '';

    self.rate = params.rate || self.rate || 1000;
    self.duration = params.duration || self.duration || 250;

    if(typeof self.history == "undefined") {
      self.history = false;
    }

    if(typeof params.history !== "undefined") {
      self.history = params.history;
    }

    if(typeof self.xgrid == "undefined") {
      self.xgrid = false;
    }

    if(typeof params.xgrid !== "undefined") {
      self.xgrid = params.xgrid;
    }

    if(typeof self.ygrid == "undefined") {
      self.ygrid = false;
    }

    if(typeof params.ygrid !== "undefined") {
      self.ygrid = params.ygrid;
    }

    if(typeof self.points == "undefined") {
      self.points = true;
    }

    if(typeof params.points !== "undefined") {
      self.points = params.points;
    }

    if(typeof self.tooltips == "undefined") {
      self.tooltips = true;
    }

    if(typeof params.tooltips !== "undefined") {
      self.tooltips = params.tooltips;
    }

    self.flow = false;

    if(self.type == "spline" ||
      self.type == "area" ||
      self.type == "area-spline" ||
      self.type == "step" ||
      self.type == "area-step" ||
      self.type == "scatter") {

      self.flow = true;

      $('#limit-row, #points-row, #xgrid-row, #ygrid-row').show();

    } else {
      $('#limit-row, #points-row, #xgrid-row, #ygrid-row').hide();
    }

    self.chart = eon.chart({
      pubnub: self.pubnub,
      channel: channel,
      history: self.history,
      flow: self.flow,
      rate: self.rate,
      limit: self.limit,
      generate: {
        bindto: '#chart',
        data: {
          x: self.x,
          type: self.type,
          colors: self.colors
        },
        transition: {
          duration: self.duration
        },
        axis: {
          x: {
            label: self.xlabel,
          },
          y: {
            label: self.ylabel
          }
        },
        grid: {
          x: {
            show: self.xgrid
          },
          y: {
            show: self.ygrid
          }
        },
        tooltip: {
          show: self.tooltips
        },
        point: {
          show: self.points
        }
      },
      transform: function(message) {

        var message = eon.c.flatten(message);
        var o = {};

        for(index in message) {
          if(self.cols.indexOf(index)){
            o[self.labels[index] || index] = message[index];
          }
        }

        return {
          eon: o
        };

      }
    });

    self.pedit.subscribe({
      channel: channel,
      message: function(data, a, b) {

        var data = eon.c.flatten(data);

        for(var key in data) {

          var $row = $('[data-key="' + key + '"]');
          var value = data[key];

          if(!isNaN(value)) {

            if($row.length) {

              $row.find('.val').text(value)

            } else {

              self.cols.push(key);

              var color = defaultColors[$('tr').length % defaultColors.length];

              var $row = $('\

 \
                  ' + key + '	 \
                  ' + value + '	 \
                   \
                    <dciv class="input-group colorpick" data-key="' + key + '"> \
                        <input type="text" value="' + color + '" class="form-control" /> \
                         \

 \
                  	 \
                   \
                  <input type="checkbox" class="toggle" checked data-toggle="toggle"> \
                  	 \

');

              var picker = $row.find('.colorpick').colorpicker();

              self.colors[key] = color;
              picker.on('changeColor.colorpicker', function(event){

                self.colors[$(this).closest('tr').attr('data-key')] = event.color.toHex();
                self.embed();

              });

              $row.find('#key-edit').editable({
                  unsavedclass: null,
                  success: function(response, newValue) {

                    var thisKey = $(this).closest('tr').attr('data-key');

                    self.labels[thisKey] = newValue;

                    // colors map to labels in c3
                    self.colors[newValue] = self.colors[thisKey];
                    delete self.colors[thisKey];

                    self.refresh();

                  }
              });

              $row.find('.toggle').bootstrapToggle('on');

              $row.find('.toggle').change(function() {

                var thisKey = $(this).closest('tr').attr('data-key');
                var isChecked = $(this).prop('checked');

                if(typeof (isChecked) !== "undefined") {

                  if(isChecked){

                    self.cols.push(thisKey);
                    self.embed();

                  } else {

                    for(var i in self.cols) {

                      if(self.cols[i] == thisKey) {
                        self.cols.splice(i, 1);
                        self.refresh();
                      }

                    }

                  }

                }

              });

              $('#kvs').append($row);
              self.embed();

            }

          }

        }

      }
    });

    self.embed();

  }

  self.embed = function() {

    var embedsrc = '' +
      '


<commit_before>var osmb = function(map) {
    this.offset = { x:0, y:0 };
    map.addLayer(this);
};

var proto = osmb.prototype;

proto.onAdd = function(map) {
    this.map = map;
    Layers.appendTo(map._panes.overlayPane);
    maxZoom = map._layersMaxZoom;

    var off = this.getOffset(),
        po = map.getPixelOrigin();
    setSize({ w:map._size.x, h:map._size.y });
    setOrigin({ x:po.x-off.x, y:po.y-off.y });
    setZoom(map._zoom);

    Layers.setPosition(-off.x, -off.y);

    map.on({
        move:      this.onMove,
        moveend:   this.onMoveEnd,
        zoomstart: this.onZoomStart,
        zoomend:   this.onZoomEnd,
        resize:    this.onResize
    }, this);

    if (map.options.zoomAnimation) {
        map.on('zoomanim', this.onZoom, this);
    }

    map.attributionControl.addAttribution(ATTRIBUTION);

    Data.update();
    renderAll(); // in case of re-adding this layer
};

proto.onRemove = function() {
    var map = this.map;
    map.attributionControl.removeAttribution(ATTRIBUTION);

    map.off({
        move:      this.onMove,
        moveend:   this.onMoveEnd,
        zoomstart: this.onZoomStart,
        zoomend:   this.onZoomEnd,
        resize:    this.onResize
    }, this);

    if (map.options.zoomAnimation) {
        map.off('zoomanim', this.onZoom, this);
    }
    Layers.remove();
    map = null;
};

proto.onMove = function(e) {
    var off = this.getOffset();
    setCamOffset({ x:this.offset.x-off.x, y:this.offset.y-off.y });
    render();
};

proto.onMoveEnd = function(e) {
    if (this.skipMoveEnd) { // moveend is also fired after zoom
        this.skipMoveEnd = false;
        return;
    }

    var map = this.map,
        off = this.getOffset(),
        po = map.getPixelOrigin();

    this.offset = off;
    Layers.setPosition(-off.x, -off.y);
    setCamOffset({ x:0, y:0 });

    setSize({ w:map._size.x, h:map._size.y }); // in case this is triggered by resize
    setOrigin({ x:po.x-off.x, y:po.y-off.y });
    onMoveEnd(e);
};

proto.onZoomStart = function(e) {
    onZoomStart(e);
};

proto.onZoom = function(e) {
//    var map = this.map,
//        scale = map.getZoomScale(e.zoom),
//        offset = map._getCenterOffset(e.center).divideBy(1 - 1/scale),
//        viewportPos = map.containerPointToLayerPoint(map.getSize().multiplyBy(-1)),
//        origin = viewportPos.add(offset).round();
//
//    this.container.style[L.DomUtil.TRANSFORM] = L.DomUtil.getTranslateString((origin.multiplyBy(-1).add(this.getOffset().multiplyBy(-1)).multiplyBy(scale).add(origin))) + ' scale(' + scale + ') ';
//    isZooming = true;
};

proto.onZoomEnd = function(e) {
    var map = this.map,
        off = this.getOffset(),
        po = map.getPixelOrigin();

    setOrigin({ x:po.x-off.x, y:po.y-off.y });
    onZoomEnd({ zoom:map._zoom });
    this.skipMoveEnd = true;
};

proto.onResize = function() {};

proto.getOffset = function() {
    return L.DomUtil.getPosition(this.map._mapPane);
};
<commit_msg>handling Leaflet ViewReset event<commit_after>var osmb = function(map) {
    this.offset = { x:0, y:0 };
    map.addLayer(this);
};

var proto = osmb.prototype;

proto.onAdd = function(map) {
    this.map = map;
    Layers.appendTo(map._panes.overlayPane);
    maxZoom = map._layersMaxZoom;

    var off = this.getOffset(),
        po = map.getPixelOrigin();
    setSize({ w:map._size.x, h:map._size.y });
    setOrigin({ x:po.x-off.x, y:po.y-off.y });
    setZoom(map._zoom);

    Layers.setPosition(-off.x, -off.y);

    map.on({
        move:      this.onMove,
        moveend:   this.onMoveEnd,
        zoomstart: this.onZoomStart,
        zoomend:   this.onZoomEnd,
        resize:    this.onResize,
        viewreset: this.onViewReset
    }, this);

    if (map.options.zoomAnimation) {
        map.on('zoomanim', this.onZoom, this);
    }

    if (map.attributionControl) {
        map.attributionControl.addAttribution(ATTRIBUTION);
    }

    Data.update();
    renderAll(); // in case of re-adding this layer
};

proto.onRemove = function() {
    var map = this.map;
    if (map.attributionControl) {
        map.attributionControl.removeAttribution(ATTRIBUTION);
    }

    map.off({
        move:      this.onMove,
        moveend:   this.onMoveEnd,
        zoomstart: this.onZoomStart,
        zoomend:   this.onZoomEnd,
        resize:    this.onResize,
        viewreset: this.onViewReset
    }, this);

    if (map.options.zoomAnimation) {
        map.off('zoomanim', this.onZoom, this);
    }
    Layers.remove();
    map = null;
};

proto.onMove = function(e) {
    /*<debug*/console.log('Leaflet: onMove');/*>*/
    var off = this.getOffset();
    setCamOffset({ x:this.offset.x-off.x, y:this.offset.y-off.y });
    render();
};

proto.onMoveEnd = function(e) {
    if (this.skipMoveEnd) { // moveend is also fired after zoom
        this.skipMoveEnd = false;
        return;
    }
    /*<debug*/console.log('Leaflet: onMoveEnd');/*>*/

    var map = this.map,
        off = this.getOffset(),
        po = map.getPixelOrigin();

    this.offset = off;
    Layers.setPosition(-off.x, -off.y);
    setCamOffset({ x:0, y:0 });

    setSize({ w:map._size.x, h:map._size.y }); // in case this is triggered by resize
    setOrigin({ x:po.x-off.x, y:po.y-off.y });
    onMoveEnd(e);
};

proto.onZoomStart = function(e) {
    /*<debug*/console.log('Leaflet: onZoomStart');/*>*/
    onZoomStart(e);
};

proto.onZoom = function(e) {
    /*<debug*/console.log('Leaflet: onZoom');/*>*/
//    var map = this.map,
//        scale = map.getZoomScale(e.zoom),
//        offset = map._getCenterOffset(e.center).divideBy(1 - 1/scale),
//        viewportPos = map.containerPointToLayerPoint(map.getSize().multiplyBy(-1)),
//        origin = viewportPos.add(offset).round();
//
//    this.container.style[L.DomUtil.TRANSFORM] = L.DomUtil.getTranslateString((origin.multiplyBy(-1).add(this.getOffset().multiplyBy(-1)).multiplyBy(scale).add(origin))) + ' scale(' + scale + ') ';
//    isZooming = true;
};

proto.onZoomEnd = function(e) {
    /*<debug*/console.log('Leaflet: onZoomEnd');/*>*/
    var map = this.map,
        off = this.getOffset(),
        po = map.getPixelOrigin();

    setOrigin({ x:po.x-off.x, y:po.y-off.y });
    onZoomEnd({ zoom:map._zoom });
    this.skipMoveEnd = true;
};

proto.onResize = function() {
    /*<debug*/console.log('Leaflet: onResize');/*>*/
};

proto.onViewReset = function() {
    /*<debug*/console.log('Leaflet: onViewReset');/*>*/
    var off = this.getOffset();

    this.offset = off;
    Layers.setPosition(-off.x, -off.y);
    setCamOffset({ x:0, y:0 });
};

proto.getOffset = function() {
    return L.DomUtil.getPosition(this.map._mapPane);
};
<|endoftext|>


<commit_before>

var
	local = require('../req').local,

	clc   = local('cli-color'),
	erase = clc.move.up(1) + clc.erase.line;

module.exports = function (instance, console, instantRun)
{
	console.warn('something running');
	//instance.eval(instantRun.eval, instance.context, 'repl', new Function);
	//instance.clearLine();
	console.writer.write('stdout', erase);
	instance.eval(instantRun.eval, instance.context);
	instance.displayPrompt();
}
<commit_msg>instarun with string.<commit_after>

var
	local = require('../req').local,

	clc   = local('cli-color'),
	erase = clc.move.up(1) + clc.erase.line;

module.exports = function (instance, console, instantRun)
{
	if (instantRun.eval)
	{
		evalString(instance, console, instantRun.eval);
	}
}

function evalString (instance, console, string)
{
	/* instance.clearLine(); */
	//console.writer.write('stdout', erase);

	/* instance.eval(string, instance.context, 'repl', new Function); */
	instance.eval(string, instance.context);
	instance.displayPrompt();
}
<|endoftext|>


<commit_before>// Opening for events
const eventTitles = getElementsByClassName('event-title')
const eventSubtitles = getElementsByClassName('event-subtitle')
const eventDetails = getElementsByClassName('event-details')
for (let i = 0; i < eventTitles.length; i++) {
	// Fade in
	eventTitles[i].classList.add('fade-move')
	eventSubtitles[i].classList.add('fade-move')
	eventDetails[i].classList.add('fade-move')
	// Email signup form
	// If background image is so complex that email signup form needs a dark background instead of a transparent background...
	const emailBox = getElementsByClassName('email-box')[i]
	// emailBox with class `email container background` has conditional visibility in Webflow, so Webflow tags a new class called `w-condition-invisible` if collection determines it’s invisible
	const visible = emailBox.querySelector('div.email-container-background.w-condition-invisible') === null
	changeEmailContainerBackground({ visible })
}

// Reg Form elements
const regFormButtons = getElementsByClassName('button register')
const regFormBg = getElementByClassName('reg-form-background')
const regFormContainer = getElementByClassName('reg-form-container')

const showRegForm = () => {
	showElement(regFormBg)
	flexElement(regFormContainer)
	setTimeout(() => {
		fadeInElement(regFormBg)
		fadeInElement(regFormContainer)
		// Prevent background to scroll
		document.body.style.overflow = 'hidden'
	}, 100)
}

const closeRegForm = () => {
	// Reallow background to scroll
	document.body.style.overflow = 'visible'
	fadeOutElement(regFormBg)
	fadeOutElement(regFormContainer)
	setTimeout(() => {
		hideElement(regFormBg)
		hideElement(regFormContainer)
	}, 200)
}

// Event listener for if reg form is opened...
for (let i = 0; i < regFormButtons.length; i++) {
	onClick(regFormButtons[i], () => showRegForm())
}
// ...and closed.
const regFormClose = getElementByClassName('reg-form-close')
onClick(regFormClose, () => closeRegForm())

// Event summary “Read more...” expansion
getElementByClassName('text read-more').addEventListener('mouseover', () => {
	hideElement(getElementByClassName('text read-more'))
	hideElement(getElementByClassName('text summary'))
	getElementByClassName('text description').classList.add('display')
	setTimeout(() => getElementByClassName('text description display').classList.add('fade'), 100)
})<commit_msg>009 - flex css<commit_after>// Opening for events
const eventTitles = getElementsByClassName('event-title')
const eventSubtitles = getElementsByClassName('event-subtitle')
const eventDetails = getElementsByClassName('event-details')
for (let i = 0; i < eventTitles.length; i++) {
	// Fade in
	eventTitles[i].classList.add('fade-move')
	eventSubtitles[i].classList.add('fade-move')
	eventDetails[i].classList.add('fade-move')
	// Email signup form
	// If background image is so complex that email signup form needs a dark background instead of a transparent background...
	const emailBox = getElementsByClassName('email-box')[i]
	// emailBox with class `email container background` has conditional visibility in Webflow, so Webflow tags a new class called `w-condition-invisible` if collection determines it’s invisible
	const visible = emailBox.querySelector('div.email-container-background.w-condition-invisible') === null
	changeEmailContainerBackground({ visible })
}

// Reg Form elements
const regFormButtons = getElementsByClassName('button register')
const regFormBg = getElementByClassName('reg-form-background')
const regFormContainer = getElementByClassName('reg-form-container')

const showRegForm = () => {
	showElement(regFormBg)
	setTimeout(() => {
		fadeInElement(regFormBg)
		// Prevent background to scroll
		document.body.style.overflow = 'hidden'
	}, 100)
}

const closeRegForm = () => {
	// Reallow background to scroll
	document.body.style.overflow = 'visible'
	fadeOutElement(regFormBg)
	setTimeout(() => {
		hideElement(regFormBg)
	}, 200)
}

// Event listener for if reg form is opened...
for (let i = 0; i < regFormButtons.length; i++) {
	onClick(regFormButtons[i], () => showRegForm())
}
// ...and closed.
const regFormClose = getElementByClassName('reg-form-close')
onClick(regFormClose, () => closeRegForm())

// Event summary “Read more...” expansion
getElementByClassName('text read-more').addEventListener('mouseover', () => {
	hideElement(getElementByClassName('text read-more'))
	hideElement(getElementByClassName('text summary'))
	getElementByClassName('text description').classList.add('display')
	setTimeout(() => getElementByClassName('text description display').classList.add('fade'), 100)
})<|endoftext|>


<commit_before>
import ObserverEvent from './ObserverEvent'

function Observer() {
  this._eventListeners = {}
}

function getListenersByName (observer, name) {
  let listenerArr = observer._eventListeners[name]

  return listenerArr || []
}

function appendListenerByName (observer, name, func) {
  let listenerArr = getListenersByName(observer, name)

  listenerArr.push(func)
  observer._eventListeners[name] = listenerArr
}

function removeListenerByName(observer, name, func) {
  if (func == null) {

    delete observer._eventListeners[name];

  } else {
    let listenerArr = getListenersByName(observer, name)
    let index = listenerArr.indexOf(func)

    if ( index > -1 ) listenerArr.splice(index, 1)
  }
}

function runListener(listener, name, data, label, now, args) {
  listener.call(null, new ObserverEvent(name, data, label, now))
}

Observer.prototype = {

  on: function (name, func) {

    appendListenerByName(this, name, func)
  },

  off: function (name, func) {

    removeListenerByName(this, name, func)
  },

  trigger: function (name, data = null, now = null, ...args) {

    let [evtType, label] = name.split(':')
    let evtListenerArr = getListenersByName(this, evtType) || []
    let listenerArr = getListenersByName(this, name) || []

    evtListenerArr.forEach((listener)=> runListener(listener, name, data, label, now, args))
    label && listenerArr.forEach((listener)=> runListener(listener, name, data, label, now, args))
  }
};

Observer.buildName = function (name, type) {

  return type ?`${name}:${type}`: name;
}

export default Observer

<commit_msg>remove all listeners  if input parameters is zero<commit_after>
import ObserverEvent from './ObserverEvent'

function Observer() {
  this._eventListeners = {}
}

function getListenersByName (observer, name) {
  let listenerArr = observer._eventListeners[name]

  return listenerArr || []
}

function appendListenerByName (observer, name, func) {
  let listenerArr = getListenersByName(observer, name)

  listenerArr.push(func)
  observer._eventListeners[name] = listenerArr
}

function removeListenerByName(observer, name, func) {
  if (func == null) {

    delete observer._eventListeners[name];

  }else if (name == null && func == null) {

    observer._eventListeners = {};

  }else {
    let listenerArr = getListenersByName(observer, name)
    let index = listenerArr.indexOf(func)

    if ( index > -1 ) listenerArr.splice(index, 1)
  }
}

function runListener(listener, name, data, label, now, args) {
  listener.call(null, new ObserverEvent(name, data, label, now))
}

Observer.prototype = {

  on: function (name, func) {

    appendListenerByName(this, name, func)
  },

  off: function (name, func) {

    removeListenerByName(this, name, func)
  },

  trigger: function (name, data = null, now = null, ...args) {

    let [evtType, label] = name.split(':')
    let evtListenerArr = getListenersByName(this, evtType) || []
    let listenerArr = getListenersByName(this, name) || []

    evtListenerArr.forEach((listener)=> runListener(listener, name, data, label, now, args))
    label && listenerArr.forEach((listener)=> runListener(listener, name, data, label, now, args))
  }
};

Observer.buildName = function (name, type) {

  return type ?`${name}:${type}`: name;
}

export default Observer

<|endoftext|>


<commit_before>'use strict';

var assign          = require('es5-ext/object/assign')
  , create          = require('es5-ext/object/create')
  , callable        = require('es5-ext/object/valid-callable')
  , d               = require('d')
  , lazy            = require('d/lazy')
  , injectPrimitive = require('../utils/inject-primitive')
  , observePass     = require('../utils/observe-pass-through')
  , DbjsError       = require('../error')
  , ObjectsSet      = require('../objects-set')
  , Observable      = require('./observable')
  , DynamicMultiple = require('./dynamic-multiple')
  , DynamicValue    = require('./dynamic-value')
  , ReverseMap      = require('./reverse-map')

  , call = Function.prototype.call
  , hasOwnProperty = Object.prototype.hasOwnProperty, keys = Object.keys
  , getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor
  , getPrototypeOf = Object.getPrototypeOf
  , defineProperties = Object.defineProperties;

module.exports = function (db, object, descriptor) {
	defineProperties(object, assign({
		// Descriptor
		__descriptorPrototype__: d('', descriptor),
		__descriptors__: d('', create(null)),
		isKeyStatic: d(function (key) {
			var obj;
			if (typeof key !== 'string') return false;
			if (!(key in this)) return false;
			obj = this;
			while (!obj.hasOwnProperty(key)) obj = getPrototypeOf(obj);
			return getOwnPropertyDescriptor(obj, key).hasOwnProperty('value');
		}),
		_getCurrentDescriptor_: d(function (sKey) {
			var key = this._keys_[sKey];
			if (this.isKeyStatic(key)) return null;
			return this._getDescriptor_(sKey);
		}),
		_descriptorPrototype_: d.gs(function () {
			if (this.hasOwnProperty('__descriptorPrototype__')) {
				return this.__descriptorPrototype__;
			}
			return this.__descriptorPrototype__._create_(this);
		}),
		_getOwnDescriptor_: d(function (sKey, dbEvent) {
			if (this.hasOwnProperty('__descriptors__')) {
				if (hasOwnProperty.call(this.__descriptors__, sKey)) {
					return this.__descriptors__[sKey];
				}
			}
			if (this.__descriptors__[sKey]) {
				return this.__descriptors__[sKey]._create_(this);
			}
			return this.__descriptorPrototype__
				._createDescriptor_(this, sKey, dbEvent);
		}),
		$getOwn: d(function (key) {
			var sKey = this._serialize_(key);
			if (sKey == null) {
				throw new DbjsError(key + " is invalid key", 'INVALID_KEY');
			}
			return this._getOwnDescriptor_(sKey);
		}),
		_getDescriptor_: d(function (sKey) {
			return this.__descriptors__[sKey] || this.__descriptorPrototype__;
		}),
		$get: d(function (key) {
			var sKey = this._serialize_(key);
			if (sKey == null) {
				throw new DbjsError(key + " is invalid key", 'INVALID_KEY');
			}
			return this._getDescriptor_(sKey);
		}),

		// Nested object
		_getObject_: d(function (sKey) {
			var objects = this._objects_, desc, Type, proto;
			if (objects[sKey]) return objects[sKey];
			desc = this._getDescriptor_(sKey);
			while (!desc.hasOwnProperty('type')) desc = getPrototypeOf(desc);
			if (desc.object !== this) {
				proto = getPrototypeOf(this);
				while (true) {
					if (proto.hasOwnProperty('__objects__') && proto.__objects__[sKey]) {
						return (objects[sKey] =
							proto.__objects__[sKey]._extendNested_(this));
					}
					if (desc.object === proto) break;
					proto = getPrototypeOf(proto);
				}
			}
			Type = desc.type;
			if ((Type !== db.Base) && !db.isObjectType(Type)) Type = db.Base;
			return (objects[sKey] = Type.prototype._extendNested_(this, sKey));
		}),

		// Observables
		_getObservable_: d(function (sKey) {
			var observables = this._observableProperties_;
			if (observables[sKey]) return observables[sKey];
			return (observables[sKey] = new Observable(this, sKey));
		}),
		_get: d(function (key) {
			var sKey;
			if (this.isKeyStatic(key)) return this[key];
			sKey = this._serialize_(key);
			if (sKey == null) {
				throw new DbjsError(key + " is invalid key", 'INVALID_KEY');
			}
			return this._getObservable_(sKey);
		}),

		// Reverse
		_getReverseMap_: d(function (sKey) {
			var maps = this._reverseMaps_;
			if (hasOwnProperty.call(maps, sKey)) return maps[sKey];
			return (maps[sKey] = new ReverseMap(this, sKey));
		}),

		// Dynamic multiple
		_getDynamicMultiple_: d(function (sKey, value) {
			var data = this._dynamicMultiples_;
			if (data[sKey]) return data[sKey];
			data[sKey] = new DynamicMultiple(this, sKey, value);
			return data[sKey];
		}),
		_resolveDynamicMultiple_: d(function (sKey, getter) {
			var data = this._dynamicMultiples_, value;
			if (data[sKey]) {
				data[sKey]._updateGetter_(getter);
			} else {
				if (getter) value = getter.call(this, observePass);
				data[sKey] = new DynamicMultiple(this, sKey, value);
			}
			return data[sKey];
		}),

		// Dynamic value
		_getDynamicValue_: d(function (sKey) {
			var data = this._dynamicValues_;
			if (!data[sKey]) data[sKey] = new DynamicValue(this, sKey);
			return data[sKey];
		}),

		_forEachOwnDescriptor_: d(function (cb/*, thisArg*/) {
			var thisArg = arguments[1];
			callable(cb);
			if (!this.hasOwnProperty('__descriptors__')) return;
			keys(this.__descriptors__).forEach(function (sKey) {
				call.call(cb, thisArg, this[sKey], sKey);
			}, this.__descriptors__);
		}),

		_forEachOwnNestedObject_: d(function (cb/*, thisArg*/) {
			var thisArg = arguments[1];
			callable(cb);
			if (!this.hasOwnProperty('__objects__')) return;
			keys(this.__objects__).forEach(function (sKey) {
				call.call(cb, thisArg, this[sKey], sKey);
			}, this.__objects__);
		})

	}, lazy({

		// Descriptors
		_descriptors_: d(function () {
			return injectPrimitive(this, create(this.__descriptors__),
				'__descriptors__');
		}, { cacheName: '__descriptors__', desc: '' }),

		// Nested objects
		_objects_: d(function () { return create(null); },
			{ cacheName: '__objects__', desc: '' }),

		// Observables
		_dynamicListeners_: d(function () { return []; },
			{ cacheName: '__dynamicListeners__', desc: '' }),
		_observableProperties_: d(function () { return create(null); },
			{ cacheName: '__observableProperties__', desc: '' }),

		// Reverse
		_reverseMaps_: d(function () {
			return injectPrimitive(this, create(this.__reverseMaps__ || null),
				'__reverseMaps__');
		}, { cacheName: '__reverseMaps__', desc: '' }),

		// Dynamic multiple
		_dynamicMultiples_: d(function () { return create(null); },
			{ cacheName: '__dynamicMultiples__', desc: '' }),

		// Dynamic value
		_dynamicValues_: d(function () { return create(null); },
			{ cacheName: '__dynamicValues__', desc: '' }),

		// Iterator
		_iterators_: d(function () { return []; },
			{ cacheName: '__iterators__', desc: '' }),

		// Assignments
		_assignments_: d(function () { return new ObjectsSet(); },
			{ cacheName: '__assignments__', desc: '' })

	})));
};
<commit_msg>Provide self descriptive get descriptor methods<commit_after>'use strict';

var assign          = require('es5-ext/object/assign')
  , create          = require('es5-ext/object/create')
  , callable        = require('es5-ext/object/valid-callable')
  , d               = require('d')
  , lazy            = require('d/lazy')
  , injectPrimitive = require('../utils/inject-primitive')
  , observePass     = require('../utils/observe-pass-through')
  , DbjsError       = require('../error')
  , ObjectsSet      = require('../objects-set')
  , Observable      = require('./observable')
  , DynamicMultiple = require('./dynamic-multiple')
  , DynamicValue    = require('./dynamic-value')
  , ReverseMap      = require('./reverse-map')

  , call = Function.prototype.call
  , hasOwnProperty = Object.prototype.hasOwnProperty, keys = Object.keys
  , getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor
  , getPrototypeOf = Object.getPrototypeOf
  , defineProperties = Object.defineProperties
  , desc1, desc2;

module.exports = function (db, object, descriptor) {
	defineProperties(object, assign({
		// Descriptor
		__descriptorPrototype__: d('', descriptor),
		__descriptors__: d('', create(null)),
		isKeyStatic: d(function (key) {
			var obj;
			if (typeof key !== 'string') return false;
			if (!(key in this)) return false;
			obj = this;
			while (!obj.hasOwnProperty(key)) obj = getPrototypeOf(obj);
			return getOwnPropertyDescriptor(obj, key).hasOwnProperty('value');
		}),
		_getCurrentDescriptor_: d(function (sKey) {
			var key = this._keys_[sKey];
			if (this.isKeyStatic(key)) return null;
			return this._getDescriptor_(sKey);
		}),
		_descriptorPrototype_: d.gs(function () {
			if (this.hasOwnProperty('__descriptorPrototype__')) {
				return this.__descriptorPrototype__;
			}
			return this.__descriptorPrototype__._create_(this);
		}),

		_getOwnDescriptor_: d(function (sKey, dbEvent) {
			if (this.hasOwnProperty('__descriptors__')) {
				if (hasOwnProperty.call(this.__descriptors__, sKey)) {
					return this.__descriptors__[sKey];
				}
			}
			if (this.__descriptors__[sKey]) {
				return this.__descriptors__[sKey]._create_(this);
			}
			return this.__descriptorPrototype__
				._createDescriptor_(this, sKey, dbEvent);
		}),
		getOwnDescriptor: desc1 = d(function (key) {
			var sKey = this._serialize_(key);
			if (sKey == null) {
				throw new DbjsError(key + " is invalid key", 'INVALID_KEY');
			}
			return this._getOwnDescriptor_(sKey);
		}),
		$getOwn: desc1,

		_getDescriptor_: d(function (sKey) {
			return this.__descriptors__[sKey] || this.__descriptorPrototype__;
		}),
		getDescriptor: desc2 = d(function (key) {
			var sKey = this._serialize_(key);
			if (sKey == null) {
				throw new DbjsError(key + " is invalid key", 'INVALID_KEY');
			}
			return this._getDescriptor_(sKey);
		}),
		$get: desc2,

		// Nested object
		_getObject_: d(function (sKey) {
			var objects = this._objects_, desc, Type, proto;
			if (objects[sKey]) return objects[sKey];
			desc = this._getDescriptor_(sKey);
			while (!desc.hasOwnProperty('type')) desc = getPrototypeOf(desc);
			if (desc.object !== this) {
				proto = getPrototypeOf(this);
				while (true) {
					if (proto.hasOwnProperty('__objects__') && proto.__objects__[sKey]) {
						return (objects[sKey] =
							proto.__objects__[sKey]._extendNested_(this));
					}
					if (desc.object === proto) break;
					proto = getPrototypeOf(proto);
				}
			}
			Type = desc.type;
			if ((Type !== db.Base) && !db.isObjectType(Type)) Type = db.Base;
			return (objects[sKey] = Type.prototype._extendNested_(this, sKey));
		}),

		// Observables
		_getObservable_: d(function (sKey) {
			var observables = this._observableProperties_;
			if (observables[sKey]) return observables[sKey];
			return (observables[sKey] = new Observable(this, sKey));
		}),
		_get: d(function (key) {
			var sKey;
			if (this.isKeyStatic(key)) return this[key];
			sKey = this._serialize_(key);
			if (sKey == null) {
				throw new DbjsError(key + " is invalid key", 'INVALID_KEY');
			}
			return this._getObservable_(sKey);
		}),

		// Reverse
		_getReverseMap_: d(function (sKey) {
			var maps = this._reverseMaps_;
			if (hasOwnProperty.call(maps, sKey)) return maps[sKey];
			return (maps[sKey] = new ReverseMap(this, sKey));
		}),

		// Dynamic multiple
		_getDynamicMultiple_: d(function (sKey, value) {
			var data = this._dynamicMultiples_;
			if (data[sKey]) return data[sKey];
			data[sKey] = new DynamicMultiple(this, sKey, value);
			return data[sKey];
		}),
		_resolveDynamicMultiple_: d(function (sKey, getter) {
			var data = this._dynamicMultiples_, value;
			if (data[sKey]) {
				data[sKey]._updateGetter_(getter);
			} else {
				if (getter) value = getter.call(this, observePass);
				data[sKey] = new DynamicMultiple(this, sKey, value);
			}
			return data[sKey];
		}),

		// Dynamic value
		_getDynamicValue_: d(function (sKey) {
			var data = this._dynamicValues_;
			if (!data[sKey]) data[sKey] = new DynamicValue(this, sKey);
			return data[sKey];
		}),

		_forEachOwnDescriptor_: d(function (cb/*, thisArg*/) {
			var thisArg = arguments[1];
			callable(cb);
			if (!this.hasOwnProperty('__descriptors__')) return;
			keys(this.__descriptors__).forEach(function (sKey) {
				call.call(cb, thisArg, this[sKey], sKey);
			}, this.__descriptors__);
		}),

		_forEachOwnNestedObject_: d(function (cb/*, thisArg*/) {
			var thisArg = arguments[1];
			callable(cb);
			if (!this.hasOwnProperty('__objects__')) return;
			keys(this.__objects__).forEach(function (sKey) {
				call.call(cb, thisArg, this[sKey], sKey);
			}, this.__objects__);
		})

	}, lazy({

		// Descriptors
		_descriptors_: d(function () {
			return injectPrimitive(this, create(this.__descriptors__),
				'__descriptors__');
		}, { cacheName: '__descriptors__', desc: '' }),

		// Nested objects
		_objects_: d(function () { return create(null); },
			{ cacheName: '__objects__', desc: '' }),

		// Observables
		_dynamicListeners_: d(function () { return []; },
			{ cacheName: '__dynamicListeners__', desc: '' }),
		_observableProperties_: d(function () { return create(null); },
			{ cacheName: '__observableProperties__', desc: '' }),

		// Reverse
		_reverseMaps_: d(function () {
			return injectPrimitive(this, create(this.__reverseMaps__ || null),
				'__reverseMaps__');
		}, { cacheName: '__reverseMaps__', desc: '' }),

		// Dynamic multiple
		_dynamicMultiples_: d(function () { return create(null); },
			{ cacheName: '__dynamicMultiples__', desc: '' }),

		// Dynamic value
		_dynamicValues_: d(function () { return create(null); },
			{ cacheName: '__dynamicValues__', desc: '' }),

		// Iterator
		_iterators_: d(function () { return []; },
			{ cacheName: '__iterators__', desc: '' }),

		// Assignments
		_assignments_: d(function () { return new ObjectsSet(); },
			{ cacheName: '__assignments__', desc: '' })

	})));
};
<|endoftext|>


<commit_before>// Classes
import {
  Individual,
  Organisation,
  Company,
  AssetManager,
  Broker,
  Exchange,
  Fund,
  GovernmentAgency,
  Party,
  Address,
  Email
} from '../parties'

// CRUD methods
import {
  retrieve,
  insert,
  amend,
  partialAmend,
  deactivate
} from '../utils/parties'

// Exports
export {
  Individual,
  Organisation,
  Company,
  AssetManager,
  Broker,
  Exchange,
  Fund,
  GovernmentAgency,
  Party
  Address,
  Email,
  retrieve,
  insert,
  amend,
  partialAmend,
  deactivate
}
<commit_msg>Fix typo<commit_after>// Classes
import {
  Individual,
  Organisation,
  Company,
  AssetManager,
  Broker,
  Exchange,
  Fund,
  GovernmentAgency,
  Party,
  Address,
  Email
} from '../parties'

// CRUD methods
import {
  retrieve,
  insert,
  amend,
  partialAmend,
  deactivate
} from '../utils/parties'

// Exports
export {
  Individual,
  Organisation,
  Company,
  AssetManager,
  Broker,
  Exchange,
  Fund,
  GovernmentAgency,
  Party,
  Address,
  Email,
  retrieve,
  insert,
  amend,
  partialAmend,
  deactivate
}
<|endoftext|>


<commit_before>"use strict";

var assert = require('assert');

var Item = function(name, price) {
  return {
    name: function() {
      return name;
    },
    unitPrice: function() {
      return price;
    }
  }
};

var Register = function() {

  var runningSum = 0;
  var offers = [];
  var items = [];

  return {
     price: function(item) {
       items.push(item);
     },

     insertOffer: function(offer) {
       offers.push(offer);
     },

     total: function() {
       var runningSum = 0;
       for (var i=0;i<items.length;++i) {
         runningSum += items[i].unitPrice();
       }

       return runningSum;
     }
  };
};

var numberOfItemsMatchingInBasket = function(item, basket) {
  var count = 0;
  for (var i=0;i<basket.length;++i) {
    if (basket[i].name() === item.name()) {
      count++;
    }
  }

  return count;
};

var Receipt = function() {
  var items = [];
  var total = 0;

  return {
    items: function() { return items; },

    total: function() { return total; },

    record: function(description, price) {
      items.push(description + ' : ' + price);
      total += price;
    },
  };
};

var Unit = function(item) {
  return {
    applies: function(basket, receipt) {
      if (numberOfItemsMatchingInBasket(item, basket) >= 1) {
        receipt.record(item.name(), item.unitPrice());
        return true;
      } else {
        return false;
      }
    }
  };
};

var BuyOneGetOneFree = function(item) {
  return {
    applies: function(basket, receipt) {
      if (numberOfItemsMatchingInBasket(item,basket) >= 2) {
        receipt.record("BOGOF " + item.name(), item.unitPrice());
        return true;
      } else {
        return false;
      }
    }
  };
};

var ThreeForTwo = function(item) {
  return {
    applies: function(basket, receipt) {
      if (numberOfItemsMatchingInBasket(item,basket) >= 3) {
        receipt.record("3 for 2 " + item.name(), 2 * item.unitPrice());
        return true;
      } else {
        return false;
      }
    }
  }
};

describe('super market', function() {

  var beans = new Item('beans', 45);
  var batteries = new Item('batteries', 60);

  describe('item', function() {
    it('have a unit price', function() {
      assert.equal(45, beans.unitPrice());
    });
  });

  describe('basket', function() {
    it('can keep track of items', function() {
      var basket = new Basket();
      basket.add(beans);

      assert.equal(1, basket.count());

      basket.remove(beans);
      assert.equal(0, basket.count());
    });
  });

  describe('receipt', function() {
    it('consists of items and a total price', function() {
      var receipt = new Receipt();
      receipt.record('2 x Beans', 45);
      receipt.record('4 x Shoes', 10);

      assert.equal(2, receipt.items().length);
      assert.equal(55, receipt.total());
    });
  });

  describe('register', function() {
    it('totals the price of items', function() {
      var register = new Register();
      register.price(beans);
      register.price(beans);

      assert.equal(90, register.total());
    });

    it('knows of offers', function() {
      var register = new Register();
      register.insertOffer(new BuyOneGetOneFree(beans));

      register.price(beans);
      register.price(beans);

      assert.equal(45, register.total());
    });
  });

  describe('offer', function() {

    var item, price, receipt;

    beforeEach(function() {
      item = undefined;
      price = undefined;
      receipt = {
        record: function(item_, price_) {
          item = item_;
          price = price_;
        }
      };
    });

    it('unit offer', function() {
      var offer = new Unit(beans);
      assert(offer.applies([beans], receipt));
      assert.equal(45, price);
    });

    it('buy-one-get-one-free', function() {
      var offer = new BuyOneGetOneFree(beans);
      assert(offer.applies([beans, beans], receipt));
      assert.equal(45, price);
    });

    it('3 for 2', function() {
      var offer = new ThreeForTwo(beans);
      assert(offer.applies([beans,beans,beans], receipt));
      assert.equal(90, price);
    });
  });
});
<commit_msg>stub object<commit_after>"use strict";

var assert = require('assert');

var Item = function(name, price) {
  return {
    name: function() {
      return name;
    },
    unitPrice: function() {
      return price;
    }
  }
};

var Basket = function() {
  var items = [];
  return {

  };
};

var Register = function() {

  var runningSum = 0;
  var offers = [];
  var items = [];

  return {
     price: function(item) {
       items.push(item);
     },

     insertOffer: function(offer) {
       offers.push(offer);
     },

     total: function() {
       var runningSum = 0;
       for (var i=0;i<items.length;++i) {
         runningSum += items[i].unitPrice();
       }

       return runningSum;
     }
  };
};

var numberOfItemsMatchingInBasket = function(item, basket) {
  var count = 0;
  for (var i=0;i<basket.length;++i) {
    if (basket[i].name() === item.name()) {
      count++;
    }
  }

  return count;
};

var Receipt = function() {
  var items = [];
  var total = 0;

  return {
    items: function() { return items; },

    total: function() { return total; },

    record: function(description, price) {
      items.push(description + ' : ' + price);
      total += price;
    },
  };
};

var Unit = function(item) {
  return {
    applies: function(basket, receipt) {
      if (numberOfItemsMatchingInBasket(item, basket) >= 1) {
        receipt.record(item.name(), item.unitPrice());
        return true;
      } else {
        return false;
      }
    }
  };
};

var BuyOneGetOneFree = function(item) {
  return {
    applies: function(basket, receipt) {
      if (numberOfItemsMatchingInBasket(item,basket) >= 2) {
        receipt.record("BOGOF " + item.name(), item.unitPrice());
        return true;
      } else {
        return false;
      }
    }
  };
};

var ThreeForTwo = function(item) {
  return {
    applies: function(basket, receipt) {
      if (numberOfItemsMatchingInBasket(item,basket) >= 3) {
        receipt.record("3 for 2 " + item.name(), 2 * item.unitPrice());
        return true;
      } else {
        return false;
      }
    }
  }
};

describe('super market', function() {

  var beans = new Item('beans', 45);
  var batteries = new Item('batteries', 60);

  describe('item', function() {
    it('have a unit price', function() {
      assert.equal(45, beans.unitPrice());
    });
  });

  describe('basket', function() {
    it('can keep track of items', function() {
      var basket = new Basket();
      basket.add(beans);

      assert.equal(1, basket.count());

      basket.remove(beans);
      assert.equal(0, basket.count());
    });
  });

  describe('receipt', function() {
    it('consists of items and a total price', function() {
      var receipt = new Receipt();
      receipt.record('2 x Beans', 45);
      receipt.record('4 x Shoes', 10);

      assert.equal(2, receipt.items().length);
      assert.equal(55, receipt.total());
    });
  });

  describe('register', function() {
    it('totals the price of items', function() {
      var register = new Register();
      register.price(beans);
      register.price(beans);

      assert.equal(90, register.total());
    });

    it('knows of offers', function() {
      var register = new Register();
      register.insertOffer(new BuyOneGetOneFree(beans));

      register.price(beans);
      register.price(beans);

      assert.equal(45, register.total());
    });
  });

  describe('offer', function() {

    var item, price, receipt;

    beforeEach(function() {
      item = undefined;
      price = undefined;
      receipt = {
        record: function(item_, price_) {
          item = item_;
          price = price_;
        }
      };
    });

    it('unit offer', function() {
      var offer = new Unit(beans);
      assert(offer.applies([beans], receipt));
      assert.equal(45, price);
    });

    it('buy-one-get-one-free', function() {
      var offer = new BuyOneGetOneFree(beans);
      assert(offer.applies([beans, beans], receipt));
      assert.equal(45, price);
    });

    it('3 for 2', function() {
      var offer = new ThreeForTwo(beans);
      assert(offer.applies([beans,beans,beans], receipt));
      assert.equal(90, price);
    });
  });
});
<|endoftext|>


<commit_before>"use strict";

var assert = require('assert');

var Item = function(desc) {

  var items = [];

  this.description = desc;

  return this;
};

var Basket = function() {

  var items = [];

  this.add = function(item) {
    items.push(item);
  };

  this.contents = function() {
    return items;
  };

  return this;
};

var Checkout = function() {
  return this;
};

describe('shopping basket', function() {
  describe('item', function() {
    it('exists', function() {
      assert(new Item('description'));
    });

    it('has a description', function() {
      var item = new Item('banana');
      assert.equal('banana', item.description);
    });
  });

  describe('basket', function() {
    it('exists', function() {
      assert(new Basket());
    });

    it('items can be added', function() {
      var basket = new Basket();
      basket.add(new Item('Shoes'));

      assert.equal(1, basket.contents().length);
    });
  });

  describe('checkout', function() {
    it('exists', function() {
      assert(new Checkout());
    });

    it('prices an empty basket at zero', function() {
      var checkout = new Checkout();
      assert.equal(0, checkout.price(new Basket()));
    });
  });
});
<commit_msg>pricing an empty basket<commit_after>"use strict";

var assert = require('assert');

var Item = function(desc) {

  var items = [];

  this.description = desc;

  return this;
};

var Basket = function() {

  var items = [];

  this.add = function(item) {
    items.push(item);
  };

  this.contents = function() {
    return items;
  };

  return this;
};

var Checkout = function() {

  this.price = function(basket) {
    return 0;
  };

  return this;
};

describe('shopping basket', function() {
  describe('item', function() {
    it('exists', function() {
      assert(new Item('description'));
    });

    it('has a description', function() {
      var item = new Item('banana');
      assert.equal('banana', item.description);
    });
  });

  describe('basket', function() {
    it('exists', function() {
      assert(new Basket());
    });

    it('items can be added', function() {
      var basket = new Basket();
      basket.add(new Item('Shoes'));

      assert.equal(1, basket.contents().length);
    });
  });

  describe('checkout', function() {
    it('exists', function() {
      assert(new Checkout());
    });

    it('prices an empty basket at zero', function() {
      var checkout = new Checkout();
      assert.equal(0, checkout.price(new Basket()));
    });
  });
});
<|endoftext|>


<commit_before>(function() {
    var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
    window.requestAnimationFrame = requestAnimationFrame;
})();

var canvas,
    canvasContext,
    playerCharacter = new Image(),
    player = { // create our player object
      x: 0,
      y: 0,
      faceRight: false,
      faceLeft: false,
      faceForward: true,
      velocity: 0,
      speed: 15
    },
    offset = {
      x: 0,
      y: 0
    },
    keys=[
      keyW = false,
      keyA = false,
      keyS = false,
      keyD = false
    ],
    objects=[
      500, 1000, 1500, 2000
    ];

var characterSpriteRight = new spriteSheet('assets/right_walk_spritesheet.png', 85, 150); // path, width, height
var characterSpriteLeft = new spriteSheet('assets/left_walk_spritesheet.png', 85, 150);
var characterTransition = new spriteSheet('assets/transition_sprite.png', 96, 150);
var characterStand = new spriteSheet('assets/standing_spritesheet.png', 92, 150);
var background = new spriteSheet('assets/placeholder.png', 50, 50);

var walkRight = new Animation(characterSpriteRight, 4, 0, 6); //sprite, speed, start, end
var walkLeft = new Animation(characterSpriteLeft, 4, 0, 6);
var transitionRight = new Animation(characterTransition, 4, 0, 0);
var transitionLeft = new Animation(characterTransition, 4, 1, 1);
var stand = new Animation(characterStand, 6, 0, 11);

function onKeyDown(event) {
  var keyCode = event.keyCode;
  switch (keyCode) {
    case 68: //d -> right
      keys.keyD = true;
      if(player.velocity < player.speed)
        player.velocity++;
      offset.x -= player.velocity;
      break;
    case 83: //s -> down
      keys.keyS = true;
      break;
    case 65: //a -> left
      keys.keyA = true;
      if(player.velocity < player.speed)
        player.velocity++;
      offset.x +=player.velocity;
      break;
    case 87: //w -> up
      keys.keyW = true;
      break;
  }
}
function onKeyUp(event) {
  var keyCode = event.keyCode;
  switch (keyCode) {
    case 68: //d
      keys.keyD = false;
      player.velocity = 0;
      break;
    case 83: //s
      keys.keyS = false;
      break;
    case 65: //a
      keys.keyA = false;
      player.velocity = 0;
      break;
    case 87: //w
      keys.keyW = false;
      break;
  }
}

window.onload = function() {
  canvas = document.getElementById('gameCanvas');
  canvasContext = canvas.getContext('2d');

  //event listener
  window.addEventListener('resize', resizeCanvas, false);
  window.addEventListener('keydown', onKeyDown, false);
  window.addEventListener('keyup', onKeyUp, false);

  resizeCanvas();
};

function resizeCanvas() {
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
  player.y = window.innerHeight/2;
  player.x = window.innerWidth/2;
  drawAssets();
}

function drawAssets() {
  canvasContext.save();
  canvasContext.translate(offset.x, offset.y);
  clearCanvas();

  drawBG();
  drawPlayer();
  canvasContext.restore();
  requestAnimationFrame(drawAssets);
}

function clearCanvas() {
  canvasContext.clearRect(-offset.x, -offset.y, canvas.width, canvas.height);
}

function spriteSheet(path, frameWidth, frameHeight) {
  this.image = new Image();
  this.frameWidth = frameWidth;
  this.frameHeight = frameHeight;

  // calculate the number of frames in a row after the image loads
  var self = this;
  this.image.onload = function() {
    self.framesPerRow = Math.floor(self.image.width / self.frameWidth);
  };

  this.image.src = path;
}

function Animation(spritesheet, frameSpeed, startFrame, endFrame) {
  var animationSequence = [];  // array holding the order of the animation
  var currentFrame = 0;        // the current frame to draw
  var counter = 0;             // keep track of frame rate

  // create the sequence of frame numbers for the animation
  for (var frameNumber = startFrame; frameNumber <= endFrame; frameNumber++) {
    animationSequence.push(frameNumber);
  }

  // Update the animation
  this.update = function() {
    // update to the next frame if it is time
    if (counter == (frameSpeed - 1)) {
      currentFrame = (currentFrame + 1) % animationSequence.length;
    }
    // update the counter
    counter = (counter + 1) % frameSpeed;
  };

  // draw the current frame
  this.draw = function(x, y) {
    // get the row and col of the frame
    var row = Math.floor(animationSequence[currentFrame] / spritesheet.framesPerRow);
    var col = Math.floor(animationSequence[currentFrame] % spritesheet.framesPerRow);

    canvasContext.drawImage(
      spritesheet.image, // sheet
      col * spritesheet.frameWidth, row * spritesheet.frameHeight, // sx, sy
      spritesheet.frameWidth, spritesheet.frameHeight, // swidth, sheight
      x, y, // x, y
      spritesheet.frameWidth, spritesheet.frameHeight); // width, height
  };
}

function drawPlayer() {

  if (keys.keyD === true) { // right
    // update move to the right
    walkRight.update();
    walkRight.draw(player.x, player.y);
    player.faceRight = true;
  } else if (keys.keyA === true) { // left
    // update move to the left
    walkLeft.update();
    walkLeft.draw(player.x, player.y);
    player.faceLeft = true;
  } else {
    stand.update();
    stand.draw(player.x, player.y);
    if(player.faceforward === false && player.faceRight === true) {
      transitionRight.update();
      transitionRight.draw(player.x, player.y);
    } else if(player.faceforward === false && player.faceLeft === true) {
      transitionLeft.update();
      transitionLeft.draw(player.x, player.y);
    }
    player.faceRight = false;
    player.faceLeft = false;
    player.faceForward = true;
  }

}

function drawBG() {
  var objectsLength = objects.length;

  canvasContext.fillStyle = '#2d77ef';
  canvasContext.fillRect(0, 0, canvas.width, canvas.height);
  canvasContext.fillStyle = '#189b33';
  canvasContext.fillRect(0, player.y+145, canvas.width, 15);
  canvasContext.fillStyle = '#189b33';
  canvasContext.fillRect(0, player.y+145, 30, 50);
  canvasContext.fillStyle = '#189b33';
  canvasContext.fillRect(500, player.y+145, 30, 50);
  canvasContext.fillStyle = '#189b33';
  canvasContext.fillRect(1000, player.y+145, 30, 50);
  canvasContext.fillStyle = '#189b33';
  canvasContext.fillRect(1500, player.y+145, 30, 50);
  canvasContext.fillStyle = '#189b33';
  canvasContext.fillRect(2000, player.y+145, 30, 50);
  canvasContext.fillStyle = '#189b33';
  canvasContext.fillRect(2500, player.y+145, 30, 50);
  canvasContext.fillStyle = '#189b33';
  canvasContext.fillRect(3000, player.y+145, 30, 50);
  canvasContext.fillStyle = '#189b33';
  canvasContext.fillRect(3500, player.y+145, 30, 50);

  canvasContext.restore();
}
<commit_msg>walking cycle update<commit_after>(function() {
    var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
    window.requestAnimationFrame = requestAnimationFrame;
})();

var canvas,
    canvasContext,
    playerCharacter = new Image(),
    player = { // create our player object
      x: 0,
      y: 0,
      faceRight: false,
      faceLeft: false,
      faceForward: true,
      velocity: 5,
      speed: 15
    },
    offset = {
      x: 0,
      y: 0
    },
    keys=[
      keyW = false,
      keyA = false,
      keyS = false,
      keyD = false
    ],
    objects=[
      500, 1000, 1500, 2000
    ];

var characterSpriteRight = new spriteSheet('assets/right_walk_spritesheet.png', 85, 150); // path, width, height
var characterSpriteLeft = new spriteSheet('assets/left_walk_spritesheet.png', 85, 150);
var characterTransition = new spriteSheet('assets/transition_sprite.png', 96, 150);
var characterStand = new spriteSheet('assets/standing_spritesheet.png', 92, 150);
var background = new spriteSheet('assets/placeholder.png', 50, 50);

var walkRight = new Animation(characterSpriteRight, 4, 0, 6); //sprite, speed, start, end
var walkLeft = new Animation(characterSpriteLeft, 4, 0, 6);
var transitionRight = new Animation(characterTransition, 4, 0, 0);
var transitionLeft = new Animation(characterTransition, 4, 1, 1);
var stand = new Animation(characterStand, 6, 0, 11);

function onKeyDown(event) {
  var keyCode = event.keyCode;
  switch (keyCode) {
    case 68: //d -> right
      keys.keyD = true;

      break;
    case 83: //s -> down
      keys.keyS = true;
      break;
    case 65: //a -> left
      keys.keyA = true;

      break;
    case 87: //w -> up
      keys.keyW = true;
      break;
  }
}
function onKeyUp(event) {
  var keyCode = event.keyCode;
  switch (keyCode) {
    case 68: //d
      keys.keyD = false;
      player.velocity = 5;
      break;
    case 83: //s
      keys.keyS = false;
      break;
    case 65: //a
      keys.keyA = false;
      player.velocity = 5;
      break;
    case 87: //w
      keys.keyW = false;
      break;
  }
}

window.onload = function() {
  canvas = document.getElementById('gameCanvas');
  canvasContext = canvas.getContext('2d');

  //event listener
  window.addEventListener('resize', resizeCanvas, false);
  window.addEventListener('keydown', onKeyDown, false);
  window.addEventListener('keyup', onKeyUp, false);

  resizeCanvas();
};

function resizeCanvas() {
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
  player.y = window.innerHeight/2;
  player.x = window.innerWidth/2;
  drawAssets();
}

function drawAssets() {
  canvasContext.save();
  canvasContext.translate(offset.x, offset.y);
  clearCanvas();

  drawBG();
  drawPlayer();
  canvasContext.restore();
  requestAnimationFrame(drawAssets);
}

function clearCanvas() {
  canvasContext.clearRect(-offset.x, -offset.y, canvas.width, canvas.height);
}

function spriteSheet(path, frameWidth, frameHeight) {
  this.image = new Image();
  this.frameWidth = frameWidth;
  this.frameHeight = frameHeight;

  // calculate the number of frames in a row after the image loads
  var self = this;
  this.image.onload = function() {
    self.framesPerRow = Math.floor(self.image.width / self.frameWidth);
  };

  this.image.src = path;
}

function Animation(spritesheet, frameSpeed, startFrame, endFrame) {
  var animationSequence = [];  // array holding the order of the animation
  var currentFrame = 0;        // the current frame to draw
  var counter = 0;             // keep track of frame rate

  // create the sequence of frame numbers for the animation
  for (var frameNumber = startFrame; frameNumber <= endFrame; frameNumber++) {
    animationSequence.push(frameNumber);
  }

  // Update the animation
  this.update = function() {
    // update to the next frame if it is time
    if (counter == (frameSpeed - 1)) {
      currentFrame = (currentFrame + 1) % animationSequence.length;
    }
    // update the counter
    counter = (counter + 1) % frameSpeed;
  };

  // draw the current frame
  this.draw = function(x, y) {
    // get the row and col of the frame
    var row = Math.floor(animationSequence[currentFrame] / spritesheet.framesPerRow);
    var col = Math.floor(animationSequence[currentFrame] % spritesheet.framesPerRow);

    canvasContext.drawImage(
      spritesheet.image, // sheet
      col * spritesheet.frameWidth, row * spritesheet.frameHeight, // sx, sy
      spritesheet.frameWidth, spritesheet.frameHeight, // swidth, sheight
      x, y, // x, y
      spritesheet.frameWidth, spritesheet.frameHeight); // width, height
  };
}

function drawPlayer() {

  if (keys.keyD === true) { // right
    // update move to the right
    if(player.velocity < player.speed)
      player.velocity++;
    offset.x -= player.velocity;

    walkRight.update();
    walkRight.draw(player.x, player.y);

    player.faceRight = true;
  } else if (keys.keyA === true) { // left
    // update move to the left
    if(player.velocity < player.speed)
      player.velocity++;
    offset.x +=player.velocity;

    walkLeft.update();
    walkLeft.draw(player.x, player.y);
    player.faceLeft = true;
  } else {
    stand.update();
    stand.draw(player.x, player.y);
    if(player.faceforward === false && player.faceRight === true) {
      transitionRight.update();
      transitionRight.draw(player.x, player.y);
    } else if(player.faceforward === false && player.faceLeft === true) {
      transitionLeft.update();
      transitionLeft.draw(player.x, player.y);
    }
    player.faceRight = false;
    player.faceLeft = false;
    player.faceForward = true;
  }

}

function drawBG() {
  var objectsLength = objects.length;

  canvasContext.fillStyle = '#2d77ef';
  canvasContext.fillRect(0, 0, canvas.width, canvas.height);
  canvasContext.fillStyle = '#189b33';
  canvasContext.fillRect(0, player.y+145, canvas.width, 15);
  canvasContext.fillStyle = '#189b33';
  canvasContext.fillRect(0, player.y+145, 30, 50);
  canvasContext.fillStyle = '#189b33';
  canvasContext.fillRect(500, player.y+145, 30, 50);
  canvasContext.fillStyle = '#189b33';
  canvasContext.fillRect(1000, player.y+145, 30, 50);
  canvasContext.fillStyle = '#189b33';
  canvasContext.fillRect(1500, player.y+145, 30, 50);
  canvasContext.fillStyle = '#189b33';
  canvasContext.fillRect(2000, player.y+145, 30, 50);
  canvasContext.fillStyle = '#189b33';
  canvasContext.fillRect(2500, player.y+145, 30, 50);
  canvasContext.fillStyle = '#189b33';
  canvasContext.fillRect(3000, player.y+145, 30, 50);
  canvasContext.fillStyle = '#189b33';
  canvasContext.fillRect(3500, player.y+145, 30, 50);

  canvasContext.restore();
}
<|endoftext|>