<commit_before>/*
 * Copyright 2013 Laurent Bovet <laurent.bovet@windmaster.ch>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

(function (definition) {
    // CommonJS
    if (typeof exports === "object") {
        module.exports = definition(require('underscore'), require('q'), require('./typson.js'));
        // RequireJS
    } else if (typeof define === "function" && define.amd) {
        define(["lib/underscore", "lib/q", "typson"], definition);
    }
})
(function (underscore, Q, typson) {
    if (underscore) {
        _ = underscore;
    }
    var api = {};

    var primitiveTypes = [ "string", "number", "boolean" ];
    var validationKeywords = [ "minimum", "exclusiveMinimum", "maximum", "exclusiveMaximum", "multipleOf", "minLength", "maxLength", "format", "pattern", "minItems", "maxItems", "uniqueItems" ];
    var annotedValidationKeywordPattern = /@[a-z]+\s*[^@\s]+/gi;

    /**
     * Creates json-schema type definitions from a type script.
     *
     * @param uri {string} Points to the source type script.
     */
    api.definitions = function (uri) {
        return Q.promise(function (resolve) {
            typson.tree(uri).done(function (tree) {
                TypeScript = typson.TypeScript;
                var definitions = {
                		interfaces: {},
                		enums: {}
                };
                _.each(tree, function (script) {
                    _.each(script.moduleElements.members, function (type) {
                        if (type.nodeType() == TypeScript.NodeType.InterfaceDeclaration) {
                        	handleInterfaceDeclaration(type, definitions);
                        }
                        else if (type.nodeType() == TypeScript.NodeType.ModuleDeclaration) {
                        	handleEnumDeclaration(type, definitions);
                        }
                    });
                });
                resolve(definitions.interfaces);
            });
        });
    };

    /**
     * Handles interface declaration as new definition and registers it in the global set of interface definitions
     *
     * @param type {object} the TypeScript AST node associated to the interface declaration
     * @param definitions {object} the set of handled interface and enum definitions
     */
    function handleInterfaceDeclaration(type, definitions) {
        var definition = definitions.interfaces[type.name.actualText] = {};
        definition.id = type.name.actualText;
        copyComment(type, definition);

        definition.properties = {};
        mergeInheritedProperties(type, definition, definitions);

        _.each(type.members.members, function (variable) {
            var property = definition.properties[variable.id.actualText] = {};
            var variableType = variable.typeExpr.term.actualText;
            copyComment(variable, property);
            var propertyType = null;

            //arrays
            if (variable.typeExpr.getFlags() & 8 /* todo: find constant */) {
                property.type = "array";
                propertyType = property.items = {};
            }
            //maps
            else if (variable.typeExpr.term.getFlags() & 8 /* todo: find constant */) {
            	property.type = "object";
            	propertyType = property.additionalProperties = {};
            	variableType = variable.typeExpr.term.members.members[0].returnTypeAnnotation.term.actualText;
            }
            //other
            else {
                propertyType = property;
            }

        	if (definitions.enums[variableType]) {
        		property.enum = definitions.enums[variableType].enumeration;
        	} else if (primitiveTypes.indexOf(variableType) == -1) {
        		propertyType.$ref = variableType;
            } else {
                propertyType.type = variableType;
            }
        });
	}

    /**
     * Visits every super type extended by the given type recursively and provisions the given definition with the properties of the associated super definitions.
     *
     * @param type {object} the TypeScript AST node associated to the interface declaration
     * @param definition {object} the definition to be provisionned
     * @param definitions {object} the set of handled interface and enum definitions
     */
    function mergeInheritedProperties(type, definition, definitions) {
    	if (type.extendsList) {
	    	_.each(type.extendsList.members, function (superType) {
	    		var superDefinition = definitions.interfaces[superType.actualText];
	    		// does the provisionning if a definition exists for the current super type
	    		if (superDefinition) {
	    			for(var superKey in superDefinition.properties) {
	    				definition.properties[superKey] = superDefinition.properties[superKey];
	    			}
	    			mergeInheritedProperties(superType, definition, definitions);
	    		}
	    	});
    	}
    }

    /**
     * Handles enum declaration as new definition and registers it in the global set of enum definitions
     *
     * @param type {object} the TypeScript AST node associated to the enum declaration
     * @param definitions {object} the set of handled interface and enum definitions
     */
    function handleEnumDeclaration(type, definitions) {
	    var definition = definitions.enums[type.name.actualText] = {};
	    definition.enumeration = [];
	    _.each(type.members.members, function (declaration) {
	    	definition.enumeration.push(declaration.declaration.declarators.members[0].id.actualText);
	    });
	}

    /**
     * Extracts the description and the validation keywords from a comment
     *
     * @param from {object} the TypeScript AST node
     * @param to {object} the destination variable or definition.
     */
    function copyComment(from, to) {
        var comments = from.docComments();

        if (comments.length > 0) {
            var commentContent = comments.slice(-1)[0].getDocCommentTextValue();
            copyValidationKeywords(copyDescription(commentContent, to), to);
        }
    }

    /**
     * Extracts the description part of a comment and register it in the description property.
     * The description is supposed to start at first position and may be delimited by @.
     *
     * @param comment {string} the full comment.
     * @param to {object} the destination variable or definition.
     * @returns {string} the full comment minus the beginning description part.
     */
    function copyDescription(comment, to) {
        var delimiter = '@';
        var delimiterIndex = comment.indexOf(delimiter);
        var description = comment.slice(0, delimiterIndex < 0 ? comment.length : delimiterIndex);
        if (description.length > 0) {
            to.description = description;
        }
        return delimiterIndex < 0 ? '' : comment.slice(delimiterIndex);
    }

    /**
     * Extracts the schema validation keywords stored in a comment and register them as properties.
     * A validation keyword starts by a @. It has a name and a value. Several keywords may occur.
     *
     * @param comment {string} the full comment.
     * @param to {object} the destination variable.
     */
    function copyValidationKeywords(comment, to) {
        annotedValidationKeywordPattern.lastIndex = 0;
        // TODO: to improve the use of the exec method: it could make the tokenization
        while ((annotation = annotedValidationKeywordPattern.exec(comment))) {
            var annotationTokens = annotation[0].split(' ');
            var keyword = annotationTokens[0].slice(1);
            // case sensitive check inside the dictionary
            if (validationKeywords.indexOf(keyword) >= 0) {
                var value = annotationTokens.length > 1 ? annotationTokens[1] : '';
                try {
                    value = JSON.parse(value);
                } catch (e) {
                }
                to[keyword] = value;
            }
        }
    }

    api.exec = function(script) {
        api.definitions(script).done(function(definitions) {
            require('sys').print(JSON.stringify(definitions, null, 2));
        });
    }

    if (typeof window === 'undefined' && require.main === module) {
        if (process.argv[2]) {
            api.exec(process.argv[2]);
        } else {
            require('sys').print("Usage: node typson-schema.js <url-or-path-to-type-script-file>\n");
        }
    } else {
        return api;
    }
});
<commit_msg>implemented required feature<commit_after>/*
 * Copyright 2013 Laurent Bovet <laurent.bovet@windmaster.ch>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

(function (definition) {
    // CommonJS
    if (typeof exports === "object") {
        module.exports = definition(require('underscore'), require('q'), require('./typson.js'));
        // RequireJS
    } else if (typeof define === "function" && define.amd) {
        define(["lib/underscore", "lib/q", "typson"], definition);
    }
})
(function (underscore, Q, typson) {
    if (underscore) {
        _ = underscore;
    }
    var api = {};

    var primitiveTypes = [ "string", "number", "boolean" ];
    var validationKeywords = [ "minimum", "exclusiveMinimum", "maximum", "exclusiveMaximum", "multipleOf", "minLength", "maxLength", "format", "pattern", "minItems", "maxItems", "uniqueItems" ];
    var annotedValidationKeywordPattern = /@[a-z]+\s*[^@\s]+/gi;
    var optionalPropertyPattern = /[a-z]+\?/gi;
    var TypescriptASTFlags = { 'optionalName' : 4, 'arrayType' : 8 };

    /**
     * Creates json-schema type definitions from a type script.
     *
     * @param uri {string} Points to the source type script.
     */
    api.definitions = function (uri) {
        return Q.promise(function (resolve) {
            typson.tree(uri).done(function (tree) {
                TypeScript = typson.TypeScript;
                var definitions = {
                		interfaces: {},
                		enums: {}
                };
                _.each(tree, function (script) {
                    _.each(script.moduleElements.members, function (type) {
                        if (type.nodeType() == TypeScript.NodeType.InterfaceDeclaration) {
                        	handleInterfaceDeclaration(type, definitions);
                        }
                        else if (type.nodeType() == TypeScript.NodeType.ModuleDeclaration) {
                        	handleEnumDeclaration(type, definitions);
                        }
                    });
                });
                resolve(definitions.interfaces);
            });
        });
    };

    /**
     * Handles interface declaration as new definition and registers it in the global set of interface definitions
     *
     * @param type {object} the TypeScript AST node associated to the interface declaration
     * @param definitions {object} the set of handled interface and enum definitions
     */
    function handleInterfaceDeclaration(type, definitions) {
        var definition = definitions.interfaces[type.name.actualText] = {};
        definition.id = type.name.actualText;
        copyComment(type, definition);

        definition.properties = {};
        mergeInheritedProperties(type, definition, definitions);

        _.each(type.members.members, function (variable) {
            var property = definition.properties[variable.id.actualText] = {};
            var variableType = variable.typeExpr.term.actualText;
            copyComment(variable, property);
            var propertyType = null;

            //required
            if (!(variable.id.getFlags() & TypescriptASTFlags.optionalName)) {
            	if (!definition.required) {
            		definition.required = [];
            	}
            	definition.required.push(variable.id.actualText);
            }
            //arrays
            if (variable.typeExpr.getFlags() & TypescriptASTFlags.arrayType) {
                property.type = "array";
                propertyType = property.items = {};
            }
            //maps
            else if (variable.typeExpr.term.getFlags() & TypescriptASTFlags.arrayType) {
            	property.type = "object";
            	propertyType = property.additionalProperties = {};
            	variableType = variable.typeExpr.term.members.members[0].returnTypeAnnotation.term.actualText;
            }
            //other
            else {
                propertyType = property;
            }

            //enums
        	if (definitions.enums[variableType]) {
        		property.enum = definitions.enums[variableType].enumeration;
        	}
        	//other
        	else if (primitiveTypes.indexOf(variableType) == -1) {
        		propertyType.$ref = variableType;
            } else {
                propertyType.type = variableType;
            }
        });
	}

    /**
     * Visits every super type extended by the given type recursively and provisions the given definition with the properties of the associated super definitions.
     *
     * @param type {object} the TypeScript AST node associated to the interface declaration
     * @param definition {object} the definition to be provisionned
     * @param definitions {object} the set of handled interface and enum definitions
     */
    function mergeInheritedProperties(type, definition, definitions) {
    	if (type.extendsList) {
	    	_.each(type.extendsList.members, function (superType) {
	    		var superDefinition = definitions.interfaces[superType.actualText];
	    		// does the provisionning if a definition exists for the current super type
	    		if (superDefinition) {
	    			// recursive call
	    			mergeInheritedProperties(superType, definition, definitions);
	    			// merges properties
	    			for(var superKey in superDefinition.properties) {
	    				definition.properties[superKey] = superDefinition.properties[superKey];
	    			}
	    			// merges required
	    			if (superDefinition.required) {
	    				for (var idx in superDefinition.required) {
	    	            	if (!definition.required) {
	    	            		definition.required = [];
	    	            	}
	    	            	definition.required.push(superDefinition.required[idx]);
	    				}
	    			}
	    		}
	    	});
    	}
    }

    /**
     * Handles enum declaration as new definition and registers it in the global set of enum definitions
     *
     * @param type {object} the TypeScript AST node associated to the enum declaration
     * @param definitions {object} the set of handled interface and enum definitions
     */
    function handleEnumDeclaration(type, definitions) {
	    var definition = definitions.enums[type.name.actualText] = {};
	    definition.enumeration = [];
	    _.each(type.members.members, function (declaration) {
	    	definition.enumeration.push(declaration.declaration.declarators.members[0].id.actualText);
	    });
	}

    /**
     * Extracts the description and the validation keywords from a comment
     *
     * @param from {object} the TypeScript AST node
     * @param to {object} the destination variable or definition.
     */
    function copyComment(from, to) {
        var comments = from.docComments();

        if (comments.length > 0) {
            var commentContent = comments.slice(-1)[0].getDocCommentTextValue();
            copyValidationKeywords(copyDescription(commentContent, to), to);
        }
    }

    /**
     * Extracts the description part of a comment and register it in the description property.
     * The description is supposed to start at first position and may be delimited by @.
     *
     * @param comment {string} the full comment.
     * @param to {object} the destination variable or definition.
     * @returns {string} the full comment minus the beginning description part.
     */
    function copyDescription(comment, to) {
        var delimiter = '@';
        var delimiterIndex = comment.indexOf(delimiter);
        var description = comment.slice(0, delimiterIndex < 0 ? comment.length : delimiterIndex);
        if (description.length > 0) {
            to.description = description;
        }
        return delimiterIndex < 0 ? '' : comment.slice(delimiterIndex);
    }

    /**
     * Extracts the schema validation keywords stored in a comment and register them as properties.
     * A validation keyword starts by a @. It has a name and a value. Several keywords may occur.
     *
     * @param comment {string} the full comment.
     * @param to {object} the destination variable.
     */
    function copyValidationKeywords(comment, to) {
        annotedValidationKeywordPattern.lastIndex = 0;
        // TODO: to improve the use of the exec method: it could make the tokenization
        while ((annotation = annotedValidationKeywordPattern.exec(comment))) {
            var annotationTokens = annotation[0].split(' ');
            var keyword = annotationTokens[0].slice(1);
            // case sensitive check inside the dictionary
            if (validationKeywords.indexOf(keyword) >= 0) {
                var value = annotationTokens.length > 1 ? annotationTokens[1] : '';
                try {
                    value = JSON.parse(value);
                } catch (e) {
                }
                to[keyword] = value;
            }
        }
    }

    api.exec = function(script) {
        api.definitions(script).done(function(definitions) {
            require('sys').print(JSON.stringify(definitions, null, 2));
        });
    }

    if (typeof window === 'undefined' && require.main === module) {
        if (process.argv[2]) {
            api.exec(process.argv[2]);
        } else {
            require('sys').print("Usage: node typson-schema.js <url-or-path-to-type-script-file>\n");
        }
    } else {
        return api;
    }
});
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, you can obtain one at http://mozilla.org/MPL/2.0/. */

'use strict';

/* Filters */

treeherder.filter('showOrHide', function() {
    // determine whether this is a label for a job group (like mochitest)
    return function(input, isCollapsed) {
        if (isCollapsed == true) {
            return "show" + input;
        } else {
            return "hide" + input;
        }
    };
});

treeherder.filter('platformName', ['thPlatformNameMap', function(thPlatformNameMap) {
    // fix the platform name from the raw name in the db, with the more
    // "human read-able" one
    return function(input, name) {
        var newName = platformNameMap[name];
        if (newName) {
            return newName;
        }
        // if it's not found, then return it unchanged.
        return name;
    };
}]);

treeherder.filter('stripHtml', function() {
    return function(input) {
        var str = input || '';
        return str.replace(/<\/?[^>]+>/gi, '');
    };
});

treeherder.filter('linkifyBugs', function() {
    return function(input) {
        var str = input || '';
        var clear_attr = 'ignore-job-clear-on-click';

        var bug_matches = str.match(/-- ([0-9]+)|bug.([0-9]+)/ig);
        var pr_matches = str.match(/PR#([0-9]+)/ig);

        // Settings
        var bug_title = 'bugzilla.mozilla.org';
        var bug_url = '$1';
        var pr_title = 'github.com';
        var pr_url = '$1';

        if (bug_matches) {
            // Separate passes to preserve prefix
            str = str.replace(/Bug ([0-9]+)/g, "Bug " + bug_url);
            str = str.replace(/bug ([0-9]+)/g, "bug " + bug_url);
            str = str.replace(/-- ([0-9]+)/g, "-- " + bug_url);
        }

        if (pr_matches) {
            // Separate passes to preserve prefix
            str = str.replace(/PR#([0-9]+)/g, "PR#" + pr_url);
            str = str.replace(/pr#([0-9]+)/g, "pr#" + pr_url);
        }

        return str;
    };
});

treeherder.filter('initials', function() {
    return function(input) {
        var str = input || '';
        var words = str.split(' ');
        var first = words[0].replace(/[^A-Z]/gi, '')[0];
        var last = words.slice(-1)[0].replace(/[^A-Z]/gi, '')[0];
        var initials = first + last;

        return '' + initials + '';
    };
});

function inTag(str, index, start, end) {
    var prePart = str.substr(0, index);
    return prePart.split(start).length > prePart.split(end).length;
}

treeherder.filter('highlightCommonTerms', function(){
    return function(input, compareStr){
        var tokens = compareStr.split(/[^a-zA-Z0-9_-]+/);
        tokens.sort(function(a, b){
            return b.length - a.length;
        });
        angular.forEach(tokens, function(elem){
            if (elem.length > 0){
                input = input.replace(new RegExp(elem, "gi"), function(token, index, str){
                    if (inTag(str, index, "<", ">") || inTag(str, index, "&", ";")){
                        return token;
                    }else{
                        return ""+token+"";
                    }
                });
            }
        });
        return input;
    };
});

treeherder.filter('escapeHTML', function() {
    return function(text){
        if (text) {
            return text.
                replace(/&/g, '&').
                replace(/</g, '<').
                replace(/>/g, '>').
                replace(/'/g, ''').
                replace(/"/g, '"');
        }
        return '';
    };
});

treeherder.filter('getRevisionUrl', ['thServiceDomain', function(thServiceDomain) {
    return function(revision, projectName) {
        if (revision) {
            return thServiceDomain + '#/jobs?repo=' + projectName + '&revision=' + revision;
        }
        return '';
    };
}]);
<commit_msg>Bug 1185155 - Fix links to revision job data on production<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, you can obtain one at http://mozilla.org/MPL/2.0/. */

'use strict';

/* Filters */

treeherder.filter('showOrHide', function() {
    // determine whether this is a label for a job group (like mochitest)
    return function(input, isCollapsed) {
        if (isCollapsed == true) {
            return "show" + input;
        } else {
            return "hide" + input;
        }
    };
});

treeherder.filter('platformName', ['thPlatformNameMap', function(thPlatformNameMap) {
    // fix the platform name from the raw name in the db, with the more
    // "human read-able" one
    return function(input, name) {
        var newName = platformNameMap[name];
        if (newName) {
            return newName;
        }
        // if it's not found, then return it unchanged.
        return name;
    };
}]);

treeherder.filter('stripHtml', function() {
    return function(input) {
        var str = input || '';
        return str.replace(/<\/?[^>]+>/gi, '');
    };
});

treeherder.filter('linkifyBugs', function() {
    return function(input) {
        var str = input || '';
        var clear_attr = 'ignore-job-clear-on-click';

        var bug_matches = str.match(/-- ([0-9]+)|bug.([0-9]+)/ig);
        var pr_matches = str.match(/PR#([0-9]+)/ig);

        // Settings
        var bug_title = 'bugzilla.mozilla.org';
        var bug_url = '$1';
        var pr_title = 'github.com';
        var pr_url = '$1';

        if (bug_matches) {
            // Separate passes to preserve prefix
            str = str.replace(/Bug ([0-9]+)/g, "Bug " + bug_url);
            str = str.replace(/bug ([0-9]+)/g, "bug " + bug_url);
            str = str.replace(/-- ([0-9]+)/g, "-- " + bug_url);
        }

        if (pr_matches) {
            // Separate passes to preserve prefix
            str = str.replace(/PR#([0-9]+)/g, "PR#" + pr_url);
            str = str.replace(/pr#([0-9]+)/g, "pr#" + pr_url);
        }

        return str;
    };
});

treeherder.filter('initials', function() {
    return function(input) {
        var str = input || '';
        var words = str.split(' ');
        var first = words[0].replace(/[^A-Z]/gi, '')[0];
        var last = words.slice(-1)[0].replace(/[^A-Z]/gi, '')[0];
        var initials = first + last;

        return '' + initials + '';
    };
});

function inTag(str, index, start, end) {
    var prePart = str.substr(0, index);
    return prePart.split(start).length > prePart.split(end).length;
}

treeherder.filter('highlightCommonTerms', function(){
    return function(input, compareStr){
        var tokens = compareStr.split(/[^a-zA-Z0-9_-]+/);
        tokens.sort(function(a, b){
            return b.length - a.length;
        });
        angular.forEach(tokens, function(elem){
            if (elem.length > 0){
                input = input.replace(new RegExp(elem, "gi"), function(token, index, str){
                    if (inTag(str, index, "<", ">") || inTag(str, index, "&", ";")){
                        return token;
                    }else{
                        return ""+token+"";
                    }
                });
            }
        });
        return input;
    };
});

treeherder.filter('escapeHTML', function() {
    return function(text){
        if (text) {
            return text.
                replace(/&/g, '&').
                replace(/</g, '<').
                replace(/>/g, '>').
                replace(/'/g, ''').
                replace(/"/g, '"');
        }
        return '';
    };
});

treeherder.filter('getRevisionUrl', ['thServiceDomain', function(thServiceDomain) {
    return function(revision, projectName) {
        if (revision) {
            return thServiceDomain + '/#/jobs?repo=' + projectName + '&revision=' + revision;
        }
        return '';
    };
}]);
<|endoftext|>


<commit_before>/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

import { ROUTES } from '../navigation/constants';
import { UIDatabase } from '../database';
import { PRESCRIPTION_ACTIONS } from '../actions/PrescriptionActions';

const initialState = () => ({
  currentTab: 0,
  transaction: null,
  items: UIDatabase.objects('Item'),
  itemSearchTerm: '',
});

export const PrescriptionReducer = (state = initialState(), action) => {
  const { type } = action;

  switch (type) {
    case 'Navigation/NAVIGATE': {
      const { routeName, params } = action;

      if (routeName !== ROUTES.PRESCRIPTION) return state;
      const { transaction } = params;

      return { ...state, transaction };
    }
    case PRESCRIPTION_ACTIONS.REFRESH: {
      return { ...state };
    }

    case PRESCRIPTION_ACTIONS.FILTER: {
      const { payload } = action;
      const { itemSearchTerm } = payload;

      return { ...state, itemSearchTerm };
    }

    default:
      return state;
  }
};
<commit_msg>Add PrescriptionReducer update<commit_after>/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

import { ROUTES } from '../navigation/constants';
import { UIDatabase } from '../database';
import { PRESCRIPTION_ACTIONS } from '../actions/PrescriptionActions';

const initialState = () => ({
  currentTab: 0,
  transaction: null,
  items: UIDatabase.objects('Item'),
  itemSearchTerm: '',
  commentModalOpen: false,
});

export const PrescriptionReducer = (state = initialState(), action) => {
  const { type } = action;

  switch (type) {
    case 'Navigation/NAVIGATE': {
      const { routeName, params } = action;

      if (routeName !== ROUTES.PRESCRIPTION) return state;
      const { transaction } = params;

      return { ...state, transaction };
    }

    case PRESCRIPTION_ACTIONS.REFRESH: {
      return { ...state };
    }

    case PRESCRIPTION_ACTIONS.FILTER: {
      const { payload } = action;
      const { itemSearchTerm } = payload;

      return { ...state, itemSearchTerm };
    }

    case PRESCRIPTION_ACTIONS.OPEN_COMMENT_MODAL: {
      return { ...state, commentModalOpen: true };
    }

    case PRESCRIPTION_ACTIONS.CLOSE_COMMENT_MODAL: {
      return { ...state, commentModalOpen: false };
    }

    default: {
      return state;
    }
  }
};
<|endoftext|>


<commit_before>import * as types from '../actions/actionTypes';
import initialState from './initialState';

export default function destinationReducer(state = initialState.destinations, action){
  switch (action.type){
    case types.LOAD_ALL_DESTS_SUCCESS:
      return action.destinations;
    case types.UPDATE_DEST_SUCCESS:
      return [
        ...state.filter(dest => dest._id != action.destination._id),
        Object.assign({}, action.destination)
      ];
    default:
      return state;
  }
}
<commit_msg>Feat: CRUD Update destination<commit_after>import * as types from '../actions/actionTypes';
import initialState from './initialState';

export default function destinationReducer(state = initialState.destinations, action){
  switch (action.type){
    case types.LOAD_ALL_DESTS_SUCCESS:
      return action.destinations;
    case types.UPDATE_DEST_SUCCESS:
      return [
        ...state.filter(dest => dest._id != action.response._id),
        Object.assign({}, action.response)
      ];
    default:
      return state;
  }
}
<|endoftext|>


<commit_before>THREE.WebGLProgram = ( function () {

	var programIdCount = 0;

	function generateDefines( defines ) {

		var chunks = [];

		for ( var name in defines ) {

			var value = defines[ name ];

			if ( value === false ) continue;

			chunks.push( '#define ' + name + ' ' + value );

		}

		return chunks.join( '\n' );

	}

	function fetchUniformLocations( gl, program, identifiers ) {

		var uniforms = {};

		var n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );
		for ( var i = 0; i < n; i ++ ) {

			var info = gl.getActiveUniform( program , i );
			var name = info.name;
			var location = gl.getUniformLocation( program, name );

			//console.log("THREE.WebGLProgram: ACTIVE UNIFORM:", name);

			var suffixPos = name.lastIndexOf( '[0]' );
			if ( suffixPos !== -1 && suffixPos === name.length - 3 ) {

				uniforms[ name.substr( 0, suffixPos ) ] = location;

			}

			uniforms[ name ] = location;

		}

		return uniforms;

	}

	function fetchAttributeLocations( gl, program, identifiers ) {

		var attributes = {};

		var n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );
		for ( var i = 0; i < n; i ++ ) {

			var info = gl.getActiveAttrib( program , i );
			var name = info.name;

			//console.log("THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:", name);

			attributes[ name ] = gl.getAttribLocation( program, name );

		}

		return attributes;

	}

	function filterEmptyLine( string ) {

		return string !== '';

	}

	return function ( renderer, code, material, parameters ) {

		var gl = renderer.context;

		var defines = material.defines;
		var uniforms = material.__webglShader.uniforms;
		var attributes = material.attributes;

		var vertexShader = material.__webglShader.vertexShader;
		var fragmentShader = material.__webglShader.fragmentShader;

		var index0AttributeName = material.index0AttributeName;

		/*
		if ( index0AttributeName === undefined && parameters.morphTargets === true ) {

			// programs with morphTargets displace position out of attribute 0

			index0AttributeName = 'position';

		}
		*/

		var shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';

		if ( parameters.shadowMapType === THREE.PCFShadowMap ) {

			shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';

		} else if ( parameters.shadowMapType === THREE.PCFSoftShadowMap ) {

			shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';

		}

		var envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
		var envMapModeDefine = 'ENVMAP_MODE_REFLECTION';
		var envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';

		if ( parameters.envMap ) {

			switch ( material.envMap.mapping ) {

				case THREE.CubeReflectionMapping:
				case THREE.CubeRefractionMapping:
					envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
					break;

				case THREE.EquirectangularReflectionMapping:
				case THREE.EquirectangularRefractionMapping:
					envMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';
					break;

				case THREE.SphericalReflectionMapping:
					envMapTypeDefine = 'ENVMAP_TYPE_SPHERE';
					break;

			}

			switch ( material.envMap.mapping ) {

				case THREE.CubeRefractionMapping:
				case THREE.EquirectangularRefractionMapping:
					envMapModeDefine = 'ENVMAP_MODE_REFRACTION';
					break;

			}

			switch ( material.combine ) {

				case THREE.MultiplyOperation:
					envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
					break;

				case THREE.MixOperation:
					envMapBlendingDefine = 'ENVMAP_BLENDING_MIX';
					break;

				case THREE.AddOperation:
					envMapBlendingDefine = 'ENVMAP_BLENDING_ADD';
					break;

			}

		}

		var gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;

		// console.log( 'building new program ' );

		//

		var customDefines = generateDefines( defines );

		//

		var program = gl.createProgram();

		var prefixVertex, prefixFragment;

		if ( material instanceof THREE.RawShaderMaterial ) {

			prefixVertex = '';
			prefixFragment = '';

		} else {

			prefixVertex = [

				'precision ' + parameters.precision + ' float;',
				'precision ' + parameters.precision + ' int;',

				customDefines,

				parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',

				renderer.gammaInput ? '#define GAMMA_INPUT' : '',
				renderer.gammaOutput ? '#define GAMMA_OUTPUT' : '',
				'#define GAMMA_FACTOR ' + gammaFactorDefine,

				'#define MAX_DIR_LIGHTS ' + parameters.maxDirLights,
				'#define MAX_POINT_LIGHTS ' + parameters.maxPointLights,
				'#define MAX_SPOT_LIGHTS ' + parameters.maxSpotLights,
				'#define MAX_HEMI_LIGHTS ' + parameters.maxHemiLights,

				'#define MAX_SHADOWS ' + parameters.maxShadows,

				'#define MAX_BONES ' + parameters.maxBones,

				parameters.map ? '#define USE_MAP' : '',
				parameters.envMap ? '#define USE_ENVMAP' : '',
				parameters.envMap ? '#define ' + envMapModeDefine : '',
				parameters.lightMap ? '#define USE_LIGHTMAP' : '',
				parameters.aoMap ? '#define USE_AOMAP' : '',
				parameters.bumpMap ? '#define USE_BUMPMAP' : '',
				parameters.normalMap ? '#define USE_NORMALMAP' : '',
				parameters.specularMap ? '#define USE_SPECULARMAP' : '',
				parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
				parameters.vertexColors ? '#define USE_COLOR' : '',

				parameters.flatShading ? '#define FLAT_SHADED': '',

				parameters.skinning ? '#define USE_SKINNING' : '',
				parameters.useVertexTexture ? '#define BONE_TEXTURE' : '',

				parameters.morphTargets ? '#define USE_MORPHTARGETS' : '',
				parameters.morphNormals ? '#define USE_MORPHNORMALS' : '',
				parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
				parameters.flipSided ? '#define FLIP_SIDED' : '',

				parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
				parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
				parameters.shadowMapDebug ? '#define SHADOWMAP_DEBUG' : '',
				parameters.shadowMapCascade ? '#define SHADOWMAP_CASCADE' : '',

				parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',

				parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
				parameters.logarithmicDepthBuffer && renderer.extensions.get('EXT_frag_depth') ? '#define USE_LOGDEPTHBUF_EXT' : '',

				'uniform mat4 modelMatrix;',
				'uniform mat4 modelViewMatrix;',
				'uniform mat4 projectionMatrix;',
				'uniform mat4 viewMatrix;',
				'uniform mat3 normalMatrix;',
				'uniform vec3 cameraPosition;',

				'attribute vec3 position;',
				'attribute vec3 normal;',
				'attribute vec2 uv;',

				'#ifdef USE_COLOR',

				'	attribute vec3 color;',

				'#endif',

				'#ifdef USE_MORPHTARGETS',

				'	attribute vec3 morphTarget0;',
				'	attribute vec3 morphTarget1;',
				'	attribute vec3 morphTarget2;',
				'	attribute vec3 morphTarget3;',

				'	#ifdef USE_MORPHNORMALS',

				'		attribute vec3 morphNormal0;',
				'		attribute vec3 morphNormal1;',
				'		attribute vec3 morphNormal2;',
				'		attribute vec3 morphNormal3;',

				'	#else',

				'		attribute vec3 morphTarget4;',
				'		attribute vec3 morphTarget5;',
				'		attribute vec3 morphTarget6;',
				'		attribute vec3 morphTarget7;',

				'	#endif',

				'#endif',

				'#ifdef USE_SKINNING',

				'	attribute vec4 skinIndex;',
				'	attribute vec4 skinWeight;',

				'#endif',

				'\n'

			].filter( filterEmptyLine ).join( '\n' );

			prefixFragment = [

				( parameters.bumpMap || parameters.normalMap || parameters.flatShading || material.derivatives ) ? '#extension GL_OES_standard_derivatives : enable' : '',

				'precision ' + parameters.precision + ' float;',
				'precision ' + parameters.precision + ' int;',

				customDefines,

				'#define MAX_DIR_LIGHTS ' + parameters.maxDirLights,
				'#define MAX_POINT_LIGHTS ' + parameters.maxPointLights,
				'#define MAX_SPOT_LIGHTS ' + parameters.maxSpotLights,
				'#define MAX_HEMI_LIGHTS ' + parameters.maxHemiLights,

				'#define MAX_SHADOWS ' + parameters.maxShadows,

				parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '',

				renderer.gammaInput ? '#define GAMMA_INPUT' : '',
				renderer.gammaOutput ? '#define GAMMA_OUTPUT' : '',
				'#define GAMMA_FACTOR ' + gammaFactorDefine,

				( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
				( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',

				parameters.map ? '#define USE_MAP' : '',
				parameters.envMap ? '#define USE_ENVMAP' : '',
				parameters.envMap ? '#define ' + envMapTypeDefine : '',
				parameters.envMap ? '#define ' + envMapModeDefine : '',
				parameters.envMap ? '#define ' + envMapBlendingDefine : '',
				parameters.lightMap ? '#define USE_LIGHTMAP' : '',
				parameters.aoMap ? '#define USE_AOMAP' : '',
				parameters.bumpMap ? '#define USE_BUMPMAP' : '',
				parameters.normalMap ? '#define USE_NORMALMAP' : '',
				parameters.specularMap ? '#define USE_SPECULARMAP' : '',
				parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
				parameters.vertexColors ? '#define USE_COLOR' : '',

				parameters.flatShading ? '#define FLAT_SHADED': '',

				parameters.metal ? '#define METAL' : '',
				parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
				parameters.flipSided ? '#define FLIP_SIDED' : '',

				parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
				parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
				parameters.shadowMapDebug ? '#define SHADOWMAP_DEBUG' : '',
				parameters.shadowMapCascade ? '#define SHADOWMAP_CASCADE' : '',

				parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
				parameters.logarithmicDepthBuffer && renderer.extensions.get('EXT_frag_depth') ? '#define USE_LOGDEPTHBUF_EXT' : '',

				'uniform mat4 viewMatrix;',
				'uniform vec3 cameraPosition;',

				'\n'

			].filter( filterEmptyLine ).join( '\n' );

		}

		var vertexGlsl = prefixVertex + vertexShader;
		var fragmentGlsl = prefixFragment + fragmentShader;

		var glVertexShader = new THREE.WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );
		var glFragmentShader = new THREE.WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );

		gl.attachShader( program, glVertexShader );
		gl.attachShader( program, glFragmentShader );

		if ( index0AttributeName !== undefined ) {

			// Force a particular attribute to index 0.
			// because potentially expensive emulation is done by browser if attribute 0 is disabled.
			// And, color, for example is often automatically bound to index 0 so disabling it

			gl.bindAttribLocation( program, 0, index0AttributeName );

		}

		gl.linkProgram( program );

		var programLogInfo = gl.getProgramInfoLog( program );
		var vertexErrorLogInfo = gl.getShaderInfoLog( glVertexShader );
		var fragmentErrorLogInfo = gl.getShaderInfoLog( glFragmentShader );

		if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {

			console.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLogInfo, vertexErrorLogInfo, fragmentErrorLogInfo );

		}

		if ( programLogInfo !== '' ) {

			console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLogInfo );

		}

		// clean up

		gl.deleteShader( glVertexShader );
		gl.deleteShader( glFragmentShader );

		// set up caching for uniform locations

		var getUniforms = function() { return this._cachedUniforms; };

		this.getUniforms = function() {

			// fetch, cache, and next time just use a dumb accessor
			var uniforms = fetchUniformLocations( gl, program );
			this._cachedUniforms = uniforms;
			this.getUniforms = getUniforms;
			return uniforms;

		};

		// set up caching for attribute locations

		var getAttributes = function() { return this._cachedAttributes; };

		this.getAttributes = function() {

			var attributes = fetchAttributeLocations( gl, program );
			this._cachedAttributes = attributes;
			this.getAttributes = getAttributes;
			return attributes;

		};

		// DEPRECATED

		Object.defineProperties( this, {

			uniforms: {
				get: function() {

					console.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );
					return this.getUniforms();

				}
			},

			attributes: {
				get: function() {

					console.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );
					return this.getAttributes();

				}
			},

			attributesKeys: {
				get: function() {

					console.warn( 'THREE.WebGLProgram: .attributesKeys has been removed.' );
					return Object.keys( this.getAttributes() );

				}
			}
		});

		//

		this.id = programIdCount ++;
		this.code = code;
		this.usedTimes = 1;
		this.program = program;
		this.vertexShader = glVertexShader;
		this.fragmentShader = glFragmentShader;

		return this;

	};

} )();
<commit_msg>WebGLProgram: Minor clean up.<commit_after>THREE.WebGLProgram = ( function () {

	var programIdCount = 0;

	function generateDefines( defines ) {

		var chunks = [];

		for ( var name in defines ) {

			var value = defines[ name ];

			if ( value === false ) continue;

			chunks.push( '#define ' + name + ' ' + value );

		}

		return chunks.join( '\n' );

	}

	function fetchUniformLocations( gl, program, identifiers ) {

		var uniforms = {};

		var n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );

		for ( var i = 0; i < n; i ++ ) {

			var info = gl.getActiveUniform( program , i );
			var name = info.name;
			var location = gl.getUniformLocation( program, name );

			//console.log("THREE.WebGLProgram: ACTIVE UNIFORM:", name);

			var suffixPos = name.lastIndexOf( '[0]' );
			if ( suffixPos !== -1 && suffixPos === name.length - 3 ) {

				uniforms[ name.substr( 0, suffixPos ) ] = location;

			}

			uniforms[ name ] = location;

		}

		return uniforms;

	}

	function fetchAttributeLocations( gl, program, identifiers ) {

		var attributes = {};

		var n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );

		for ( var i = 0; i < n; i ++ ) {

			var info = gl.getActiveAttrib( program , i );
			var name = info.name;

			//console.log("THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:", name);

			attributes[ name ] = gl.getAttribLocation( program, name );

		}

		return attributes;

	}

	function filterEmptyLine( string ) {

		return string !== '';

	}

	return function ( renderer, code, material, parameters ) {

		var gl = renderer.context;

		var defines = material.defines;
		var uniforms = material.__webglShader.uniforms;
		var attributes = material.attributes;

		var vertexShader = material.__webglShader.vertexShader;
		var fragmentShader = material.__webglShader.fragmentShader;

		var index0AttributeName = material.index0AttributeName;

		/*
		if ( index0AttributeName === undefined && parameters.morphTargets === true ) {

			// programs with morphTargets displace position out of attribute 0

			index0AttributeName = 'position';

		}
		*/

		var shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';

		if ( parameters.shadowMapType === THREE.PCFShadowMap ) {

			shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';

		} else if ( parameters.shadowMapType === THREE.PCFSoftShadowMap ) {

			shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';

		}

		var envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
		var envMapModeDefine = 'ENVMAP_MODE_REFLECTION';
		var envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';

		if ( parameters.envMap ) {

			switch ( material.envMap.mapping ) {

				case THREE.CubeReflectionMapping:
				case THREE.CubeRefractionMapping:
					envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
					break;

				case THREE.EquirectangularReflectionMapping:
				case THREE.EquirectangularRefractionMapping:
					envMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';
					break;

				case THREE.SphericalReflectionMapping:
					envMapTypeDefine = 'ENVMAP_TYPE_SPHERE';
					break;

			}

			switch ( material.envMap.mapping ) {

				case THREE.CubeRefractionMapping:
				case THREE.EquirectangularRefractionMapping:
					envMapModeDefine = 'ENVMAP_MODE_REFRACTION';
					break;

			}

			switch ( material.combine ) {

				case THREE.MultiplyOperation:
					envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
					break;

				case THREE.MixOperation:
					envMapBlendingDefine = 'ENVMAP_BLENDING_MIX';
					break;

				case THREE.AddOperation:
					envMapBlendingDefine = 'ENVMAP_BLENDING_ADD';
					break;

			}

		}

		var gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;

		// console.log( 'building new program ' );

		//

		var customDefines = generateDefines( defines );

		//

		var program = gl.createProgram();

		var prefixVertex, prefixFragment;

		if ( material instanceof THREE.RawShaderMaterial ) {

			prefixVertex = '';
			prefixFragment = '';

		} else {

			prefixVertex = [

				'precision ' + parameters.precision + ' float;',
				'precision ' + parameters.precision + ' int;',

				customDefines,

				parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',

				renderer.gammaInput ? '#define GAMMA_INPUT' : '',
				renderer.gammaOutput ? '#define GAMMA_OUTPUT' : '',
				'#define GAMMA_FACTOR ' + gammaFactorDefine,

				'#define MAX_DIR_LIGHTS ' + parameters.maxDirLights,
				'#define MAX_POINT_LIGHTS ' + parameters.maxPointLights,
				'#define MAX_SPOT_LIGHTS ' + parameters.maxSpotLights,
				'#define MAX_HEMI_LIGHTS ' + parameters.maxHemiLights,

				'#define MAX_SHADOWS ' + parameters.maxShadows,

				'#define MAX_BONES ' + parameters.maxBones,

				parameters.map ? '#define USE_MAP' : '',
				parameters.envMap ? '#define USE_ENVMAP' : '',
				parameters.envMap ? '#define ' + envMapModeDefine : '',
				parameters.lightMap ? '#define USE_LIGHTMAP' : '',
				parameters.aoMap ? '#define USE_AOMAP' : '',
				parameters.bumpMap ? '#define USE_BUMPMAP' : '',
				parameters.normalMap ? '#define USE_NORMALMAP' : '',
				parameters.specularMap ? '#define USE_SPECULARMAP' : '',
				parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
				parameters.vertexColors ? '#define USE_COLOR' : '',

				parameters.flatShading ? '#define FLAT_SHADED': '',

				parameters.skinning ? '#define USE_SKINNING' : '',
				parameters.useVertexTexture ? '#define BONE_TEXTURE' : '',

				parameters.morphTargets ? '#define USE_MORPHTARGETS' : '',
				parameters.morphNormals ? '#define USE_MORPHNORMALS' : '',
				parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
				parameters.flipSided ? '#define FLIP_SIDED' : '',

				parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
				parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
				parameters.shadowMapDebug ? '#define SHADOWMAP_DEBUG' : '',
				parameters.shadowMapCascade ? '#define SHADOWMAP_CASCADE' : '',

				parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',

				parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
				parameters.logarithmicDepthBuffer && renderer.extensions.get('EXT_frag_depth') ? '#define USE_LOGDEPTHBUF_EXT' : '',

				'uniform mat4 modelMatrix;',
				'uniform mat4 modelViewMatrix;',
				'uniform mat4 projectionMatrix;',
				'uniform mat4 viewMatrix;',
				'uniform mat3 normalMatrix;',
				'uniform vec3 cameraPosition;',

				'attribute vec3 position;',
				'attribute vec3 normal;',
				'attribute vec2 uv;',

				'#ifdef USE_COLOR',

				'	attribute vec3 color;',

				'#endif',

				'#ifdef USE_MORPHTARGETS',

				'	attribute vec3 morphTarget0;',
				'	attribute vec3 morphTarget1;',
				'	attribute vec3 morphTarget2;',
				'	attribute vec3 morphTarget3;',

				'	#ifdef USE_MORPHNORMALS',

				'		attribute vec3 morphNormal0;',
				'		attribute vec3 morphNormal1;',
				'		attribute vec3 morphNormal2;',
				'		attribute vec3 morphNormal3;',

				'	#else',

				'		attribute vec3 morphTarget4;',
				'		attribute vec3 morphTarget5;',
				'		attribute vec3 morphTarget6;',
				'		attribute vec3 morphTarget7;',

				'	#endif',

				'#endif',

				'#ifdef USE_SKINNING',

				'	attribute vec4 skinIndex;',
				'	attribute vec4 skinWeight;',

				'#endif',

				'\n'

			].filter( filterEmptyLine ).join( '\n' );

			prefixFragment = [

				( parameters.bumpMap || parameters.normalMap || parameters.flatShading || material.derivatives ) ? '#extension GL_OES_standard_derivatives : enable' : '',

				'precision ' + parameters.precision + ' float;',
				'precision ' + parameters.precision + ' int;',

				customDefines,

				'#define MAX_DIR_LIGHTS ' + parameters.maxDirLights,
				'#define MAX_POINT_LIGHTS ' + parameters.maxPointLights,
				'#define MAX_SPOT_LIGHTS ' + parameters.maxSpotLights,
				'#define MAX_HEMI_LIGHTS ' + parameters.maxHemiLights,

				'#define MAX_SHADOWS ' + parameters.maxShadows,

				parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '',

				renderer.gammaInput ? '#define GAMMA_INPUT' : '',
				renderer.gammaOutput ? '#define GAMMA_OUTPUT' : '',
				'#define GAMMA_FACTOR ' + gammaFactorDefine,

				( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
				( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',

				parameters.map ? '#define USE_MAP' : '',
				parameters.envMap ? '#define USE_ENVMAP' : '',
				parameters.envMap ? '#define ' + envMapTypeDefine : '',
				parameters.envMap ? '#define ' + envMapModeDefine : '',
				parameters.envMap ? '#define ' + envMapBlendingDefine : '',
				parameters.lightMap ? '#define USE_LIGHTMAP' : '',
				parameters.aoMap ? '#define USE_AOMAP' : '',
				parameters.bumpMap ? '#define USE_BUMPMAP' : '',
				parameters.normalMap ? '#define USE_NORMALMAP' : '',
				parameters.specularMap ? '#define USE_SPECULARMAP' : '',
				parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
				parameters.vertexColors ? '#define USE_COLOR' : '',

				parameters.flatShading ? '#define FLAT_SHADED': '',

				parameters.metal ? '#define METAL' : '',
				parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
				parameters.flipSided ? '#define FLIP_SIDED' : '',

				parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
				parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
				parameters.shadowMapDebug ? '#define SHADOWMAP_DEBUG' : '',
				parameters.shadowMapCascade ? '#define SHADOWMAP_CASCADE' : '',

				parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
				parameters.logarithmicDepthBuffer && renderer.extensions.get('EXT_frag_depth') ? '#define USE_LOGDEPTHBUF_EXT' : '',

				'uniform mat4 viewMatrix;',
				'uniform vec3 cameraPosition;',

				'\n'

			].filter( filterEmptyLine ).join( '\n' );

		}

		var vertexGlsl = prefixVertex + vertexShader;
		var fragmentGlsl = prefixFragment + fragmentShader;

		var glVertexShader = new THREE.WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );
		var glFragmentShader = new THREE.WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );

		gl.attachShader( program, glVertexShader );
		gl.attachShader( program, glFragmentShader );

		if ( index0AttributeName !== undefined ) {

			// Force a particular attribute to index 0.
			// because potentially expensive emulation is done by browser if attribute 0 is disabled.
			// And, color, for example is often automatically bound to index 0 so disabling it

			gl.bindAttribLocation( program, 0, index0AttributeName );

		}

		gl.linkProgram( program );

		var programLogInfo = gl.getProgramInfoLog( program );
		var vertexErrorLogInfo = gl.getShaderInfoLog( glVertexShader );
		var fragmentErrorLogInfo = gl.getShaderInfoLog( glFragmentShader );

		if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {

			console.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLogInfo, vertexErrorLogInfo, fragmentErrorLogInfo );

		}

		if ( programLogInfo !== '' ) {

			console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLogInfo );

		}

		// clean up

		gl.deleteShader( glVertexShader );
		gl.deleteShader( glFragmentShader );

		// set up caching for uniform locations

		var getUniforms = function() { return this._cachedUniforms; };

		this.getUniforms = function() {

			// fetch, cache, and next time just use a dumb accessor
			var uniforms = fetchUniformLocations( gl, program );
			this._cachedUniforms = uniforms;
			this.getUniforms = getUniforms;
			return uniforms;

		};

		// set up caching for attribute locations

		var getAttributes = function() { return this._cachedAttributes; };

		this.getAttributes = function() {

			var attributes = fetchAttributeLocations( gl, program );
			this._cachedAttributes = attributes;
			this.getAttributes = getAttributes;
			return attributes;

		};

		// DEPRECATED

		Object.defineProperties( this, {

			uniforms: {
				get: function() {

					console.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );
					return this.getUniforms();

				}
			},

			attributes: {
				get: function() {

					console.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );
					return this.getAttributes();

				}
			}

		});

		//

		this.id = programIdCount ++;
		this.code = code;
		this.usedTimes = 1;
		this.program = program;
		this.vertexShader = glVertexShader;
		this.fragmentShader = glFragmentShader;

		return this;

	};

} )();
<|endoftext|>


<commit_before>/**
 * @author mrdoob / http://mrdoob.com/
 */

import { Matrix4 } from '../../math/Matrix4.js';
import { Vector4 } from '../../math/Vector4.js';
import { Vector3 } from '../../math/Vector3.js';
import { Quaternion } from '../../math/Quaternion.js';
import { ArrayCamera } from '../../cameras/ArrayCamera.js';
import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js';

function WebVRManager( renderer ) {

	var scope = this;

	var device = null;
	var frameData = null;

	var poseTarget = null;

	var standingMatrix = new Matrix4();
	var standingMatrixInverse = new Matrix4();

	if ( typeof window !== 'undefined' && 'VRFrameData' in window ) {

		frameData = new window.VRFrameData();

	}

	var matrixWorldInverse = new Matrix4();
	var tempQuaternion = new Quaternion();
	var tempPosition = new Vector3();

	var cameraL = new PerspectiveCamera();
	cameraL.bounds = new Vector4( 0.0, 0.0, 0.5, 1.0 );
	cameraL.layers.enable( 1 );

	var cameraR = new PerspectiveCamera();
	cameraR.bounds = new Vector4( 0.5, 0.0, 0.5, 1.0 );
	cameraR.layers.enable( 2 );

	var cameraVR = new ArrayCamera( [ cameraL, cameraR ] );
	cameraVR.layers.enable( 1 );
	cameraVR.layers.enable( 2 );

	//

	var currentSize, currentPixelRatio;

	function onVRDisplayPresentChange() {

		if ( device !== null && device.isPresenting ) {

			var eyeParameters = device.getEyeParameters( 'left' );
			var renderWidth = eyeParameters.renderWidth;
			var renderHeight = eyeParameters.renderHeight;

			currentPixelRatio = renderer.getPixelRatio();
			currentSize = renderer.getSize();

			renderer.setDrawingBufferSize( renderWidth * 2, renderHeight, 1 );

		} else if ( scope.enabled ) {

			renderer.setDrawingBufferSize( currentSize.width, currentSize.height, currentPixelRatio );

		}

	}

	if ( typeof window !== 'undefined' ) {

		window.addEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false );

	}

	//

	this.enabled = false;
	this.userHeight = 1.6;

	this.getDevice = function () {

		return device;

	};

	this.setDevice = function ( value ) {

		if ( value !== undefined ) device = value;

	};

	this.setPoseTarget = function ( object ) {

		if ( object !== undefined ) poseTarget = object;

	};

	this.getCamera = function ( camera ) {

		if ( device === null ) return camera;

		device.depthNear = camera.near;
		device.depthFar = camera.far;

		device.getFrameData( frameData );

		//

		var stageParameters = device.stageParameters;

		if ( stageParameters ) {

			standingMatrix.fromArray( stageParameters.sittingToStandingTransform );

		} else {

			standingMatrix.makeTranslation( 0, scope.userHeight, 0 );

		}

		var pose = frameData.pose;
		var poseObject = poseTarget !== null ? poseTarget : camera;

		// We want to manipulate poseObject by its position and quaternion components since users may rely on them.
		poseObject.matrix.copy( standingMatrix );
		poseObject.matrix.decompose(poseObject.position, poseObject.quaternion, poseObject.scale);

		if ( pose.orientation !== null ) {

			tempQuaternion.fromArray ( pose.orientation );
			poseObject.quaternion.multiply( tempQuaternion );

		}

		if ( pose.position !== null ) {

			tempQuaternion.setFromRotationMatrix(standingMatrix);
			tempPosition.fromArray( pose.position );
			tempPosition.applyQuaternion(tempQuaternion);
			poseObject.position.add( tempPosition );

		}

		poseObject.updateMatrixWorld();

		if ( device.isPresenting === false ) return camera;

		//

		cameraL.near = camera.near;
		cameraR.near = camera.near;

		cameraL.far = camera.far;
		cameraR.far = camera.far;

		cameraVR.matrixWorld.copy( camera.matrixWorld );
		cameraVR.matrixWorldInverse.copy( camera.matrixWorldInverse );

		cameraL.matrixWorldInverse.fromArray( frameData.leftViewMatrix );
		cameraR.matrixWorldInverse.fromArray( frameData.rightViewMatrix );

		// TODO (mrdoob) Double check this code

		standingMatrixInverse.getInverse( standingMatrix );

		cameraL.matrixWorldInverse.multiply( standingMatrixInverse );
		cameraR.matrixWorldInverse.multiply( standingMatrixInverse );

		var parent = poseObject.parent;

		if ( parent !== null ) {

			matrixWorldInverse.getInverse( parent.matrixWorld );

			cameraL.matrixWorldInverse.multiply( matrixWorldInverse );
			cameraR.matrixWorldInverse.multiply( matrixWorldInverse );

		}

		// envMap and Mirror needs camera.matrixWorld

		cameraL.matrixWorld.getInverse( cameraL.matrixWorldInverse );
		cameraR.matrixWorld.getInverse( cameraR.matrixWorldInverse );

		cameraL.projectionMatrix.fromArray( frameData.leftProjectionMatrix );
		cameraR.projectionMatrix.fromArray( frameData.rightProjectionMatrix );

		// HACK (mrdoob)
		// https://github.com/w3c/webvr/issues/203

		cameraVR.projectionMatrix.copy( cameraL.projectionMatrix );

		//

		var layers = device.getLayers();

		if ( layers.length ) {

			var layer = layers[ 0 ];

			if ( layer.leftBounds !== null && layer.leftBounds.length === 4 ) {

				cameraL.bounds.fromArray( layer.leftBounds );

			}

			if ( layer.rightBounds !== null && layer.rightBounds.length === 4 ) {

				cameraR.bounds.fromArray( layer.rightBounds );

			}

		}

		return cameraVR;

	};

	this.getStandingMatrix = function () {

		return standingMatrix;

	};

	this.submitFrame = function () {

		if ( device && device.isPresenting ) device.submitFrame();

	};

	this.dispose = function () {

		if ( typeof window !== 'undefined' ) {

			window.removeEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange );

		}

	};

}

export { WebVRManager };
<commit_msg>formatting<commit_after>/**
 * @author mrdoob / http://mrdoob.com/
 */

import { Matrix4 } from '../../math/Matrix4.js';
import { Vector4 } from '../../math/Vector4.js';
import { Vector3 } from '../../math/Vector3.js';
import { Quaternion } from '../../math/Quaternion.js';
import { ArrayCamera } from '../../cameras/ArrayCamera.js';
import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js';

function WebVRManager( renderer ) {

	var scope = this;

	var device = null;
	var frameData = null;

	var poseTarget = null;

	var standingMatrix = new Matrix4();
	var standingMatrixInverse = new Matrix4();

	if ( typeof window !== 'undefined' && 'VRFrameData' in window ) {

		frameData = new window.VRFrameData();

	}

	var matrixWorldInverse = new Matrix4();
	var tempQuaternion = new Quaternion();
	var tempPosition = new Vector3();

	var cameraL = new PerspectiveCamera();
	cameraL.bounds = new Vector4( 0.0, 0.0, 0.5, 1.0 );
	cameraL.layers.enable( 1 );

	var cameraR = new PerspectiveCamera();
	cameraR.bounds = new Vector4( 0.5, 0.0, 0.5, 1.0 );
	cameraR.layers.enable( 2 );

	var cameraVR = new ArrayCamera( [ cameraL, cameraR ] );
	cameraVR.layers.enable( 1 );
	cameraVR.layers.enable( 2 );

	//

	var currentSize, currentPixelRatio;

	function onVRDisplayPresentChange() {

		if ( device !== null && device.isPresenting ) {

			var eyeParameters = device.getEyeParameters( 'left' );
			var renderWidth = eyeParameters.renderWidth;
			var renderHeight = eyeParameters.renderHeight;

			currentPixelRatio = renderer.getPixelRatio();
			currentSize = renderer.getSize();

			renderer.setDrawingBufferSize( renderWidth * 2, renderHeight, 1 );

		} else if ( scope.enabled ) {

			renderer.setDrawingBufferSize( currentSize.width, currentSize.height, currentPixelRatio );

		}

	}

	if ( typeof window !== 'undefined' ) {

		window.addEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false );

	}

	//

	this.enabled = false;
	this.userHeight = 1.6;

	this.getDevice = function () {

		return device;

	};

	this.setDevice = function ( value ) {

		if ( value !== undefined ) device = value;

	};

	this.setPoseTarget = function ( object ) {

		if ( object !== undefined ) poseTarget = object;

	};

	this.getCamera = function ( camera ) {

		if ( device === null ) return camera;

		device.depthNear = camera.near;
		device.depthFar = camera.far;

		device.getFrameData( frameData );

		//

		var stageParameters = device.stageParameters;

		if ( stageParameters ) {

			standingMatrix.fromArray( stageParameters.sittingToStandingTransform );

		} else {

			standingMatrix.makeTranslation( 0, scope.userHeight, 0 );

		}

		var pose = frameData.pose;
		var poseObject = poseTarget !== null ? poseTarget : camera;

		// We want to manipulate poseObject by its position and quaternion components since users may rely on them.
		poseObject.matrix.copy( standingMatrix );
		poseObject.matrix.decompose( poseObject.position, poseObject.quaternion, poseObject.scale );

		if ( pose.orientation !== null ) {

			tempQuaternion.fromArray ( pose.orientation );
			poseObject.quaternion.multiply( tempQuaternion );

		}

		if ( pose.position !== null ) {

			tempQuaternion.setFromRotationMatrix( standingMatrix );
			tempPosition.fromArray( pose.position );
			tempPosition.applyQuaternion( tempQuaternion );
			poseObject.position.add( tempPosition );

		}

		poseObject.updateMatrixWorld();

		if ( device.isPresenting === false ) return camera;

		//

		cameraL.near = camera.near;
		cameraR.near = camera.near;

		cameraL.far = camera.far;
		cameraR.far = camera.far;

		cameraVR.matrixWorld.copy( camera.matrixWorld );
		cameraVR.matrixWorldInverse.copy( camera.matrixWorldInverse );

		cameraL.matrixWorldInverse.fromArray( frameData.leftViewMatrix );
		cameraR.matrixWorldInverse.fromArray( frameData.rightViewMatrix );

		// TODO (mrdoob) Double check this code

		standingMatrixInverse.getInverse( standingMatrix );

		cameraL.matrixWorldInverse.multiply( standingMatrixInverse );
		cameraR.matrixWorldInverse.multiply( standingMatrixInverse );

		var parent = poseObject.parent;

		if ( parent !== null ) {

			matrixWorldInverse.getInverse( parent.matrixWorld );

			cameraL.matrixWorldInverse.multiply( matrixWorldInverse );
			cameraR.matrixWorldInverse.multiply( matrixWorldInverse );

		}

		// envMap and Mirror needs camera.matrixWorld

		cameraL.matrixWorld.getInverse( cameraL.matrixWorldInverse );
		cameraR.matrixWorld.getInverse( cameraR.matrixWorldInverse );

		cameraL.projectionMatrix.fromArray( frameData.leftProjectionMatrix );
		cameraR.projectionMatrix.fromArray( frameData.rightProjectionMatrix );

		// HACK (mrdoob)
		// https://github.com/w3c/webvr/issues/203

		cameraVR.projectionMatrix.copy( cameraL.projectionMatrix );

		//

		var layers = device.getLayers();

		if ( layers.length ) {

			var layer = layers[ 0 ];

			if ( layer.leftBounds !== null && layer.leftBounds.length === 4 ) {

				cameraL.bounds.fromArray( layer.leftBounds );

			}

			if ( layer.rightBounds !== null && layer.rightBounds.length === 4 ) {

				cameraR.bounds.fromArray( layer.rightBounds );

			}

		}

		return cameraVR;

	};

	this.getStandingMatrix = function () {

		return standingMatrix;

	};

	this.submitFrame = function () {

		if ( device && device.isPresenting ) device.submitFrame();

	};

	this.dispose = function () {

		if ( typeof window !== 'undefined' ) {

			window.removeEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange );

		}

	};

}

export { WebVRManager };
<|endoftext|>


<commit_before>/**
 * @author mrdoob / http://mrdoob.com/
 */

import { Matrix4 } from '../../math/Matrix4.js';
import { Vector4 } from '../../math/Vector4.js';
import { Vector3 } from '../../math/Vector3.js';
import { Quaternion } from '../../math/Quaternion.js';
import { ArrayCamera } from '../../cameras/ArrayCamera.js';
import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js';

function WebXRManager( gl ) {

	var scope = this;

	var device = null;
	var session = null;

	var frameOfRef = null;
	var isExclusive = false;

	var pose = null;

	function isPresenting() {

		return session !== null && frameOfRef !== null;

	}

	//

	var cameraL = new PerspectiveCamera();
	cameraL.layers.enable( 1 );
	cameraL.viewport = new Vector4();

	var cameraR = new PerspectiveCamera();
	cameraR.layers.enable( 2 );
	cameraR.viewport = new Vector4();

	var cameraVR = new ArrayCamera( [ cameraL, cameraR ] );
	cameraVR.layers.enable( 1 );
	cameraVR.layers.enable( 2 );

	//

	this.enabled = false;

	this.getDevice = function () {

		return device;

	};

	this.setDevice = function ( value ) {

		if ( value !== undefined ) device = value;

		gl.setCompatibleXRDevice( value );

	};

	this.setSession = function ( value ) {

		session = value;

		if ( session !== null ) {

			session.baseLayer = new XRWebGLLayer( session, gl );
			session.requestFrameOfReference( 'stage' ).then( function ( value ) {

				frameOfRef = value;
				isExclusive = session.exclusive;

			} );

		}

	};

	this.getCamera = function ( camera ) {

		return isPresenting() ? cameraVR : camera;

	};

	this.isPresenting = isPresenting;

	this.requestAnimationFrame = function ( callback ) {

		function onFrame( time, frame ) {

			pose = frame.getDevicePose( frameOfRef );

			var layer = session.baseLayer;
			var views = frame.views;

			for ( var i = 0; i < views.length; i ++ ) {

				var view = views[ i ];
				var viewport = layer.getViewport( view );
				var viewMatrix = pose.getViewMatrix( view );

				var camera = cameraVR.cameras[ i ];
				camera.projectionMatrix.fromArray( view.projectionMatrix );
				camera.matrixWorldInverse.fromArray( viewMatrix );
				camera.matrixWorld.getInverse( camera.matrixWorldInverse );
				camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height );

				if ( i === 0 ) {

					cameraVR.matrixWorld.copy( camera.matrixWorld );
					cameraVR.matrixWorldInverse.copy( camera.matrixWorldInverse );

					// HACK (mrdoob)
					// https://github.com/w3c/webvr/issues/203

					cameraVR.projectionMatrix.copy( camera.projectionMatrix );

				}

			}

			gl.bindFramebuffer( gl.FRAMEBUFFER, session.baseLayer.framebuffer );

			callback();

		}

		session.requestAnimationFrame( onFrame );

	};

	this.submitFrame = function () {

		// if ( device && device.isPresenting ) device.submitFrame();

	};

}

export { WebXRManager };
<commit_msg>WebXRManager: Added getStandingMatrix().<commit_after>/**
 * @author mrdoob / http://mrdoob.com/
 */

import { Matrix4 } from '../../math/Matrix4.js';
import { Vector4 } from '../../math/Vector4.js';
import { Vector3 } from '../../math/Vector3.js';
import { Quaternion } from '../../math/Quaternion.js';
import { ArrayCamera } from '../../cameras/ArrayCamera.js';
import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js';

function WebXRManager( gl ) {

	var scope = this;

	var device = null;
	var session = null;

	var frameOfRef = null;
	var isExclusive = false;

	var pose = null;

	function isPresenting() {

		return session !== null && frameOfRef !== null;

	}

	//

	var cameraL = new PerspectiveCamera();
	cameraL.layers.enable( 1 );
	cameraL.viewport = new Vector4();

	var cameraR = new PerspectiveCamera();
	cameraR.layers.enable( 2 );
	cameraR.viewport = new Vector4();

	var cameraVR = new ArrayCamera( [ cameraL, cameraR ] );
	cameraVR.layers.enable( 1 );
	cameraVR.layers.enable( 2 );

	//

	this.enabled = false;

	this.getDevice = function () {

		return device;

	};

	this.setDevice = function ( value ) {

		if ( value !== undefined ) device = value;

		gl.setCompatibleXRDevice( value );

	};

	this.setSession = function ( value ) {

		session = value;

		if ( session !== null ) {

			session.baseLayer = new XRWebGLLayer( session, gl );
			session.requestFrameOfReference( 'stage' ).then( function ( value ) {

				frameOfRef = value;
				isExclusive = session.exclusive;

			} );

		}

	};

	this.getCamera = function ( camera ) {

		return isPresenting() ? cameraVR : camera;

	};

	this.isPresenting = isPresenting;

	this.requestAnimationFrame = function ( callback ) {

		function onFrame( time, frame ) {

			pose = frame.getDevicePose( frameOfRef );

			var layer = session.baseLayer;
			var views = frame.views;

			for ( var i = 0; i < views.length; i ++ ) {

				var view = views[ i ];
				var viewport = layer.getViewport( view );
				var viewMatrix = pose.getViewMatrix( view );

				var camera = cameraVR.cameras[ i ];
				camera.projectionMatrix.fromArray( view.projectionMatrix );
				camera.matrixWorldInverse.fromArray( viewMatrix );
				camera.matrixWorld.getInverse( camera.matrixWorldInverse );
				camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height );

				if ( i === 0 ) {

					cameraVR.matrixWorld.copy( camera.matrixWorld );
					cameraVR.matrixWorldInverse.copy( camera.matrixWorldInverse );

					// HACK (mrdoob)
					// https://github.com/w3c/webvr/issues/203

					cameraVR.projectionMatrix.copy( camera.projectionMatrix );

				}

			}

			gl.bindFramebuffer( gl.FRAMEBUFFER, session.baseLayer.framebuffer );

			callback();

		}

		session.requestAnimationFrame( onFrame );

	};

	// DEPRECATED

	this.getStandingMatrix = function () {

		console.warn( 'THREE.WebXRManager: getStandingMatrix() is no longer needed.' );
		return new THREE.Matrix4();

	};

	this.submitFrame = function () {};

}

export { WebXRManager };
<|endoftext|>


<commit_before>// Stores the CSV data
var dataset;

// Dimensions for the svg space
var width = 1400;
var height = 512;

// Radius of the data points
var radius = 2;

d3.csv("tour_de_france.csv", function(error, data) {
    if (error) {
        console.log(error);
    }
    else{
        console.log(data);  //DEBUG: delete this later...
        dataset = data;
        generateSpeedGraph();
    }
});

function generateSpeedGraph(){
    var svg = d3.select("body")
        .append("svg")
        .attr("width", width)
        .attr("height", height);

    var circles = svg.selectAll("circle")
        .data(dataset)
        .enter()
        .append("circle");

    circles.attr("cx", function(d, i) {
        return (i * 12.5) + 25;
    })
        .attr("cy", function(d, i) {
            return height - d.average_speed;
        })
        .attr("r", radius)
        .attr("fill", "blue");
}

<commit_msg>Scaled the height of the points, so they wouldn't be so low. Trying to figure out how to not plot points with a value of "0" speed.<commit_after>// Stores the CSV data
var dataset;

// Dimensions for the svg space
var width = 1400;
var height = 512;

// Radius of the data points
var radius = 3;

d3.csv("tour_de_france.csv", function(error, data) {
    if (error) {
        console.log(error);
    }
    else{
        console.log(data);  //DEBUG: delete this later...
        dataset = data;
        generateSpeedGraph();
    }
});

function generateSpeedGraph(){
    var svg = d3.select("body")
        .append("svg")
        .attr("width", width)
        .attr("height", height);

    var circles = svg.selectAll("circle")
        .data(dataset)
        .enter()
        .append("circle");
        // Only plot points that have data for speed
        if (function(d, i){return d.average_speed;} != "0"){
            circles.attr("cx", function(d, i) {
            return (i * 12.5) + 25;
            })
            .attr("cy", function(d, i) {
                var circleHeight = d.average_speed * 5;
                return height - circleHeight;
            })
            .attr("r", radius);

        }
}

<|endoftext|>


<commit_before>/**
	_moon.Icon_ is a control that displays an icon image. Specify the image by
	setting the _src_ property to a URL indicating the image file's location.

	In Moonstone, icons have a size of 32x32 pixels. Since the icon image is
	applied as a CSS background, the height and width of an icon must be set if an
	image of a different size is used.

		{kind: "moon.Icon", src: "images/search.png"}

	For situations in which an icon should act like a button, use
	moon.IconButton.
*/
enyo.kind({
	name: "moon.Icon",
	published: {
		/**
			Specify the icon name from the following list
			[list of available icons here]
		*/
		icon: "",
		//* URL specifying path to icon image
		src: "",
		//* When true, icon is shown as disabled
		disabled: false,
		/**
			A parameter indicating the size of the button.
			If true, the diameter of this button is 60px.
			However, the button's tap target still has a diameter of 78px, so there is
			invisible DOM that wraps the small button to provide the larger tap zone.
		*/
		small: true
	},
	classes: "moon-icon",
	//* @protected
	create: function() {
		this.inherited(arguments);
		// if (this.src) {
		// 	this.srcChanged();
		// }
		if (this.icon) {
			this.iconChanged();
		}
		this.smallChanged();
		this.disabledChanged();
		// console.log('Icon',this.icon, this.getIconClass());
	},
	getIconClass: function(inIconName) {
		return "moon-icon-" + (inIconName || this.icon);
	},
	disabledChanged: function() {
		this.addRemoveClass("disabled", this.disabled);
	},
	srcChanged: function() {
		this.applyStyle("background-image", "url(" + enyo.path.rewrite(this.src) + ")");
	},
	iconChanged: function(inOld) {
		if (inOld) {
			this.removeClass(this.getIconClass(inOld));
		}
		this.addClass(this.getIconClass());
	},
	smallChanged: function() {
		// console.log('smallChanged',this.small);
		if (this.$.tapArea) {
			this.$.tapArea.destroy();
		}

		if (this.small) {
			// this.addClass("small");
			// this.addClass("moon-small-button-text");
			var ta = this.createComponent({name: "tapArea", classes: "small-icon-tap-area", isChrome: true});
			if (this.generated) {
				ta.render();
			}
			// console.log('tapArea',ta);
		// } else {
		// 	this.removeClass("small");
		// 	this.removeClass("moon-small-button-text");
		}
		// console.log('smallChanged',this.small);
		// this.contentChanged();
		this.addRemoveClass("small", this.small);
	// },
	// smallChanged: function() {
	// 	this.addRemoveClass("small", this.small);
	}
});<commit_msg>Indenting and cleanup. Enyo-DCO-1.1-Signed-off-by: Blake Stephens <blake.stephens@lge.com><commit_after>/**
	_moon.Icon_ is a control that displays an icon image. Specify the image by
	setting the _src_ property to a URL indicating the image file's location.

	In Moonstone, icons have a size of 32x32 pixels. Since the icon image is
	applied as a CSS background, the height and width of an icon must be set if an
	image of a different size is used.

		{kind: "moon.Icon", src: "images/search.png"}

	For situations in which an icon should act like a button, use
	moon.IconButton.
*/
enyo.kind({
	name: "moon.Icon",
	published: {
		/**
			Specify the icon name from the following list
			[list of available icons here]
		*/
		icon: "",
		//* URL specifying path to icon image
		src: "",
		//* When true, icon is shown as disabled
		disabled: false,
		/**
			A parameter indicating the size of the button.
			If true, the diameter of this button is 60px.
			However, the button's tap target still has a diameter of 78px, so there is
			invisible DOM that wraps the small button to provide the larger tap zone.
		*/
		small: true
	},
	classes: "moon-icon",
	//* @protected
	create: function() {
		this.inherited(arguments);
		if (this.src) {
			this.srcChanged();
		}
		if (this.icon) {
			this.iconChanged();
		}
		this.smallChanged();
		this.disabledChanged();
	},
	getIconClass: function(inIconName) {
		return "moon-icon-" + (inIconName || this.icon);
	},
	disabledChanged: function() {
		this.addRemoveClass("disabled", this.disabled);
	},
	srcChanged: function() {
		this.applyStyle("background-image", "url(" + enyo.path.rewrite(this.src) + ")");
	},
	iconChanged: function(inOld) {
		if (inOld) {
			this.removeClass(this.getIconClass(inOld));
		}
		this.addClass(this.getIconClass());
	},
	smallChanged: function() {
		if (this.$.tapArea) {
			this.$.tapArea.destroy();
		}

		if (this.small) {
			var ta = this.createComponent({name: "tapArea", classes: "small-icon-tap-area", isChrome: true});
			if (this.generated) {
				ta.render();
			}
		}
		this.addRemoveClass("small", this.small);
	}
});<|endoftext|>


<commit_before>// Variables

// Steam API
var STEAM_API_KEY = "";
var STEAM_ID64 = "";

// Headers
var IS_THERE_ANY_DEAL_HEADER = "isthereanydeal URL";
var TIMESTAMP_HEADER = "Added";
var ON_UPDATE_HEADER = "Name";
var OWN_STATUS_HEADER = "Own Status";
var STEAM_URL_HEADER = "Steam URL";
var CARDS_HEADER = "Cards";

// Texts
var MISSING_TEXT = "Missing";
var OWN_TEXT = "Own";

// Colors
var BUNDLED_BACKGROUND_COLOR = '#f6b26b';
var NON_BUNDLED_BACKGROUND_COLOR = '#66ccff';

var SHEET_NAME = 'Keys';

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

var ss, title, headers, changedCell;

function onEdit(event)
{
  ss = event.source.getSheetByName(SHEET_NAME);
  title = _encodeName(event.value);
  headers = ss.getRange(1, 1, 1, ss.getLastColumn()).getValues();
  changedCell= event.source.getActiveRange().getA1Notation();

  if(title == "" || title == undefined || changedCell.indexOf('A') === -1){
    return;
  }

  addDateStamp(event);
  handleBundled(event);
}

// Checks if the game got cards and adds the result---------------------------------------------
function checkIfGotCards(event, appId){
  var url = "http://steamcommunity.com/profiles/" + STEAM_ID64 + "/gamecards/" + appId;
  var url = "http://api.enhancedsteam.com/market_data/card_prices/?appid=" + appId;

  var options = {
    "followRedirects": true,
    "muteHttpExceptions":false
  }

  var response = UrlFetchApp.fetch(url,options);
  var text = response.getContentText();

  var urlCol = headers[0].indexOf(CARDS_HEADER);
  var cell = ss.getRange(event.source.getActiveRange().getRow(), urlCol + 1);

  if (text.length > 0){
    var link = "http://www.steamcardexchange.net/index.php?gamepage-appid-" + appId;
    var displayName = "Have";
    cell.setFormula("=hyperlink(\""+link+"\";\"" + displayName + "\")");
  }
  else{
    cell.setValue("Missing");
  }
}

// Adds an Steam url----------------------------------------------------------------------------
function addSteamUrl(event, appId){
  var url = "http://store.steampowered.com/app/" + appId + "/";
  var urlCol = headers[0].indexOf(STEAM_URL_HEADER);

  var urlToUpdate = ss.getRange(event.source.getActiveRange().getRow(), urlCol + 1);
  urlToUpdate.setValue(url);
}

// Adds an isThereAnyDeal url---------------------------------------------------------------------
function addIsThereAnyDealUrl(event){
  var isthereanydealUrl = "https://isthereanydeal.com/#/page:game/info?plain=" + title;
  var urlCol = headers[0].indexOf(IS_THERE_ANY_DEAL_HEADER);

  var urlToUpdate = ss.getRange(event.source.getActiveRange().getRow(), urlCol + 1);
  urlToUpdate.setValue(isthereanydealUrl);
}

// Checks to see if you own the game or not, needs STEAM_API_KEY and STEAM_ID64--------------------
function getSteamOwnStatusAndSetIt(text, event){
  var myRegexp = /([steampowered.com]*)(\d+)/g;
  var match = myRegexp.exec(text);
  var appID = match[0];

  addSteamUrl(event, appID);
  checkIfGotCards(event, appID);

  var data = {
    "steamid":STEAM_ID64,
    "appids_filter": [parseInt(appID)]
  };

  var payload = "&input_json=" + encodeURIComponent(JSON.stringify(data));
  var url = "https://api.steampowered.com/IPlayerService/GetOwnedGames/v1/?key=" + STEAM_API_KEY + payload;
  var response = UrlFetchApp.fetch(url);
  var text = response.getContentText();

  var urlCol = headers[0].indexOf(OWN_STATUS_HEADER);
  var ownStatusToUpdate = ss.getRange(event.source.getActiveRange().getRow(), urlCol + 1);

  if (text.indexOf(appID) !== -1){
    ownStatusToUpdate.setValue(OWN_TEXT);
  }
  else{
    ownStatusToUpdate.setValue(MISSING_TEXT);
  }
}

// Checks if the game have been bundled before and sets the right color--------------------------------
function handleBundled(event){
  addIsThereAnyDealUrl(event);

  var url = 'https://isthereanydeal.com/ajax/game/info?plain=' + title;
  var response = UrlFetchApp.fetch(url);
  var text = response.getContentText();

  getSteamOwnStatusAndSetIt(text, event);

  if (text.indexOf("This game has been included in following Specials") !== -1){
    ss.getRange(changedCell).setBackgroundColor(BUNDLED_BACKGROUND_COLOR);
  }
  else{
    ss.getRange(changedCell).setBackgroundColor(NON_BUNDLED_BACKGROUND_COLOR);
  }
}

// Adds a timestamp when editing-----------------------------------------------------------------------
function addDateStamp(event)
{
  var timezone = "GMT-5";
  var timestamp_format = "MM-dd-yyyy"; // Timestamp Format.
  var updateColName = ON_UPDATE_HEADER;
  var timeStampColName = TIMESTAMP_HEADER;

  var actRng = event.source.getActiveRange();
  var editColumn = actRng.getColumn();
  var index = actRng.getRowIndex();
  var headers = ss.getRange(1, 1, 1, ss.getLastColumn()).getValues();
  var dateCol = headers[0].indexOf(timeStampColName);
  var updateCol = headers[0].indexOf(updateColName); updateCol = updateCol+1;
  if (dateCol > -1 && index > 1 && editColumn == updateCol) { // only timestamp if 'Last Updated' header exists, but not in the header row itself!
    var cell = ss.getRange(index, dateCol + 1);
    var date = Utilities.formatDate(new Date(), timezone, timestamp_format);
    cell.setValue(date);
  }
}

// Misc Methods------------------------------------------------------------------------------------------
function _romanize (num) {
  var key = ["","i","ii","iii","iv","v","vi","vii","viii","ix"];
  return key[Number(num)];
}

function _encodeName(str){
  str = str.toLowerCase(); //lowercase
  str = str.replace(/[1-9]/g, _romanize);//_romanize digits
  str = str.replace(/(^the[^a-z])|([^a-z]the[^a-z])|([^a-z]the$)/g, ""); //remove "the", but not e.g. "other" or "them"
  str = str.replace(/\+/g, "plus");    //spell out "plus"
  str = str.replace(/\&/g, "and");    //spell out "and"
  str = str.replace(/[^a-z0]/g, '');    //remove remaining invalid characters, like spaces, braces, hyphens etc
  return str;
}
<commit_msg>Update GoogleAppsScript.js<commit_after>// Variables

// Steam API
var STEAM_API_KEY = "";
var STEAM_ID64 = "";

// Headers
var IS_THERE_ANY_DEAL_HEADER = "isthereanydeal URL";
var TIMESTAMP_HEADER = "Added";
var ON_UPDATE_HEADER = "Name";
var OWN_STATUS_HEADER = "Own Status";
var STEAM_URL_HEADER = "Steam URL";
var CARDS_HEADER = "Cards";

// Texts
var MISSING_TEXT = "Missing";
var OWN_TEXT = "Own";

// Colors
var BUNDLED_BACKGROUND_COLOR = '#f6b26b';
var NON_BUNDLED_BACKGROUND_COLOR = '#66ccff';

var SHEET_NAME = 'Keys';

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

var ss, title, headers, changedCell;

function onEdit(event)
{
  ss = event.source.getSheetByName(SHEET_NAME);
  title = _encodeName(event.value);
  headers = ss.getRange(1, 1, 1, ss.getLastColumn()).getValues();
  changedCell= event.source.getActiveRange().getA1Notation();

  if(title == "" || title == undefined || changedCell.indexOf('A') === -1){
    return;
  }

  addDateStamp(event);
  handleBundled(event);
}

// Checks if the game got cards and adds the result---------------------------------------------
function checkIfGotCards(event, appId){
  var url = "http://api.enhancedsteam.com/market_data/card_prices/?appid=" + appId;

  var options = {
    "followRedirects": true,
    "muteHttpExceptions":false
  }

  var response = UrlFetchApp.fetch(url,options);
  var text = response.getContentText();

  var urlCol = headers[0].indexOf(CARDS_HEADER);
  var cell = ss.getRange(event.source.getActiveRange().getRow(), urlCol + 1);

  if (text.length > 0){
    var link = "http://www.steamcardexchange.net/index.php?gamepage-appid-" + appId;
    var displayName = "Have";
    cell.setFormula("=hyperlink(\""+link+"\";\"" + displayName + "\")");
  }
  else{
    cell.setValue("Missing");
  }
}

// Adds an Steam url----------------------------------------------------------------------------
function addSteamUrl(event, appId){
  var url = "http://store.steampowered.com/app/" + appId + "/";
  var urlCol = headers[0].indexOf(STEAM_URL_HEADER);

  var urlToUpdate = ss.getRange(event.source.getActiveRange().getRow(), urlCol + 1);
  urlToUpdate.setValue(url);
}

// Adds an isThereAnyDeal url---------------------------------------------------------------------
function addIsThereAnyDealUrl(event){
  var isthereanydealUrl = "https://isthereanydeal.com/#/page:game/info?plain=" + title;
  var urlCol = headers[0].indexOf(IS_THERE_ANY_DEAL_HEADER);

  var urlToUpdate = ss.getRange(event.source.getActiveRange().getRow(), urlCol + 1);
  urlToUpdate.setValue(isthereanydealUrl);
}

// Checks to see if you own the game or not, needs STEAM_API_KEY and STEAM_ID64--------------------
function getSteamOwnStatusAndSetIt(text, event){
  var myRegexp = /[steampowered.com/app/](\d+)[/]/g;
  var match = myRegexp.exec(text);
  var appID = match[1];

  addSteamUrl(event, appID);
  checkIfGotCards(event, appID);

  var data = {
    "steamid":STEAM_ID64,
    "appids_filter": [parseInt(appID)]
  };

  var payload = "&input_json=" + encodeURIComponent(JSON.stringify(data));
  var url = "https://api.steampowered.com/IPlayerService/GetOwnedGames/v1/?key=" + STEAM_API_KEY + payload;
  var response = UrlFetchApp.fetch(url);
  var text = response.getContentText();

  var urlCol = headers[0].indexOf(OWN_STATUS_HEADER);
  var ownStatusToUpdate = ss.getRange(event.source.getActiveRange().getRow(), urlCol + 1);

  if (text.indexOf(appID) !== -1){
    ownStatusToUpdate.setValue(OWN_TEXT);
  }
  else{
    ownStatusToUpdate.setValue(MISSING_TEXT);
  }
}

// Checks if the game have been bundled before and sets the right color--------------------------------
function handleBundled(event){
  addIsThereAnyDealUrl(event);

  var url = 'https://isthereanydeal.com/ajax/game/info?plain=' + title;
  var response = UrlFetchApp.fetch(url);
  var text = response.getContentText();

  getSteamOwnStatusAndSetIt(text, event);

  if (text.indexOf("This game has been included in following Specials") !== -1){
    ss.getRange(changedCell).setBackgroundColor(BUNDLED_BACKGROUND_COLOR);
  }
  else{
    ss.getRange(changedCell).setBackgroundColor(NON_BUNDLED_BACKGROUND_COLOR);
  }
}

// Adds a timestamp when editing-----------------------------------------------------------------------
function addDateStamp(event)
{
  var timezone = "GMT-5";
  var timestamp_format = "MM-dd-yyyy"; // Timestamp Format.
  var updateColName = ON_UPDATE_HEADER;
  var timeStampColName = TIMESTAMP_HEADER;

  var actRng = event.source.getActiveRange();
  var editColumn = actRng.getColumn();
  var index = actRng.getRowIndex();
  var headers = ss.getRange(1, 1, 1, ss.getLastColumn()).getValues();
  var dateCol = headers[0].indexOf(timeStampColName);
  var updateCol = headers[0].indexOf(updateColName); updateCol = updateCol+1;
  if (dateCol > -1 && index > 1 && editColumn == updateCol) { // only timestamp if 'Last Updated' header exists, but not in the header row itself!
    var cell = ss.getRange(index, dateCol + 1);
    var date = Utilities.formatDate(new Date(), timezone, timestamp_format);
    cell.setValue(date);
  }
}

// Misc Methods------------------------------------------------------------------------------------------
function _romanize (num) {
  var key = ["","i","ii","iii","iv","v","vi","vii","viii","ix"];
  return key[Number(num)];
}

function _encodeName(str){
  str = str.toLowerCase(); //lowercase
  str = str.replace(/[1-9]/g, _romanize);//_romanize digits
  str = str.replace(/(^the[^a-z])|([^a-z]the[^a-z])|([^a-z]the$)/g, ""); //remove "the", but not e.g. "other" or "them"
  str = str.replace(/\+/g, "plus");    //spell out "plus"
  str = str.replace(/\&/g, "and");    //spell out "and"
  str = str.replace(/[^a-z0]/g, '');    //remove remaining invalid characters, like spaces, braces, hyphens etc
  return str;
}
<|endoftext|>


<commit_before>/*jslint nomen:true */
/*global _, async, console, Image, document, module, define, require, window, process */

(function () {
    'use strict';

    var Canvas, CanvasRenderer, Layer, img;

    function passThrough(canvas, callback) {
        callback(null, canvas);
    }

    Layer = function (img) {
        this.img = img;
        this.filter = null;
    };

    Layer.prototype.setFilter = function (filter) {
        this.filter = filter;
    };

    Canvas = function () {
        this.layers = [];
    };

    Canvas.prototype.addLayer = function (filename) {
        var layer = new Layer(filename);
        this.layers.push(layer);
        return layer;
    };

    Canvas.prototype.render = function (callback) {
        CanvasRenderer.render(this, callback);
    };

    CanvasRenderer = {};

    CanvasRenderer.load = function (layer) {
        var src = layer.img;
        return function (_, callback) {
            var source = new Image(),
                canvas = document.createElement('canvas'),
                ctx = canvas.getContext('2d');

            source.onload = function () {
                canvas.width = source.width;
                canvas.height = source.height;
                ctx.drawImage(source, 0, 0, canvas.width, canvas.height);
                callback(null, canvas);
            };
            source.src = src;
        };
    };

    CanvasRenderer._processNoWorker = function (layer) {
        var filter = layer.filter;
        if (filter === null) { return passThrough; }

        return function (canvas, callback) {
            var ctx = canvas.getContext('2d'),
                width = canvas.width,
                height = canvas.height,
                canvasInData = ctx.getImageData(0, 0, width, height),
                canvasOutData = ctx.createImageData(width, height);

            process[filter.name](canvasInData.data, canvasOutData.data, width, height, filter.options);
            ctx.putImageData(canvasOutData, 0, 0);
            callback(null, canvas);
        };
    };

    CanvasRenderer._processWithWorker = function (layer) {
        var filter = layer.filter;
        if (filter === null) { return passThrough; }

        return function (canvas, callback) {
            var ctx = canvas.getContext('2d'),
                width = canvas.width,
                height = canvas.height,
                canvasInData = ctx.getImageData(0, 0, width, height),
                canvasOutData = ctx.createImageData(width, height),
                worker = new window.Worker('img.worker.control.js');

            worker.onmessage = function (e) {
                canvasOutData = e.data.result;
                ctx.putImageData(canvasOutData, 0, 0);
                callback(null, canvas);
            };

            worker.postMessage({ inData: canvasInData,
                                 outData: canvasOutData,
                                 width: width,
                                 height: height,
                                 filter: filter });
        };
    };

    if (!window.Worker) {
        CanvasRenderer.processImage = CanvasRenderer._processNoWorker;
    } else {
        CanvasRenderer.processImage = CanvasRenderer._processWithWorker;
    }

    CanvasRenderer.processLayer = function (layer, callback) {
        async.compose(
            CanvasRenderer.processImage(layer),
            CanvasRenderer.load(layer)
        )(null, callback);
    };

    CanvasRenderer.render = function (canvas, callback) {
        async.map(canvas.layers,
              CanvasRenderer.processLayer, function (err, result) {
                if (callback) {
                    callback(result);
                }
            });
    };

    img = {};
    img.Layer = Layer;
    img.Canvas = Canvas;

    // MODULE SUPPORT ///////////////////////////////////////////////////////

    if (typeof module !== 'undefined') {
        module.exports = img;
    } else if (typeof define !== 'undefined') {
        define('img', ['underscore'], function () {
            return img;
        });
    } else {
        window.img = img;
    }

}());
<commit_msg>Added createImageData function.<commit_after>/*jslint nomen:true */
/*global _, async, console, Image, document, module, define, require, window, process */

(function () {
    'use strict';

    var Canvas, CanvasRenderer, Layer, img;

    function passThrough(canvas, callback) {
        callback(null, canvas);
    }

    function createImageData(ctx, width, height) {
        if (ctx.createImageData) {
            return ctx.createImageData(width, height);
        } else {
            return ctx.getImageData(0, 0, width, height);
        }
    }

    Layer = function (img) {
        this.img = img;
        this.filter = null;
    };

    Layer.prototype.setFilter = function (filter) {
        this.filter = filter;
    };

    Canvas = function () {
        this.layers = [];
    };

    Canvas.prototype.addLayer = function (filename) {
        var layer = new Layer(filename);
        this.layers.push(layer);
        return layer;
    };

    Canvas.prototype.render = function (callback) {
        CanvasRenderer.render(this, callback);
    };

    CanvasRenderer = {};

    CanvasRenderer.load = function (layer) {
        var src = layer.img;
        return function (_, callback) {
            var source = new Image(),
                canvas = document.createElement('canvas'),
                ctx = canvas.getContext('2d');

            source.onload = function () {
                canvas.width = source.width;
                canvas.height = source.height;
                ctx.drawImage(source, 0, 0, canvas.width, canvas.height);
                callback(null, canvas);
            };
            source.src = src;
        };
    };

    CanvasRenderer._processNoWorker = function (layer) {
        var filter = layer.filter;
        if (filter === null) { return passThrough; }

        return function (canvas, callback) {
            var ctx = canvas.getContext('2d'),
                width = canvas.width,
                height = canvas.height,
                canvasInData = ctx.getImageData(0, 0, width, height),
                canvasOutData = createImageData(ctx, width, height);

            process[filter.name](canvasInData.data, canvasOutData.data, width, height, filter.options);
            ctx.putImageData(canvasOutData, 0, 0);
            callback(null, canvas);
        };
    };

    CanvasRenderer._processWithWorker = function (layer) {
        var filter = layer.filter;
        if (filter === null) { return passThrough; }

        return function (canvas, callback) {
            var ctx = canvas.getContext('2d'),
                width = canvas.width,
                height = canvas.height,
                canvasInData = ctx.getImageData(0, 0, width, height),
                canvasOutData = createImageData(ctx, width, height),
                worker = new window.Worker('img.worker.control.js');

            worker.onmessage = function (e) {
                canvasOutData = e.data.result;
                ctx.putImageData(canvasOutData, 0, 0);
                callback(null, canvas);
            };

            worker.postMessage({ inData: canvasInData,
                                 outData: canvasOutData,
                                 width: width,
                                 height: height,
                                 filter: filter });
        };
    };

    if (!window.Worker) {
        CanvasRenderer.processImage = CanvasRenderer._processNoWorker;
    } else {
        CanvasRenderer.processImage = CanvasRenderer._processWithWorker;
    }

    CanvasRenderer.processLayer = function (layer, callback) {
        async.compose(
            CanvasRenderer.processImage(layer),
            CanvasRenderer.load(layer)
        )(null, callback);
    };

    CanvasRenderer.render = function (canvas, callback) {
        async.map(canvas.layers,
              CanvasRenderer.processLayer, function (err, result) {
                if (callback) {
                    callback(result);
                }
            });
    };

    img = {};
    img.Layer = Layer;
    img.Canvas = Canvas;

    // MODULE SUPPORT ///////////////////////////////////////////////////////

    if (typeof module !== 'undefined') {
        module.exports = img;
    } else if (typeof define !== 'undefined') {
        define('img', ['underscore'], function () {
            return img;
        });
    } else {
        window.img = img;
    }

}());
<|endoftext|>