<commit_before>//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
//>>description: Behavior for "fixed" headers and footers - be sure to also include the item 'Browser specific workarounds for "fixed" headers and footers' when supporting Android 2.x or iOS 5
//>>label: Toolbars: Fixed
//>>group: Widgets
//>>css.structure: ../css/structure/jquery.mobile.fixedToolbar.css
//>>css.theme: ../css/themes/default/jquery.mobile.theme.css

define( [ "jquery", "../jquery.mobile.widget", "../jquery.mobile.core", "../jquery.mobile.navigation", "./page", "../jquery.mobile.zoom" ], function( jQuery ) {
//>>excludeEnd("jqmBuildExclude");
(function( $, undefined ) {

	$.widget( "mobile.toolbar", $.mobile.widget, {
		options: {
			theme: "a",
			addBackBtn: false,
			backBtnTheme: null,
			backBtnText: "Back"
		},

		_create: function() {
			var leftbtn, rightbtn, backBtn,
				role =  this.element.is( ":jqmData(role='header')" ) ? "header" : "footer",
				page = this.element.closest(".ui-page");
			if( page.length === 0 ){
				page = false;
				this._on($.mobile.document, {
					"pageshow":"refresh"

				});
			}
			$.extend( this, {
				role:role,
				page:page,
				leftbtn: leftbtn,
				rightbtn: rightbtn,
				backBtn: backBtn
			});
			this.element.attr( "role", role === "header" ? "banner" : "contentinfo" ).addClass("ui-"+role);
			this.refresh();
			this._setOptions( this.options );
		},
		_setOptions:function( o ){
			if( o.addBackBtn !== undefined){
				if( this.options.addBackBtn &&
					this.role === "header" &&
					$( ".ui-page" ).length > 1 &&
					this.page[ 0 ].getAttribute( "data-" + $.mobile.ns + "url" ) !== $.mobile.path.stripHash( location.hash ) &&
					!this.leftbtn){
						this._addBackButton();
				} else {
					this.element.find(".ui-toolbar-back-btn").remove();
				}
			}
			if( o.backBtnTheme !== undefined){
				this.element.find(".ui-toolbar-back-btn").attr( "data-"+ $.mobile.ns +"theme", o.theme).buttonMarkup();
			}
			if( o.backBtnText !== undefined){
				this.element.find(".ui-toolbar-back-btn .ui-btn-text").text( o.backBtnText );
			}
			if( o.theme !== undefined ){
				this.element.removeClass("ui-bar-" + this.options.theme ).addClass( "ui-bar-" + o.theme );
			}
			this._superApply( o );

		},
		refresh: function(){
			if( this.role === "header") {
				this._addHeaderButtonClasses();
			}
			if( !this.page ){
				$("[data-role='page']").css({"position":"relative"});
				if( this.role === "footer" ){
					this.element.appendTo("body");
				}
			}
			this._addHeadingClasses();
			this._btnMarkup();
		},
		_btnMarkup: function(){
			this.element.children("a").buttonMarkup({ theme:this.options.theme});
		},
		_addHeaderButtonClasses:function(){
			var $headeranchors	= this.element.children( "a, button" );
			this.leftbtn	= $headeranchors.hasClass( "ui-btn-left" );
			this.rightbtn = $headeranchors.hasClass( "ui-btn-right" );

			this.leftbtn = this.leftbtn || $headeranchors.eq( 0 ).not( ".ui-btn-right" ).addClass( "ui-btn-left" ).length;

			this.rightbtn = this.rightbtn || $headeranchors.eq( 1 ).addClass( "ui-btn-right" ).length;

		},
		_addBackButton:function(){
			this.backBtn = $( ""+ this.options.backBtnText +"" )
					// If theme is provided, override default inheritance
					.attr( "data-"+ $.mobile.ns +"theme", this.options.backBtnTheme || this.options.theme )
					.prependTo( this.element );
		},
		_addHeadingClasses:function(){
			this.element.children( "h1, h2, h3, h4, h5, h6" )
				.addClass( "ui-title" )
				// Regardless of h element number in src, it becomes h1 for the enhanced page
				.attr({
					"role": "heading",
					"aria-level": "1"
				});
		}
	});
	$.mobile.toolbar.initSelector = ":jqmData(role='footer'), :jqmData(role='header')";

	$.mobile._enhancer.add( "mobile.toolbar");

})( jQuery );
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
});
//>>excludeEnd("jqmBuildExclude");
<commit_msg>Toolbar: chain up in _setOptions() with this._super( o ) instead of this._superApply( o ).<commit_after>//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
//>>description: Behavior for "fixed" headers and footers - be sure to also include the item 'Browser specific workarounds for "fixed" headers and footers' when supporting Android 2.x or iOS 5
//>>label: Toolbars: Fixed
//>>group: Widgets
//>>css.structure: ../css/structure/jquery.mobile.fixedToolbar.css
//>>css.theme: ../css/themes/default/jquery.mobile.theme.css

define( [ "jquery", "../jquery.mobile.widget", "../jquery.mobile.core", "../jquery.mobile.navigation", "./page", "../jquery.mobile.zoom" ], function( jQuery ) {
//>>excludeEnd("jqmBuildExclude");
(function( $, undefined ) {

	$.widget( "mobile.toolbar", $.mobile.widget, {
		options: {
			theme: "a",
			addBackBtn: false,
			backBtnTheme: null,
			backBtnText: "Back"
		},

		_create: function() {
			var leftbtn, rightbtn, backBtn,
				role =  this.element.is( ":jqmData(role='header')" ) ? "header" : "footer",
				page = this.element.closest(".ui-page");
			if( page.length === 0 ){
				page = false;
				this._on($.mobile.document, {
					"pageshow":"refresh"

				});
			}
			$.extend( this, {
				role:role,
				page:page,
				leftbtn: leftbtn,
				rightbtn: rightbtn,
				backBtn: backBtn
			});
			this.element.attr( "role", role === "header" ? "banner" : "contentinfo" ).addClass("ui-"+role);
			this.refresh();
			this._setOptions( this.options );
		},
		_setOptions:function( o ){
			if( o.addBackBtn !== undefined){
				if( this.options.addBackBtn &&
					this.role === "header" &&
					$( ".ui-page" ).length > 1 &&
					this.page[ 0 ].getAttribute( "data-" + $.mobile.ns + "url" ) !== $.mobile.path.stripHash( location.hash ) &&
					!this.leftbtn){
						this._addBackButton();
				} else {
					this.element.find(".ui-toolbar-back-btn").remove();
				}
			}
			if( o.backBtnTheme !== undefined){
				this.element.find(".ui-toolbar-back-btn").attr( "data-"+ $.mobile.ns +"theme", o.theme).buttonMarkup();
			}
			if( o.backBtnText !== undefined){
				this.element.find(".ui-toolbar-back-btn .ui-btn-text").text( o.backBtnText );
			}
			if( o.theme !== undefined ){
				this.element.removeClass("ui-bar-" + this.options.theme ).addClass( "ui-bar-" + o.theme );
			}
			this._super( o );

		},
		refresh: function(){
			if( this.role === "header") {
				this._addHeaderButtonClasses();
			}
			if( !this.page ){
				$("[data-role='page']").css({"position":"relative"});
				if( this.role === "footer" ){
					this.element.appendTo("body");
				}
			}
			this._addHeadingClasses();
			this._btnMarkup();
		},
		_btnMarkup: function(){
			this.element.children("a").buttonMarkup({ theme:this.options.theme});
		},
		_addHeaderButtonClasses:function(){
			var $headeranchors	= this.element.children( "a, button" );
			this.leftbtn	= $headeranchors.hasClass( "ui-btn-left" );
			this.rightbtn = $headeranchors.hasClass( "ui-btn-right" );

			this.leftbtn = this.leftbtn || $headeranchors.eq( 0 ).not( ".ui-btn-right" ).addClass( "ui-btn-left" ).length;

			this.rightbtn = this.rightbtn || $headeranchors.eq( 1 ).addClass( "ui-btn-right" ).length;

		},
		_addBackButton:function(){
			this.backBtn = $( ""+ this.options.backBtnText +"" )
					// If theme is provided, override default inheritance
					.attr( "data-"+ $.mobile.ns +"theme", this.options.backBtnTheme || this.options.theme )
					.prependTo( this.element );
		},
		_addHeadingClasses:function(){
			this.element.children( "h1, h2, h3, h4, h5, h6" )
				.addClass( "ui-title" )
				// Regardless of h element number in src, it becomes h1 for the enhanced page
				.attr({
					"role": "heading",
					"aria-level": "1"
				});
		}
	});
	$.mobile.toolbar.initSelector = ":jqmData(role='footer'), :jqmData(role='header')";

	$.mobile._enhancer.add( "mobile.toolbar");

})( jQuery );
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
});
//>>excludeEnd("jqmBuildExclude");
<|endoftext|>


<commit_before>(function () {
    'use strict';

    function MiniListViewDirective(contentResource, memberResource, mediaResource) {

        function link(scope, el, attr, ctrl) {

            scope.search = "";
            scope.miniListViews = [];
            scope.breadcrumb = [];

            var miniListViewsHistory = [];
            var goingForward = true;
            var skipAnimation = true;

            function onInit() {
                open(scope.node);
            }

            function open(node) {

                goingForward = true;

                var miniListView = {
                    node: node,
                    loading: true,
                    pagination: {
                        pageSize: 10,
                        pageNumber: 1,
                        filter: '',
                        orderDirection: "Ascending",
                        orderBy: "SortOrder",
                        orderBySystemField: true
                    }
                };

                // clear and push mini list view in dom so we only render 1 view
                scope.miniListViews = [];
                scope.miniListViews.push(miniListView);

                // store in history so we quickly can navigate back
                miniListViewsHistory.push(miniListView);

                // get children
                getChildrenForMiniListView(miniListView);

                makeBreadcrumb();

            }

            function getChildrenForMiniListView(miniListView) {

                // start loading animation list view
                miniListView.loading = true;

                // setup the correct resource depending on section
                var resource = "";

                if (scope.entityType === "Member") {
                    resource = memberResource.getPagedResults;
                } else if (scope.entityType === "Media") {
                    resource = mediaResource.getChildren;
                } else {
                    resource = contentResource.getChildren;
                }

                resource(miniListView.node.id, miniListView.pagination)
                    .then(function (data) {
                        // update children
                        miniListView.children = data.items;
                        // update pagination
                        miniListView.pagination.totalItems = data.totalItems;
                        miniListView.pagination.totalPages = data.totalPages;
                        // stop load indicator
                        miniListView.loading = false;
                    });
            }

            scope.openNode = function(event, node) {
			    open(node);
                event.stopPropagation();
            };

            scope.selectNode = function(node) {
                if(scope.onSelect) {
                    scope.onSelect({'node': node});
                }
            };

            /* Pagination */
            scope.goToPage = function(pageNumber, miniListView) {
                // set new page number
                miniListView.pagination.pageNumber = pageNumber;
                // get children
                getChildrenForMiniListView(miniListView);
            };

            /* Breadcrumb */
            scope.clickBreadcrumb = function(ancestor) {

                var found = false;
                goingForward = false;

                angular.forEach(miniListViewsHistory, function(historyItem, index){
                    // We need to make sure we can compare the two id's.
                    // Some id's are integers and others are strings.
                    // Members have string ids like "all-members".
                    if(historyItem.node.id.toString() === ancestor.id.toString()) {
                        // load the list view from history
                        scope.miniListViews = [];
                        scope.miniListViews.push(historyItem);
                        // clean up history - remove all children after
                        miniListViewsHistory.splice(index + 1, miniListViewsHistory.length);
                        found = true;
                    }
                });

                if(!found) {
                    // if we can't find the view in the history - close the list view
                    scope.exitMiniListView();
                }

                // update the breadcrumb
                makeBreadcrumb();

            };

            scope.showBackButton = function() {
                // don't show the back button if the start node is a list view
                if(scope.node.metaData && scope.node.metaData.IsContainer || scope.node.isContainer) {
                    return false;
                } else {
                    return true;
                }
            };

            scope.exitMiniListView = function() {
                miniListViewsHistory = [];
                scope.miniListViews = [];
                if(scope.onClose) {
                    scope.onClose();
                }
            };

            function makeBreadcrumb() {
                scope.breadcrumb = [];
                angular.forEach(miniListViewsHistory, function(historyItem){
                    scope.breadcrumb.push(historyItem.node);
                });
            }

            /* Search */
            scope.searchMiniListView = function(search, miniListView) {
                // set search value
                miniListView.pagination.filter = search;
                // start loading animation list view
                miniListView.loading = true;
                searchMiniListView(miniListView);
            };

            var searchMiniListView = _.debounce(function (miniListView) {
                scope.$apply(function () {
                    getChildrenForMiniListView(miniListView);
                });
            }, 500);

            /* Animation */
            scope.getMiniListViewAnimation = function() {

                // disable the first "slide-in-animation"" if the start node is a list view
                if(scope.node.metaData && scope.node.metaData.IsContainer && skipAnimation || scope.node.isContainer && skipAnimation) {
                    skipAnimation = false;
                    return;
                }

                if(goingForward) {
                    return 'umb-mini-list-view--forward';
                } else {
                    return 'umb-mini-list-view--backwards';
                }
            };

            onInit();

        }

        var directive = {
            restrict: 'E',
            replace: true,
            templateUrl: 'views/components/umb-mini-list-view.html',
            scope: {
                node: "=",
                entityType: "@",
                startNodeId: "=",
                onSelect: "&",
                onClose: "&"
            },
            link: link
        };

        return directive;

    }

    angular.module('umbraco.directives').directive('umbMiniListView', MiniListViewDirective);

})();
<commit_msg>reset pagination when searching<commit_after>(function () {
    'use strict';

    function MiniListViewDirective(contentResource, memberResource, mediaResource) {

        function link(scope, el, attr, ctrl) {

            scope.search = "";
            scope.miniListViews = [];
            scope.breadcrumb = [];

            var miniListViewsHistory = [];
            var goingForward = true;
            var skipAnimation = true;

            function onInit() {
                open(scope.node);
            }

            function open(node) {

                goingForward = true;

                var miniListView = {
                    node: node,
                    loading: true,
                    pagination: {
                        pageSize: 10,
                        pageNumber: 1,
                        filter: '',
                        orderDirection: "Ascending",
                        orderBy: "SortOrder",
                        orderBySystemField: true
                    }
                };

                // clear and push mini list view in dom so we only render 1 view
                scope.miniListViews = [];
                scope.miniListViews.push(miniListView);

                // store in history so we quickly can navigate back
                miniListViewsHistory.push(miniListView);

                // get children
                getChildrenForMiniListView(miniListView);

                makeBreadcrumb();

            }

            function getChildrenForMiniListView(miniListView) {

                // start loading animation list view
                miniListView.loading = true;

                // setup the correct resource depending on section
                var resource = "";

                if (scope.entityType === "Member") {
                    resource = memberResource.getPagedResults;
                } else if (scope.entityType === "Media") {
                    resource = mediaResource.getChildren;
                } else {
                    resource = contentResource.getChildren;
                }

                resource(miniListView.node.id, miniListView.pagination)
                    .then(function (data) {
                        // update children
                        miniListView.children = data.items;
                        // update pagination
                        miniListView.pagination.totalItems = data.totalItems;
                        miniListView.pagination.totalPages = data.totalPages;
                        // stop load indicator
                        miniListView.loading = false;
                    });
            }

            scope.openNode = function(event, node) {
			    open(node);
                event.stopPropagation();
            };

            scope.selectNode = function(node) {
                if(scope.onSelect) {
                    scope.onSelect({'node': node});
                }
            };

            /* Pagination */
            scope.goToPage = function(pageNumber, miniListView) {
                // set new page number
                miniListView.pagination.pageNumber = pageNumber;
                // get children
                getChildrenForMiniListView(miniListView);
            };

            /* Breadcrumb */
            scope.clickBreadcrumb = function(ancestor) {

                var found = false;
                goingForward = false;

                angular.forEach(miniListViewsHistory, function(historyItem, index){
                    // We need to make sure we can compare the two id's.
                    // Some id's are integers and others are strings.
                    // Members have string ids like "all-members".
                    if(historyItem.node.id.toString() === ancestor.id.toString()) {
                        // load the list view from history
                        scope.miniListViews = [];
                        scope.miniListViews.push(historyItem);
                        // clean up history - remove all children after
                        miniListViewsHistory.splice(index + 1, miniListViewsHistory.length);
                        found = true;
                    }
                });

                if(!found) {
                    // if we can't find the view in the history - close the list view
                    scope.exitMiniListView();
                }

                // update the breadcrumb
                makeBreadcrumb();

            };

            scope.showBackButton = function() {
                // don't show the back button if the start node is a list view
                if(scope.node.metaData && scope.node.metaData.IsContainer || scope.node.isContainer) {
                    return false;
                } else {
                    return true;
                }
            };

            scope.exitMiniListView = function() {
                miniListViewsHistory = [];
                scope.miniListViews = [];
                if(scope.onClose) {
                    scope.onClose();
                }
            };

            function makeBreadcrumb() {
                scope.breadcrumb = [];
                angular.forEach(miniListViewsHistory, function(historyItem){
                    scope.breadcrumb.push(historyItem.node);
                });
            }

            /* Search */
            scope.searchMiniListView = function(search, miniListView) {
                // set search value
                miniListView.pagination.filter = search;
                // reset pagination
                miniListView.pagination.pageNumber = 1;
                // start loading animation list view
                miniListView.loading = true;
                searchMiniListView(miniListView);
            };

            var searchMiniListView = _.debounce(function (miniListView) {
                scope.$apply(function () {
                    getChildrenForMiniListView(miniListView);
                });
            }, 500);

            /* Animation */
            scope.getMiniListViewAnimation = function() {

                // disable the first "slide-in-animation"" if the start node is a list view
                if(scope.node.metaData && scope.node.metaData.IsContainer && skipAnimation || scope.node.isContainer && skipAnimation) {
                    skipAnimation = false;
                    return;
                }

                if(goingForward) {
                    return 'umb-mini-list-view--forward';
                } else {
                    return 'umb-mini-list-view--backwards';
                }
            };

            onInit();

        }

        var directive = {
            restrict: 'E',
            replace: true,
            templateUrl: 'views/components/umb-mini-list-view.html',
            scope: {
                node: "=",
                entityType: "@",
                startNodeId: "=",
                onSelect: "&",
                onClose: "&"
            },
            link: link
        };

        return directive;

    }

    angular.module('umbraco.directives').directive('umbMiniListView', MiniListViewDirective);

})();
<|endoftext|>


<commit_before>const path                          = require('path');
const extend                        = require('extend');
const webpack                       = require('webpack');
const walk                          = require('walk');
const CleanWebpackPlugin            = require('clean-webpack-plugin');
const CopyWebpackPlugin             = require('copy-webpack-plugin');
const ExtractTextPlugin             = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin             = require('html-webpack-plugin');
// const UglifyJsPlugin                = require('uglifyjs-webpack-plugin');

let pathProjectRoot = path.resolve(__dirname, '../');
let pathPackage = path.resolve(pathProjectRoot, 'package.json');
let pathNpm = path.resolve(pathProjectRoot, 'node_modules');
let pathBuild = path.resolve(pathProjectRoot, 'build');
let pathDist = path.resolve(pathProjectRoot, 'dist');
let pathSrc = path.resolve(pathProjectRoot, 'src');
let pathDocs = path.resolve(pathProjectRoot, 'docs');
let pathFavicon = path.resolve(pathDocs, 'favicon.ico');
// let pathDocsCommon = path.resolve(pathDocs, 'common');
let pathReport = path.resolve(pathProjectRoot, 'report');
// let pathCoverage = path.resolve(pathReport, 'coverage');
let pathLib = path.resolve(pathSrc, 'lib');
let pathLibCommon = path.resolve(pathLib, 'common');
let pathLibUtils = path.resolve(pathLib, 'utils');
let pathSrcDocs = path.resolve(pathSrc, 'docs');
let pathSrcDocsPages = path.resolve(pathSrcDocs, 'pages');

let commonConfig = {};
let devVerConfig = {};
let prodVerConfig = {};
let docsConfig = {};

let extractDevCss = new ExtractTextPlugin({
    filename : 'morning-ui.css',
    allChunks : true
});
let extractProdCss = new ExtractTextPlugin('morning-ui.min.css');
let extractDocsCss = new ExtractTextPlugin('[name].css');
// let extractLibHighlightHopscotch = new ExtractTextPlugin('highlight.style.hopscotch.css');

let getDocsEntry = async docsConf => {

    walk.walkSync(pathSrcDocsPages, {
        listeners : {
            file : (root, fileStats, next) => {

                if (fileStats.name === 'index.js') {

                    let urlPath = root.replace(`${pathSrcDocsPages}/`, '');
                    let entryFile = `${root}/index.js`;

                    docsConf.entry[urlPath] = entryFile;

                }

                next();

            }
        }
    });

};

let getDocsHtmlPlugin = async docsConf => {

    for (let urlPath of Object.keys(docsConf.entry)) {

        if (['doc-common'].indexOf(urlPath) === -1) {

            docsConf.plugins.push(new HtmlWebpackPlugin({
                chunks : [urlPath],
                filename : `${urlPath}.html`,
                template : path.resolve(pathSrcDocs, 'tpl.html')
            }));

        }

    }

};

commonConfig = {
    entry : './src/lib/index.js',
    plugins : [],
    resolve : {
        alias : {
            Common : pathLibCommon,
            Utils : pathLibUtils,
            Npm : pathNpm
        }
    },
    externals : {
        vue : 'Vue'
    },
    output : {
        path : pathDist,
        library : 'morning',
        libraryTarget : 'umd'
    }
};

devVerConfig = extend(
    true,
    {},
    commonConfig,
    {
        plugins : [
            new CleanWebpackPlugin([pathDist], {
                root : pathProjectRoot
            }),
            new webpack.DefinePlugin({
                'process.env.NODE_ENV' : process.env.NODE_ENV
            }),
            extractDevCss
        ],
        module : {
            rules : [
                {
                    test : /\.less$/,
                    use : extractDevCss.extract({
                        fallback : 'vue-style-loader',
                        use : [{
                            loader : 'css-loader',
                            options : {
                                importLoaders : 2
                            }
                        }, {
                            loader : 'less-loader'
                        }, {
                            loader : 'postcss-loader',
                            options : {
                                config : {
                                    path : path.resolve(pathBuild, 'postcss.config.js')
                                }
                            }
                        }]
                    })
                },
                {
                    test : /\.woff$/,
                    exclude : /node_modules/,
                    use : [{
                        loader : 'url-loader'
                    }]
                },
                {
                    test : /\.vue$/,
                    loader : 'vue-loader',
                    options : {
                        loaders : {
                            js : 'babel-loader',
                            less : extractDevCss.extract({
                                fallback : 'vue-style-loader',
                                use : [{
                                    loader : 'css-loader',
                                    options : {
                                        importLoaders : 2
                                    }
                                }, {
                                    loader : 'less-loader'
                                }, {
                                    loader : 'postcss-loader',
                                    options : {
                                        config : {
                                            path : path.resolve(pathBuild, 'postcss.config.js')
                                        }
                                    }
                                }]
                            })
                        }
                    }
                },
                {
                    test : /\.js$/,
                    exclude : /node_modules/,
                    use : {
                        loader : 'babel-loader'
                    }
                }
            ]
        },
        output : {
            filename : 'morning-ui.js',
            publicPath : '/dist'
        },
        optimization : {
            minimize : false
        }
    }
);

prodVerConfig = extend(
    true,
    {},
    commonConfig,
    {
        plugins : [
            new CleanWebpackPlugin([pathDist], {
                root : pathProjectRoot
            }),
            new webpack.DefinePlugin({
                'process.env.NODE_ENV' : process.env.NODE_ENV
            }),
            // new UglifyJsPlugin(),
            extractProdCss
        ],
        module : {
            rules : [
                {
                    test : /\.less$/,
                    use : extractProdCss.extract({
                        fallback : 'vue-style-loader',
                        use : [{
                            loader : 'css-loader',
                            options : {
                                importLoaders : 3
                            }
                        }, {
                            loader : 'clean-css-loader'
                        }, {
                            loader : 'less-loader'
                        }, {
                            loader : 'postcss-loader',
                            options : {
                                config : {
                                    path : path.resolve(pathBuild, 'postcss.config.js')
                                }
                            }
                        }]
                    })
                },
                {
                    test : /\.woff/,
                    exclude : /node_modules/,
                    use : [{
                        loader : 'url-loader'
                    }]
                },
                {
                    test : /\.vue$/,
                    loader : 'vue-loader',
                    options : {
                        loaders : {
                            js : 'babel-loader',
                            less : extractProdCss.extract({
                                fallback : 'vue-style-loader',
                                use : [{
                                    loader : 'css-loader',
                                    options : {
                                        importLoaders : 3
                                    }
                                }, {
                                    loader : 'clean-css-loader'
                                }, {
                                    loader : 'less-loader'
                                }, {
                                    loader : 'postcss-loader',
                                    options : {
                                        config : {
                                            path : path.resolve(pathBuild, 'postcss.config.js')
                                        }
                                    }
                                }]
                            })
                        }
                    }
                },
                {
                    test : /\.js$/,
                    exclude : /node_modules/,
                    use : {
                        loader : 'babel-loader'
                    }
                }
            ]
        },
        output : {
            filename : 'morning-ui.min.js',
            publicPath : '/dist'
        }
    }
);

docsConfig = {
    entry : {
        // 'doc-common' : [
        //     'underscore',
        //     'highlight.js',
        //     'markdown-it',
        //     'mustache',
        //     'extend',
        //     'Docs/common/menu.js',
        //     'Docs/common/DocBody.vue',
        //     'Docs/common/DocComponent.vue',
        //     'Docs/common/DocComponentStatus.vue',
        //     'Docs/common/DocFooter.vue',
        //     'Docs/common/DocGuide.vue',
        //     'Docs/common/DocHeader.vue',
        //     'Docs/common/DocSubmenu.vue'
        // ]
    },
    plugins : [
        new CleanWebpackPlugin([pathDocs], {
            root : pathProjectRoot
        }),
        new webpack.DefinePlugin({
            'process.env.NODE_ENV' : process.env.NODE_ENV
        }),
        // new webpack.optimize.CommonsChunkPlugin({
        //     name : 'doc-common',
        //     minChunks : Infinity
        // }),
        extractDocsCss,
        new CopyWebpackPlugin([
            {
                from : path.resolve(pathSrcDocs, 'favicon.ico'),
                to : path.resolve(pathDocs, 'favicon.ico')
            }
        ])
    ],
    resolve : {
        alias : {
            Docs : pathSrcDocs,
            Npm : pathNpm
        }
    },
    externals : {
        vue : 'Vue'
    },
    devServer : {
        contentBase : [
            pathDocs,
            pathDist,
            pathReport,
            pathPackage,
            pathFavicon
        ],
        compress : true,
        hot : false
    },
    module : {
        rules : [
            {
                test : /\.woff$/,
                exclude : /node_modules/,
                use : [{
                    loader : 'file-loader',
                    options : {
                        name : '[name].[ext]'
                    }
                }]
            },
            {
                test : /\.vue$/,
                loader : 'vue-loader',
                options : {
                    loaders : {
                        js : 'babel-loader',
                        less : extractDocsCss.extract({
                            fallback : 'vue-style-loader',
                            use : ['css-loader', 'less-loader']
                        })
                    }
                }
            },
            {
                test : /\.js$/,
                exclude : /(node_modules|libs)/,
                use : {
                    loader : 'babel-loader'
                }
            }
        ]
    },
    optimization : {
        splitChunks : {
            cacheGroups: {
                commons: {
                    name: "doc-common",
                    chunks: "initial",
                    minChunks: 2
                }
            }
        }
    },
    output : {
        path : pathDocs,
        filename : '[name].js',
        publicPath : '/'
    }
};

getDocsEntry(docsConfig);
getDocsHtmlPlugin(docsConfig);

module.exports = [
    devVerConfig,
    prodVerConfig,
    docsConfig
];
<commit_msg>fix eslint<commit_after>const path                          = require('path');
const extend                        = require('extend');
const webpack                       = require('webpack');
const walk                          = require('walk');
const CleanWebpackPlugin            = require('clean-webpack-plugin');
const CopyWebpackPlugin             = require('copy-webpack-plugin');
const ExtractTextPlugin             = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin             = require('html-webpack-plugin');
// const UglifyJsPlugin                = require('uglifyjs-webpack-plugin');

let pathProjectRoot = path.resolve(__dirname, '../');
let pathPackage = path.resolve(pathProjectRoot, 'package.json');
let pathNpm = path.resolve(pathProjectRoot, 'node_modules');
let pathBuild = path.resolve(pathProjectRoot, 'build');
let pathDist = path.resolve(pathProjectRoot, 'dist');
let pathSrc = path.resolve(pathProjectRoot, 'src');
let pathDocs = path.resolve(pathProjectRoot, 'docs');
let pathFavicon = path.resolve(pathDocs, 'favicon.ico');
// let pathDocsCommon = path.resolve(pathDocs, 'common');
let pathReport = path.resolve(pathProjectRoot, 'report');
// let pathCoverage = path.resolve(pathReport, 'coverage');
let pathLib = path.resolve(pathSrc, 'lib');
let pathLibCommon = path.resolve(pathLib, 'common');
let pathLibUtils = path.resolve(pathLib, 'utils');
let pathSrcDocs = path.resolve(pathSrc, 'docs');
let pathSrcDocsPages = path.resolve(pathSrcDocs, 'pages');

let commonConfig = {};
let devVerConfig = {};
let prodVerConfig = {};
let docsConfig = {};

let extractDevCss = new ExtractTextPlugin({
    filename : 'morning-ui.css',
    allChunks : true
});
let extractProdCss = new ExtractTextPlugin('morning-ui.min.css');
let extractDocsCss = new ExtractTextPlugin('[name].css');
// let extractLibHighlightHopscotch = new ExtractTextPlugin('highlight.style.hopscotch.css');

let getDocsEntry = async docsConf => {

    walk.walkSync(pathSrcDocsPages, {
        listeners : {
            file : (root, fileStats, next) => {

                if (fileStats.name === 'index.js') {

                    let urlPath = root.replace(`${pathSrcDocsPages}/`, '');
                    let entryFile = `${root}/index.js`;

                    docsConf.entry[urlPath] = entryFile;

                }

                next();

            }
        }
    });

};

let getDocsHtmlPlugin = async docsConf => {

    for (let urlPath of Object.keys(docsConf.entry)) {

        if (['doc-common'].indexOf(urlPath) === -1) {

            docsConf.plugins.push(new HtmlWebpackPlugin({
                chunks : [urlPath],
                filename : `${urlPath}.html`,
                template : path.resolve(pathSrcDocs, 'tpl.html')
            }));

        }

    }

};

commonConfig = {
    entry : './src/lib/index.js',
    plugins : [],
    resolve : {
        alias : {
            Common : pathLibCommon,
            Utils : pathLibUtils,
            Npm : pathNpm
        }
    },
    externals : {
        vue : 'Vue'
    },
    output : {
        path : pathDist,
        library : 'morning',
        libraryTarget : 'umd'
    }
};

devVerConfig = extend(
    true,
    {},
    commonConfig,
    {
        plugins : [
            new CleanWebpackPlugin([pathDist], {
                root : pathProjectRoot
            }),
            new webpack.DefinePlugin({
                'process.env.NODE_ENV' : process.env.NODE_ENV
            }),
            extractDevCss
        ],
        module : {
            rules : [
                {
                    test : /\.less$/,
                    use : extractDevCss.extract({
                        fallback : 'vue-style-loader',
                        use : [{
                            loader : 'css-loader',
                            options : {
                                importLoaders : 2
                            }
                        }, {
                            loader : 'less-loader'
                        }, {
                            loader : 'postcss-loader',
                            options : {
                                config : {
                                    path : path.resolve(pathBuild, 'postcss.config.js')
                                }
                            }
                        }]
                    })
                },
                {
                    test : /\.woff$/,
                    exclude : /node_modules/,
                    use : [{
                        loader : 'url-loader'
                    }]
                },
                {
                    test : /\.vue$/,
                    loader : 'vue-loader',
                    options : {
                        loaders : {
                            js : 'babel-loader',
                            less : extractDevCss.extract({
                                fallback : 'vue-style-loader',
                                use : [{
                                    loader : 'css-loader',
                                    options : {
                                        importLoaders : 2
                                    }
                                }, {
                                    loader : 'less-loader'
                                }, {
                                    loader : 'postcss-loader',
                                    options : {
                                        config : {
                                            path : path.resolve(pathBuild, 'postcss.config.js')
                                        }
                                    }
                                }]
                            })
                        }
                    }
                },
                {
                    test : /\.js$/,
                    exclude : /node_modules/,
                    use : {
                        loader : 'babel-loader'
                    }
                }
            ]
        },
        output : {
            filename : 'morning-ui.js',
            publicPath : '/dist'
        },
        optimization : {
            minimize : false
        }
    }
);

prodVerConfig = extend(
    true,
    {},
    commonConfig,
    {
        plugins : [
            new CleanWebpackPlugin([pathDist], {
                root : pathProjectRoot
            }),
            new webpack.DefinePlugin({
                'process.env.NODE_ENV' : process.env.NODE_ENV
            }),
            // new UglifyJsPlugin(),
            extractProdCss
        ],
        module : {
            rules : [
                {
                    test : /\.less$/,
                    use : extractProdCss.extract({
                        fallback : 'vue-style-loader',
                        use : [{
                            loader : 'css-loader',
                            options : {
                                importLoaders : 3
                            }
                        }, {
                            loader : 'clean-css-loader'
                        }, {
                            loader : 'less-loader'
                        }, {
                            loader : 'postcss-loader',
                            options : {
                                config : {
                                    path : path.resolve(pathBuild, 'postcss.config.js')
                                }
                            }
                        }]
                    })
                },
                {
                    test : /\.woff/,
                    exclude : /node_modules/,
                    use : [{
                        loader : 'url-loader'
                    }]
                },
                {
                    test : /\.vue$/,
                    loader : 'vue-loader',
                    options : {
                        loaders : {
                            js : 'babel-loader',
                            less : extractProdCss.extract({
                                fallback : 'vue-style-loader',
                                use : [{
                                    loader : 'css-loader',
                                    options : {
                                        importLoaders : 3
                                    }
                                }, {
                                    loader : 'clean-css-loader'
                                }, {
                                    loader : 'less-loader'
                                }, {
                                    loader : 'postcss-loader',
                                    options : {
                                        config : {
                                            path : path.resolve(pathBuild, 'postcss.config.js')
                                        }
                                    }
                                }]
                            })
                        }
                    }
                },
                {
                    test : /\.js$/,
                    exclude : /node_modules/,
                    use : {
                        loader : 'babel-loader'
                    }
                }
            ]
        },
        output : {
            filename : 'morning-ui.min.js',
            publicPath : '/dist'
        }
    }
);

docsConfig = {
    entry : {},
    plugins : [
        new CleanWebpackPlugin([pathDocs], {
            root : pathProjectRoot
        }),
        new webpack.DefinePlugin({
            'process.env.NODE_ENV' : process.env.NODE_ENV
        }),
        // new webpack.optimize.CommonsChunkPlugin({
        //     name : 'doc-common',
        //     minChunks : Infinity
        // }),
        extractDocsCss,
        new CopyWebpackPlugin([
            {
                from : path.resolve(pathSrcDocs, 'favicon.ico'),
                to : path.resolve(pathDocs, 'favicon.ico')
            }
        ])
    ],
    resolve : {
        alias : {
            Docs : pathSrcDocs,
            Npm : pathNpm
        }
    },
    externals : {
        vue : 'Vue'
    },
    devServer : {
        contentBase : [
            pathDocs,
            pathDist,
            pathReport,
            pathPackage,
            pathFavicon
        ],
        compress : true,
        hot : false
    },
    module : {
        rules : [
            {
                test : /\.woff$/,
                exclude : /node_modules/,
                use : [{
                    loader : 'file-loader',
                    options : {
                        name : '[name].[ext]'
                    }
                }]
            },
            {
                test : /\.vue$/,
                loader : 'vue-loader',
                options : {
                    loaders : {
                        js : 'babel-loader',
                        less : extractDocsCss.extract({
                            fallback : 'vue-style-loader',
                            use : ['css-loader', 'less-loader']
                        })
                    }
                }
            },
            {
                test : /\.js$/,
                exclude : /(node_modules|libs)/,
                use : {
                    loader : 'babel-loader'
                }
            }
        ]
    },
    optimization : {
        splitChunks : {
            cacheGroups : {
                commons : {
                    name : 'doc-common',
                    chunks : 'initial',
                    minChunks : 2
                }
            }
        }
    },
    output : {
        path : pathDocs,
        filename : '[name].js',
        publicPath : '/'
    }
};

getDocsEntry(docsConfig);
getDocsHtmlPlugin(docsConfig);

module.exports = [
    devVerConfig,
    prodVerConfig,
    docsConfig
];
<|endoftext|>


<commit_before>/**
 * Created by fran on 14/07/2017.
 */

import React, { Component, PropTypes } from 'react';
import { reduxForm }  from 'redux-form';
import { createPost } from '../actions/index'
import { Link } from 'react-router'

class PostsNew extends Component{

    static contextTypes={
        router:PropTypes.object
    }

    onSubmit(props){
        this.props.createPost(props)
            .then(() => {
                //post created, user to the index
                //we navegate to the index calling this.context.router.push with the new path
                this.context.router.push('/')
            })
    }
    render(){
        const { fields:{ title, categories, content },handleSubmit } = this.props;

        return(
            <form onSubmit={ handleSubmit(this.onSubmit.bind(this)) }>

Create a new post

                <div className={`form-group ${title.touched && title.invalid ? 'has-danger' : ''}`}>

                        Title
                        <input type="text" className="form-control" {...title}/>

                        {title.touched ? title.error : ''}

                <div className={`form-group ${categories.touched && categories.invalid ? 'has-danger' : ''}`}>

                        Categories
                        <input type="text" className="form-control" {...categories}/>

                        {categories.touched ? categories.error : ''}

                <div className={`form-group ${content.touched && content.invalid ? 'has-danger' : ''}`}>

                        Content
                        <textarea className="form-control" {...content}/>

                        {content.touched ? content.error : ''}

                <button type="submit" className="btn btn-success" >Submit</button>
                <Link to="/" className="btn btn-danger btn-cancel">Cancel</Link>

            </form>
        )
    }
}

function validate(values){
    const errors ={};

    if (!values.title){
        errors.title = 'Enter a Username';
    }
    if (!values.categories){
        errors.categories = 'Enter a categories';
    }
    if (!values.content){
        errors.content = 'Enter a content';
    }

    return errors;
}
export default reduxForm({
    form: 'PostsNewForm',
    fields: ['title','categories','content'],
    validate
},null, { createPost })(PostsNew);
<commit_msg>Dinamic form redux-form<commit_after>/**
 * Created by fran on 14/07/2017.
 */

import _ from 'lodash';
import React, { Component, PropTypes } from 'react';
import { reduxForm }  from 'redux-form';
import { createPost } from '../actions/index'
import { Link } from 'react-router'

const FIELDS = {
    title:{
        id:1,
        type: 'input',
        label: 'Title for Post',
    },
    categories: {
        id:2,
        type: 'input',
        label: 'Categories for Post',

    },
    content:{
        id:3,
        type: 'textarea',
        label: 'Content for Post',

    }
}

class PostsNew extends Component{

    static contextTypes={
        router:PropTypes.object
    }
    renderField(fieldConfig, field ){
        const fieldHelper = this.props.fields[field];

        return(
            <div key={fieldConfig.id} className={`form-group ${fieldHelper.touched && fieldHelper.invalid ? 'has-danger' : ''}`}>

                    {fieldConfig.label}
                    <fieldConfig.type type="text" className="form-control" {...fieldHelper}/>

                    {fieldHelper.touched ? fieldHelper.error : ''}

        )
    }
    onSubmit(props){
        this.props.createPost(props)
            .then(() => {
                //post created, user to the index
                //we navegate to the index calling this.context.router.push with the new path
                this.context.router.push('/')
            })
    }
    render(){
        const { handleSubmit } = this.props;

        return(
            <form onSubmit={ handleSubmit(this.onSubmit.bind(this)) }>

Create a new post

                {_.map(FIELDS,this.renderField.bind(this))}
                <button type="submit" className="btn btn-success" >Submit</button>
                <Link to="/" className="btn btn-danger btn-cancel">Cancel</Link>

            </form>
        )
    }
}

function validate(values){
    const errors ={};

    _.each(FIELDS, (type, field)=>{
        if(!values[field]){
            errors[field]= `Enter a ${field }`
        }
    })

    return errors;
}
export default reduxForm({
    form: 'PostsNewForm',
    fields: _.keys(FIELDS),
    validate
},null, { createPost })(PostsNew);
<|endoftext|>


<commit_before>/* global
	global, document, demand, provide, queue, processor, settings, setTimeout, clearTimeout, storage,
	EVENT_QUEUE_ENQUEUE, NULL,
	singletonEvent,
	AbstractUuid
*/

//=require constants.js
//=require abstract/uuid.js

function ClassProcessor(queue) {
	var self    = this.parent.constructor.call(this),
		pointer = storage[self.uuid] = { queue: queue, current: NULL };

	demand
		.on(EVENT_QUEUE_ENQUEUE + ':' + queue.uuid, function() {
			!pointer.current && self.process();
		});
}

ClassProcessor.prototype = {
	process: function() {
		var pointer = storage[this.uuid],
				current;

		if(pointer.queue.length) {
			current = pointer.current = pointer.queue.dequeue();

			current.handler.process && current.handler.process(current);
		} else {
			pointer.current = NULL;
		}
	},
	get current() {
		return storage[this.uuid].current;
	}
};

ClassProcessor.extends(AbstractUuid);<commit_msg>fix indention<commit_after>/* global
	global, document, demand, provide, queue, processor, settings, setTimeout, clearTimeout, storage,
	EVENT_QUEUE_ENQUEUE, NULL,
	singletonEvent,
	AbstractUuid
*/

//=require constants.js
//=require abstract/uuid.js

function ClassProcessor(queue) {
	var self    = this.parent.constructor.call(this),
		pointer = storage[self.uuid] = { queue: queue, current: NULL };

	demand
		.on(EVENT_QUEUE_ENQUEUE + ':' + queue.uuid, function() {
			!pointer.current && self.process();
		});
}

ClassProcessor.prototype = {
	process: function() {
		var pointer = storage[this.uuid],
			current;

		if(pointer.queue.length) {
			current = pointer.current = pointer.queue.dequeue();

			current.handler.process && current.handler.process(current);
		} else {
			pointer.current = NULL;
		}
	},
	get current() {
		return storage[this.uuid].current;
	}
};

ClassProcessor.extends(AbstractUuid);<|endoftext|>


<commit_before>/**
* Converts an HSV color value to RGB. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes h, s, and v are contained in the set [0, 1] and
* returns r, g, and b in the set [0, 255].
*
* @param   Number  h       The hue
* @param   Number  s       The saturation
* @param   Number  v       The brightness
* @return  Array           The RGB representation
*/
function HSVtoRGB(h, s, v) {
    var r, g, b, i, f, p, q, t;
    if (arguments.length === 1) {
        s = h.s, v = h.v, h = h.h;
    }
    i = Math.floor(h * 6);
    f = h * 6 - i;
    p = v * (1 - s);
    q = v * (1 - f * s);
    t = v * (1 - (1 - f) * s);
    switch (i % 6) {
        case 0: r = v, g = t, b = p; break;
        case 1: r = q, g = v, b = p; break;
        case 2: r = p, g = v, b = t; break;
        case 3: r = p, g = q, b = v; break;
        case 4: r = t, g = p, b = v; break;
        case 5: r = v, g = p, b = q; break;
    }
    return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}

function RGBtoCSS(rgb) {
  return "rgb(" + rgb[0] + ", " + rgb[1] + ", " + rgb[2] + ")"
}

function createLinearGradient(stops) {
  return 'linear-gradient(to right, ' + stops.join(',') + ')';
}

function updateLights (state) {
  lights = state.lights
  isPartyOn = state.isPartyOn
  isLocked = state.isLocked
}

function renderLamps () {
  lights.forEach(function (light) {
    drawLamp(light)
    $('#switch_' + light.id).prop('checked', light.on)
  })
  if (isPartyOn) {
    runParty()
  } else {
    ruinParty()
  }
}
/**
* draw() is called first when the body loads, and then on each change of value (hue,bri,sat).
* Correct is a boolean for if the given value should be corrected to the triangle
* the h,s,l value is taken from each light.
*/
function draw (id, hue, sat, brightness) {
  var div = document.getElementById('color_shower_' + id)

  var rgb = HSVtoRGB(hue, sat, brightness)
  div.style.backgroundColor = RGBtoCSS(rgb)
}

// Used when disregarding the value of the selectors, only wanting to draw the color of the bulb or if it is off
function drawLamp (light) {
  if (!light.on) {
    draw(light.id, 0, 0, 0.5)
  } else {
    draw(light.id, light.hue / 65535, light.sat / 254, light.bri / 254)
  }
}
//Returns the value of the hue slider normalized.
function getHue() {
	return getNormalizedRangeValue("hue_range");
}
//Returns the value of the saturation slider normalized.
function getSat() {
	return getNormalizedRangeValue("sat_range");
}

//Returns the value of the brightness slider normalized.
function getBri() {
	return getNormalizedRangeValue("bri_range");
}

function getNormalizedRangeValue(elementId) {
	var range = document.getElementById(elementId)
	return range.value / range.max;
}

//Draws the canvas behind the brightness slider to visualize how the brightness changes
function draw_bri_canvas() {
  var slider = $(".bri-show");
  slider.css('background', 'linear-gradient(to right, black, white)');
}

//Draws the canvas behind the saturation slider with an approximation of what colour the lights will have at that position.
function draw_sat_canvas() {
	var slider = $(".sat-show");
  var hue = getHue()
  var bri = getBri()
  var stops = [HSVtoRGB(hue, 0, bri), HSVtoRGB(hue, 1, bri)].map(RGBtoCSS)
  slider.css('background', createLinearGradient(stops));
}

//Draws the canvas behind the hue slider with an approximation of what colour the lights will have at that position.
function draw_hue_canvas(){
  var slider = $(".hue-show");
	// var context = canvas.getContext("2d");
  var numberStops = 20
  var stops = []
  var sat = getSat()
  var bri = getBri()

  for (var i = 0; i < numberStops; i++) {
    stops.push(i / numberStops);
  }

  stops = stops.map(function(hue) {
    return RGBtoCSS(HSVtoRGB(hue, sat, bri));
  });

  slider.css('background', createLinearGradient(stops))
}
<commit_msg>Use JQuery in draw function<commit_after>/**
* Converts an HSV color value to RGB. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes h, s, and v are contained in the set [0, 1] and
* returns r, g, and b in the set [0, 255].
*
* @param   Number  h       The hue
* @param   Number  s       The saturation
* @param   Number  v       The brightness
* @return  Array           The RGB representation
*/
function HSVtoRGB(h, s, v) {
    var r, g, b, i, f, p, q, t;
    if (arguments.length === 1) {
        s = h.s, v = h.v, h = h.h;
    }
    i = Math.floor(h * 6);
    f = h * 6 - i;
    p = v * (1 - s);
    q = v * (1 - f * s);
    t = v * (1 - (1 - f) * s);
    switch (i % 6) {
        case 0: r = v, g = t, b = p; break;
        case 1: r = q, g = v, b = p; break;
        case 2: r = p, g = v, b = t; break;
        case 3: r = p, g = q, b = v; break;
        case 4: r = t, g = p, b = v; break;
        case 5: r = v, g = p, b = q; break;
    }
    return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}

function RGBtoCSS(rgb) {
  return "rgb(" + rgb[0] + ", " + rgb[1] + ", " + rgb[2] + ")"
}

function createLinearGradient(stops) {
  return 'linear-gradient(to right, ' + stops.join(',') + ')';
}

function updateLights (state) {
  lights = state.lights
  isPartyOn = state.isPartyOn
  isLocked = state.isLocked
}

function renderLamps () {
  lights.forEach(function (light) {
    drawLamp(light)
    $('#switch_' + light.id).prop('checked', light.on)
  })
  if (isPartyOn) {
    runParty()
  } else {
    ruinParty()
  }
}
/**
* draw() is called first when the body loads, and then on each change of value (hue,bri,sat).
* Correct is a boolean for if the given value should be corrected to the triangle
* the h,s,l value is taken from each light.
*/
function draw (id, hue, sat, brightness) {
  var rgb = HSVtoRGB(hue, sat, brightness)
  $(id)[0].style.backgroundColor = RGBtoCSS(rgb)
}

// Used when disregarding the value of the selectors, only wanting to draw the color of the bulb or if it is off
function drawLamp (light) {
  if (!light.on) {
    draw('#color_shower_' + light.id, 0, 0, 0.5)
  } else {
    draw('#color_shower_' + light.id, light.hue / 65535, light.sat / 254, light.bri / 254)
  }
}
//Returns the value of the hue slider normalized.
function getHue() {
	return getNormalizedRangeValue("hue_range");
}
//Returns the value of the saturation slider normalized.
function getSat() {
	return getNormalizedRangeValue("sat_range");
}

//Returns the value of the brightness slider normalized.
function getBri() {
	return getNormalizedRangeValue("bri_range");
}

function getNormalizedRangeValue(elementId) {
	var range = document.getElementById(elementId)
	return range.value / range.max;
}

//Draws the canvas behind the brightness slider to visualize how the brightness changes
function draw_bri_canvas() {
  var slider = $(".bri-show");
  slider.css('background', 'linear-gradient(to right, black, white)');
}

//Draws the canvas behind the saturation slider with an approximation of what colour the lights will have at that position.
function draw_sat_canvas() {
	var slider = $(".sat-show");
  var hue = getHue()
  var bri = getBri()
  var stops = [HSVtoRGB(hue, 0, bri), HSVtoRGB(hue, 1, bri)].map(RGBtoCSS)
  slider.css('background', createLinearGradient(stops));
}

//Draws the canvas behind the hue slider with an approximation of what colour the lights will have at that position.
function draw_hue_canvas(){
  var slider = $(".hue-show");
	// var context = canvas.getContext("2d");
  var numberStops = 20
  var stops = []
  var sat = getSat()
  var bri = getBri()

  for (var i = 0; i < numberStops; i++) {
    stops.push(i / numberStops);
  }

  stops = stops.map(function(hue) {
    return RGBtoCSS(HSVtoRGB(hue, sat, bri));
  });

  slider.css('background', createLinearGradient(stops))
}
<|endoftext|>


<commit_before>/**
 * Watson gives Sherlock an array A of length n. Then he asks him to determine
 * if there exists an element in the array such that the sum of the elements on
 * its left is equal to the sum of the elements on its right. If there are no
 * elements to the left/right, then the sum is considered to be zero.
 *
 * Formally, find an i, such that, A0 + A1 + ... Ai-1 = Ai + 1 + Ai + 2 +...+ An-1.
 *
 * Input Format
 *
 * The first line contains T, the number of test cases. For each test case,
 * the first line contains n, the number of elements in the array .
 * The second line for each test case contains n space-separated integers,
 * denoting the array A.
 */
process.stdin.resume();
process.stdin.setEncoding('ascii');

var input_stdin = "";
var input_stdin_array = "";
var input_currentline = 0;

process.stdin.on('data', function (data) {
    input_stdin += data;
});

process.stdin.on('end', function () {
    input_stdin_array = input_stdin.split("\n");
    main();
});

function readLine() {
    return input_stdin_array[input_currentline++];
}

/////////////// ignore above this line ////////////////////
function solve1(a) {
  // O(n*n)
  for (let i = 0; i < a.length; i++) {
    let left = 0;
    for (let j = 0; j < i; j++) {
      left += a[j];
    }

    let right = 0;
    for (let k = i + 1; k < a.length; k++) {
      right += a[k];
    }

    if (left === right) {
      return 'YES';
    }
  }

  return 'NO';
}

function solve2(a, map) {
  let sum = a[a.length - 1];

  // O(n)
  for (let i = a.length - 2; i >= 0; i--) {
    if (map.get(i) === sum) {
        return 'YES';
    }
    sum += a[i];
  }

  return 'NO';
}

function main() {
  let T = parseInt(readLine());

  for(var a0 = 0; a0 < T; a0++){
    var n = parseInt(readLine());
    a = readLine().split(' ');

    if (n === 1) {
      // https://www.hackerrank.com/challenges/sherlock-and-array/forum/comments/82083
      result = 'YES';
    } else if (n < 3) {
      result = 'NO';
    } else {
      let sumToLeft = 0;
      let map = new Map();
      a = a.map((num, i) => {
          map.set(i, sumToLeft);
          num = Number(num);
          sumToLeft += num;
          return num;
      });
      result = solve2(a, map);
    }

    process.stdout.write(""+ result +"\n");
  }
}
<commit_msg>Add a much simpler Sherlock and Array solution<commit_after>/**
 * Watson gives Sherlock an array A of length n. Then he asks him to determine
 * if there exists an element in the array such that the sum of the elements on
 * its left is equal to the sum of the elements on its right. If there are no
 * elements to the left/right, then the sum is considered to be zero.
 *
 * Formally, find an i, such that, A0 + A1 + ... Ai-1 = Ai + 1 + Ai + 2 +...+ An-1.
 *
 * Input Format
 *
 * The first line contains T, the number of test cases. For each test case,
 * the first line contains n, the number of elements in the array .
 * The second line for each test case contains n space-separated integers,
 * denoting the array A.
 */
process.stdin.resume();
process.stdin.setEncoding('ascii');

var input_stdin = "";
var input_stdin_array = "";
var input_currentline = 0;

process.stdin.on('data', function (data) {
    input_stdin += data;
});

process.stdin.on('end', function () {
    input_stdin_array = input_stdin.split("\n");
    main();
});

function readLine() {
    return input_stdin_array[input_currentline++];
}

/////////////// ignore above this line ////////////////////
function solve1(a) {
  // O(n*n)
  for (let i = 0; i < a.length; i++) {
    let left = 0;
    for (let j = 0; j < i; j++) {
      left += a[j];
    }

    let right = 0;
    for (let k = i + 1; k < a.length; k++) {
      right += a[k];
    }

    if (left === right) {
      return 'YES';
    }
  }

  return 'NO';
}

function solve2(a, map) {
  let sum = a[a.length - 1];

  // O(n)
  for (let i = a.length - 2; i >= 0; i--) {
    if (map.get(i) === sum) {
        return 'YES';
    }
    sum += a[i];
  }

  return 'NO';
}

function solve3(a, right) {
  // O(n)
  let left = 0, j = 0;
  for (let i = a.length - 1; i > 0; i--) {
      left += a[i];
      if (left === right) {
          return 'YES';
      }
      right -= a[i];
  }

  return 'NO';
}

function main() {
  let T = parseInt(readLine());

  for(var a0 = 0; a0 < T; a0++){
    var n = parseInt(readLine());
    a = readLine().split(' ');

    if (n === 1) {
      // https://www.hackerrank.com/challenges/sherlock-and-array/forum/comments/82083
      result = 'YES';
    } else if (n < 3) {
      result = 'NO';
    } else {
      let sumToLeft = 0;
      let map = new Map();
      a = a.map((num, i) => {
          map.set(i, sumToLeft);
          num = Number(num);
          sumToLeft += num;
          return num;
      });
      //result = solve2(a, map);
      result = solve3(a, sumToLeft);
    }

    process.stdout.write(""+ result +"\n");
  }
}
<|endoftext|>


<commit_before>/*
  This is a moog modal for the reorganize pages feature
*/

apos.define('apostrophe-pages-reorganize', {
  extend: 'apostrophe-modal',
  source: 'reorganize',
  construct: function(self, options) {
    self.beforeShow = function(callback) {
      self.$tree = self.$el.find('[data-tree]');
      self.$tree.tree({
        data: [],
        autoOpen: 0,
        openFolderDelay: 2500,
        dragAndDrop: true,
        onCanMoveTo: function(moved_node, target_node, position) {
          // Cannot create peers of root
          if ((target_node.slug === '/') && (position !== 'inside')) {
            return false;
          }
          return true;
        },
        onCreateLi: function(node, $li) {
          // Identify the root trashcan and add a class to its li so that we
          // can hide inappropriate controls within the trash
          // TODO: do we want to make this slug a constant forever?
          if (node.slug == '/trash') {
            $li.addClass('apos-trash');
            if (self.options.trashInTree) {
              // Hide this node altogether, we're displaying trash "in place"
              $li.css('display', 'none');
            }
          }
          $li.find('.jqtree-element').append($(''));
          // Append a link to the jqtree-element div.
          // The link has a url '#node-[id]' and a data property 'node-id'.
          var $link = $('');
          $link.attr('data-node-id', node.id);
          $link.attr('data-visit', '1');
          $link.attr('href', '#');
          // link.text('»');
          $link.append('');
          $li.find('.jqtree-element .apos-reorganize-controls').append(link);
          if (node.publish) {
            // Regular "to the trash" button. CSS hides when
            // already in the trash
            $link = $('');
            $link.attr('data-node-id', node.id);
            $link.attr('data-delete', '1');
            $link.attr('href', '#');
            $link.append('');
            $li.find('.jqtree-element .apos-reorganize-controls').append(link);

            if (self.options.deleteFromTrash) {
              // "Destroy forever" button. CSS reveals when
              // already in the trash
              $link = $('');
              $link.attr('data-node-id', node.id);
              $link.attr('data-delete-from-trash', '1');
              $link.attr('href', '#');
              $link.append('');
              $li.find('.jqtree-element .apos-reorganize-controls').append(link);
            }
          }
        }
      });

      self.$tree.on('click', '[data-visit]', function() {
        self.visit($(this));
        return false;
      });

      self.$tree.on('click', '[data-delete]', function() {
        self.delete($(this));
        return false;
      });

      self.$tree.on('click', '[data-delete-from-trash]', function() {
        self.deleteFromTrash($(this));
        return false;
      });

      self.$tree.on('tree.move', function(e) {
        self.move(e);
        return false;
      });

      self.reload(callback);
    };

    // After a reorg the page URL may have changed, be prepared to
    // navigate there or to the home page or just refresh to reflect
    // possible new tabs
    self.afterHide = function() {
      var page = apos.pages.page;
      var _id = page._id;
      self.api('info', { _id: _id }, function(data) {
        if (data.status !== 'ok') {
          // WTF, go home
          apos.ui.redirect('/');
        }
         var newPathname = data.page.slug.replace(/^\/\//, '/');
        apos.ui.redirect(newPathname);
      }, function() {
        // If the page no longer exists, navigate away to home page
        apos.ui.redirect('/');
      });
    };

    self.visit = function($node){
      var nodeId = $node.attr('data-node-id');
      var node = self.$tree.tree('getNodeById', nodeId);
      var tab = window.open(apos.prefix + node.slug, '_blank');
      tab.focus();
    };

    self.delete = function($node){
      if (!confirm('Are you sure you want to move this page to the trash?')) {
        return false;
      }

      var nodeId = $node.attr('data-node-id');
      var node = self.$tree.tree('getNodeById', nodeId);
      // Find the trashcan so we can mirror what happened on the server
      var trash;
      _.each(self.$tree.tree('getTree').children[0].children, function(node) {
        if (node.trash) {
          trash = node;
        }
      });
      if (!trash) {
        alert('No trashcan.');
        return false;
      }

      apos.pages.trash(node.id, function(err, parentSlug, changed) {
        if (err) {
          alert('An error occurred.');
          return;
        }
        self.$tree.tree('moveNode', node, trash, 'inside');
        _.each(changed, function(info) {
          var node = self.$tree.tree('getNodeById', info.id);
          if (node) {
            node.slug = info.slug;
          }
        });
      });
      return false;
    };

    self.deleteFromTrash = function($node) {

      var nodeId = $node.attr('data-node-id');
      var node = self.$tree.tree('getNodeById', nodeId);

      var warning = 'Are you sure you want to DESTROY THIS PAGE FOREVER? This CANNOT BE UNDONE.';
      if (node.children && node.children.length) {
        warning = 'Are you sure you want to DESTROY THIS PAGE AND ALL OF ITS CHILD PAGES FOREVER? This CANNOT BE UNDONE.';
      }
      if (!confirm(warning)) {
        return false;
      }

      apos.pages.deleteFromTrash(node.id, function(err, parentSlug) {
        if (err) {
          alert('An error occurred.');
          return;
        }
        self.$tree.tree('removeNode', node);
      });
      return false;
    };

    self.move = function(e){
      e.preventDefault();
      self.$el.find('.apos-reorganize-progress').fadeIn();
      var data = {
        movedId: e.move_info.moved_node.id,
        targetId: e.move_info.target_node.id,
        position: e.move_info.position
      };

      self.api('move', data, function(data){
        if(data.status === 'ok'){
          // Reflect changed slugs
          _.each(data.changed, function(info) {
            var node = self.$tree.tree('getNodeById', info.id);
            if (node) {
              node.slug = info.slug;
            }
          });
          e.move_info.do_move();
          self.$el.find('.apos-reorganize-progress').fadeOut();
        } else{
          self.errorOnMove();
        }
      }, function(){
        self.errorOnMove();
      });
    };

    self.reload = function(callback){
      self.api('get-jqtree', {}, function(data) {
        if (data.status === 'ok') {
          self.$tree.tree('loadData', data.tree);
          console.log(data.tree);
          if (callback) {
            return callback();
          }
        } else {
          self.errorOnReload();
        }
      }, function() {
        self.errorOnReload();
      });
    };

    self.errorOnReload = function(){
      alert('The server did not respond or you do not have the appropriate privileges.');
      self.hide();
    };

    self.errorOnMove = function(){
      alert('You may only move pages you are allowed to publish. If you move a page to a new parent, you must be allowed to edit the new parent.');

      setImmediate(function() {
        self.reload(function() {
          self.$el.find('.apos-reorganize-progress').fadeOut();
        });
      });
    };
  }
});
<commit_msg>more trashInTree work in progress<commit_after>/*
  This is a moog modal for the reorganize pages feature
*/

apos.define('apostrophe-pages-reorganize', {
  extend: 'apostrophe-modal',
  source: 'reorganize',
  construct: function(self, options) {
    self.beforeShow = function(callback) {
      self.$tree = self.$el.find('[data-tree]');
      self.$tree.tree({
        data: [],
        autoOpen: 0,
        openFolderDelay: 2500,
        dragAndDrop: true,
        onCanMoveTo: function(moved_node, target_node, position) {
          // Cannot create peers of root
          if ((target_node.slug === '/') && (position !== 'inside')) {
            return false;
          }
          return true;
        },
        onCreateLi: function(node, $li) {
          // Identify the root trashcan and add a class to its li so that we
          // can hide inappropriate controls within the trash
          // TODO: do we want to make this slug a constant forever?
          if (node.slug == '/trash') {
            $li.addClass('apos-trash');
            if (self.options.trashInTree) {
              // Hide this node altogether, we're displaying trash "in place"
              $li.css('display', 'none');
            }
          }
          $li.find('.jqtree-element').append($(''));
          // Append a link to the jqtree-element div.
          // The link has a url '#node-[id]' and a data property 'node-id'.
          var $link = $('');
          $link.attr('data-node-id', node.id);
          $link.attr('data-visit', '1');
          $link.attr('href', '#');
          // link.text('»');
          $link.append('');
          $li.find('.jqtree-element .apos-reorganize-controls').append($link);
          if (node.publish) {
            // Regular "to the trash" button. CSS hides when
            // already in the trash
            $link = $('');
            $link.attr('data-node-id', node.id);
            $link.attr('data-delete', '1');
            $link.attr('href', '#');
            $link.append('');
            $li.find('.jqtree-element .apos-reorganize-controls').append($link);

            if (self.options.deleteFromTrash) {
              // "Destroy forever" button. CSS reveals when
              // already in the trash
              $link = $('');
              $link.attr('data-node-id', node.id);
              $link.attr('data-delete-from-trash', '1');
              $link.attr('href', '#');
              $link.append('');
              $li.find('.jqtree-element .apos-reorganize-controls').append($link);
            }
          }
        }
      });

      self.$tree.on('click', '[data-visit]', function() {
        self.visit($(this));
        return false;
      });

      self.$tree.on('click', '[data-delete]', function() {
        self.delete($(this));
        return false;
      });

      self.$tree.on('click', '[data-delete-from-trash]', function() {
        self.deleteFromTrash($(this));
        return false;
      });

      self.$tree.on('tree.move', function(e) {
        self.move(e);
        return false;
      });

      self.reload(callback);
    };

    // After a reorg the page URL may have changed, be prepared to
    // navigate there or to the home page or just refresh to reflect
    // possible new tabs
    self.afterHide = function() {
      var page = apos.pages.page;
      var _id = page._id;
      self.api('info', { _id: _id }, function(data) {
        if (data.status !== 'ok') {
          // WTF, go home
          apos.ui.redirect('/');
        }
         var newPathname = data.page.slug.replace(/^\/\//, '/');
        apos.ui.redirect(newPathname);
      }, function() {
        // If the page no longer exists, navigate away to home page
        apos.ui.redirect('/');
      });
    };

    self.visit = function($node){
      var nodeId = $node.attr('data-node-id');
      var node = self.$tree.tree('getNodeById', nodeId);
      var tab = window.open(apos.prefix + node.slug, '_blank');
      tab.focus();
    };

    self.delete = function($node){
      if (!confirm('Are you sure you want to move this page to the trash?')) {
        return false;
      }

      var nodeId = $node.attr('data-node-id');
      var node = self.$tree.tree('getNodeById', nodeId);
      // Find the trashcan so we can mirror what happened on the server
      var trash;
      _.each(self.$tree.tree('getTree').children[0].children, function(node) {
        if (node.trash) {
          trash = node;
        }
      });
      if (!trash) {
        alert('No trashcan.');
        return false;
      }

      apos.pages.trash(node.id, function(err, parentSlug, changed) {
        if (err) {
          alert('An error occurred.');
          return;
        }
        self.$tree.tree('moveNode', node, trash, 'inside');
        _.each(changed, function(info) {
          var node = self.$tree.tree('getNodeById', info.id);
          if (node) {
            node.slug = info.slug;
          }
        });
      });
      return false;
    };

    self.deleteFromTrash = function($node) {

      var nodeId = $node.attr('data-node-id');
      var node = self.$tree.tree('getNodeById', nodeId);

      var warning = 'Are you sure you want to DESTROY THIS PAGE FOREVER? This CANNOT BE UNDONE.';
      if (node.children && node.children.length) {
        warning = 'Are you sure you want to DESTROY THIS PAGE AND ALL OF ITS CHILD PAGES FOREVER? This CANNOT BE UNDONE.';
      }
      if (!confirm(warning)) {
        return false;
      }

      apos.pages.deleteFromTrash(node.id, function(err, parentSlug) {
        if (err) {
          alert('An error occurred.');
          return;
        }
        self.$tree.tree('removeNode', node);
      });
      return false;
    };

    self.move = function(e){
      e.preventDefault();
      self.$el.find('.apos-reorganize-progress').fadeIn();
      var data = {
        movedId: e.move_info.moved_node.id,
        targetId: e.move_info.target_node.id,
        position: e.move_info.position
      };

      self.api('move', data, function(data){
        if(data.status === 'ok'){
          // Reflect changed slugs
          _.each(data.changed, function(info) {
            var node = self.$tree.tree('getNodeById', info.id);
            if (node) {
              node.slug = info.slug;
            }
          });
          e.move_info.do_move();
          self.$el.find('.apos-reorganize-progress').fadeOut();
        } else{
          self.errorOnMove();
        }
      }, function(){
        self.errorOnMove();
      });
    };

    self.reload = function(callback){
      self.api('get-jqtree', {}, function(data) {
        if (data.status === 'ok') {
          if (self.options.trashInTree) {
            self.addVirtualTrashcans(data.tree);
          }
          self.$tree.tree('loadData', data.tree);
          console.log(data.tree);
          if (callback) {
            return callback();
          }
        } else {
          self.errorOnReload();
        }
      }, function() {
        self.errorOnReload();
      });
    };

    self.addVirtualTrashcans = function(tree) {
      _.each(tree, function(node) {
        self.addVirtualTrashcanIfNeeded(node);
      });
    };

    self.addVirtualTrashcanIfNeeded = function(node) {
      if (node.children && node.children.length) {
        var trashed = _.filter(node.children, { trash: true });
        var trash = {
          label: '🗑',
          virtualTrashcan: true,
          children: trashed
        };
        node.children = _.filter(node.children, function(child) {
          return !child.trash;
        }).concat([ trash ]);
      }
    };

    self.errorOnReload = function(){
      alert('The server did not respond or you do not have the appropriate privileges.');
      self.hide();
    };

    self.errorOnMove = function(){
      alert('You may only move pages you are allowed to publish. If you move a page to a new parent, you must be allowed to edit the new parent.');

      setImmediate(function() {
        self.reload(function() {
          self.$el.find('.apos-reorganize-progress').fadeOut();
        });
      });
    };
  }
});
<|endoftext|>


<commit_before>$(function () {
    $('#monthly-overview-chart').highcharts({
        chart: {
            zoomType: 'xy'
        },
        title: {
            text: 'Energy Production for 2014'
        },
        colors: ['#428BCA', '#153E7E', '#B4C7DA', '#24CBE5', '#64E572', '#FF9655', '#FFF263', '#6AF9C4'],
        xAxis: [
            {
                type: 'datetime',
                dateTimeLabelFormats: { // don't display the dummy year
                    month: '%e. %b',
                    year: '%b'
                }
            }
        ],
        yAxis: [
            { // Primary yAxis
                labels: {
                    format: '{value} kW',
                    style: {
                        color: Highcharts.getOptions().colors[1]
                    }
                },
                title: {
                    text: 'Power',
                    style: {
                        color: Highcharts.getOptions().colors[1]
                    }
                }
            }
        ],
        tooltip: {
            shared: true,
            headerFormat: '{series.name}
',
            pointFormat: '{point.x: %b}: {point.y:.2f} kW'
        },
        legend: {
            layout: 'vertical',
            align: 'left',
            x: 120,
            verticalAlign: 'top',
            y: 100,
            floating: true,
            backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || '#FFFFFF'
        },
        series: [
            {
                name: '2014',
                type: 'column',
                yAxis: 0,
                data: series_2014,
                tooltip: {
                    valueSuffix: ' kW'
                }

            },
            {
                name: '2013',
                type: 'line',
                yAxis: 0,
                data: series_2013,
                tooltip: {
                    valueSuffix: ' kW'
                }
            }
        ]
    });
});<commit_msg>units for chart<commit_after>$(function () {
    $('#monthly-overview-chart').highcharts({
        chart: {
            zoomType: 'xy'
        },
        title: {
            text: 'Energy Production for 2014'
        },
        colors: ['#428BCA', '#153E7E', '#B4C7DA', '#24CBE5', '#64E572', '#FF9655', '#FFF263', '#6AF9C4'],
        xAxis: [
            {
                type: 'datetime',
                dateTimeLabelFormats: { // don't display the dummy year
                    month: '%e. %b',
                    year: '%b'
                }
            }
        ],
        yAxis: [
            { // Primary yAxis
                labels: {
                    format: '{value} kWh',
                    style: {
                        color: Highcharts.getOptions().colors[1]
                    }
                },
                title: {
                    text: 'Energy',
                    style: {
                        color: Highcharts.getOptions().colors[1]
                    }
                }
            }
        ],
        tooltip: {
            shared: true,
            headerFormat: '{series.name}
',
            pointFormat: '{point.x: %b}: {point.y:.2f} kWh'
        },
        legend: {
            layout: 'vertical',
            align: 'left',
            x: 120,
            verticalAlign: 'top',
            y: 100,
            floating: true,
            backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || '#FFFFFF'
        },
        series: [
            {
                name: '2014',
                type: 'column',
                yAxis: 0,
                data: series_2014,
                tooltip: {
                    valueSuffix: ' kWh'
                }

            },
            {
                name: '2013',
                type: 'line',
                yAxis: 0,
                data: series_2013,
                tooltip: {
                    valueSuffix: ' kWh'
                }
            }
        ]
    });
});<|endoftext|>


<commit_before>import {mat4} from 'gl-matrix';

export default class Renderer {

  constructor(gl, width = 0, height = 0) {
    this.gl = gl;

    this.setSize(width, height);

    this.pMatrix = mat4.create();

    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    gl.enable(gl.DEPTH_TEST);
  }

  setSize(width, height) {
    this.width = width;
    this.height = height;

    mat4.perspective(45, width / height, 0.1, 100.0, this.pMatrix);
  }

  render(object) {
    const gl = this.gl;

    gl.viewport(0, 0, this.width, this.height);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

    const program = object.material.getProgram();
    gl.bindBuffer(gl.ARRAY_BUFFER, object.geometry.vertexPositionBuffer);
    gl.vertexAttribPointer(program.vertexPositionAttribute,
                           object.geometry.vertexPositionBuffer.itemSize,
                           gl.FLOAT,
                           false, // normalized
                           0,     // stride
                           0);    // offset

    // set the uniform matrices inside each vertex shader
    this.gl.uniformMatrix4fv(program.pMatrixUniform, false, this.pMatrix);
    this.gl.uniformMatrix4fv(program.mvMatrixUniform, false, object.matrix);

    gl.drawArrays(gl.TRIANGLE_STRIP, 0, object.geometry.vertexPositionBuffer.numItems);
  }
}
<commit_msg>fix line heights<commit_after>import {mat4} from 'gl-matrix';

export default class Renderer {

  constructor(gl, width = 0, height = 0) {
    this.gl = gl;

    this.setSize(width, height);

    this.pMatrix = mat4.create();

    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    gl.enable(gl.DEPTH_TEST);
  }

  setSize(width, height) {
    this.width = width;
    this.height = height;

    mat4.perspective(45, width / height, 0.1, 100.0, this.pMatrix);
  }

  render(object) {
    const gl = this.gl;

    gl.viewport(0, 0, this.width, this.height);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

    const program = object.material.getProgram();
    gl.bindBuffer(gl.ARRAY_BUFFER, object.geometry.vertexPositionBuffer);
    gl.vertexAttribPointer(program.vertexPositionAttribute,
                           object.geometry.vertexPositionBuffer.itemSize,
                           gl.FLOAT,
                           false, // normalized
                           0,     // stride
                           0);    // offset

    // set the uniform matrices inside each vertex shader
    this.gl.uniformMatrix4fv(program.pMatrixUniform, false, this.pMatrix);
    this.gl.uniformMatrix4fv(program.mvMatrixUniform, false, object.matrix);

    gl.drawArrays(gl.TRIANGLE_STRIP, 0, object.geometry.vertexPositionBuffer.numItems);
  }
}
<|endoftext|>


<commit_before>var PowerHouse = (function () {

  /**
   * A vanilla JavaScript alternative to jQuery's $(document).ready();
   *
   * @public
   * @param {function} fn - The function to be executed when the document is ready
   * @returns {function}
   */
  var ready = function (fn) {

    if (document.readyState != 'loading') {
      fn();
    } else if (document.addEventListener) {
      document.addEventListener('DOMContentLoaded', fn);
    } else {
      document.attachEvent('onreadystatechange', function() {
        if (document.readyState != 'loading') {
          fn();
        }
      });
    }

  };

  /**
   * A vanilla JavaScript alternative to jQuery's $(document).on();
   *
   * @public
   * @param {object} el - The element being targetted
   * @param {string} eventName - The name of the event
   * @param {function} callback - The callback
   */
  var addEventListener = function (el, eventName, callback) {

    if (el.addEventListener) {
      el.addEventListener(eventName, callback);
    } else {
      el.attachEvent('on' + eventName, function() {
        callback.call(el);
      });
    }

  };

  /**
   * A vanilla JS alternative to $().next()
   */

  var nextElementSibling = function(el) {

    do { el = el.nextSibling; } while (el && el.nodeType !== 1);
    return el;

  };

  /**
   * A vanilla JS alternative to $().each();
   */
  var forEachElement = function (selector, fn) {

    var elements = document.querySelectorAll(selector);
    for (var i = 0; i < elements.length; i++) {
      fn(elements[i], i);
    }

  };

  /**
   * A vanilla JS alternative to $().hasClass()
   */
  var hasClass = function (el, className) {

    return el.className && new RegExp('(^|\\s)' + className + '(\\s|$)').test(el.className);

  };

  /**
   * Get the contents of a file
   *
   * @public
   * @param {string} file - The url of the file
   * @param {function} callback - The name of the event
   * @returns {string}
   */
  var getFileContents = function (file, callback) {

    request = new XMLHttpRequest();
    request.open('GET', file, true);

    request.onreadystatechange = function() {
      if (this.readyState === 4) {
        if (this.status >= 200 && this.status < 400) {
          callback(this.responseText);
        }
      }
    };

    request.send();
    request = null;

  };

  /**
   * A vanilla JS alternative to $().insertAfter()
   */
  var insertAfter = function (newNode, referenceNode) {

    referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);

  };

  /**
   * Get the positon of an element on the page
   *
   * 1. Get the enclosing rectangle.
   * 2. Calculate the page scroll. All browsers except IE<9 support `pageXOffset/pageYOffset`, and in IE when DOCTYPE is set, the scroll can be taken from documentElement(<html>), otherwise from `body` - so we take what we can.
   * 3. The document (`html` or `body`) can be shifted from left-upper corner in IE. Get the shift.
   * 4. Add scrolls to window-relative coordinates and substract the shift of `html/body` to get coordinates in the whole document.
   */

  var getOffsetRect = function (el) {
    /* 1 */
    var box = el.getBoundingClientRect()

    var body = document.body
    var docElement = document.documentElement

    /* 2 */
    var scrollTop = window.pageYOffset || docElement.scrollTop || body.scrollTop
    var scrollLeft = window.pageXOffset || docElement.scrollLeft || body.scrollLeft

    /* 3 */
    var clientTop = docElement.clientTop || body.clientTop || 0
    var clientLeft = docElement.clientLeft || body.clientLeft || 0

    /* 4 */
    var top  = box.top +  scrollTop - clientTop
    var left = box.left + scrollLeft - clientLeft

    return {
      top: Math.round(top),
      left: Math.round(left)
    }
  }

  return {
    ready : ready,
    addEventListener : addEventListener,
    forEachElement : forEachElement,
    hasClass : hasClass,
    nextElementSibling : nextElementSibling,
    getFileContents : getFileContents,
    insertAfter: insertAfter,
    getOffsetRect: getOffsetRect
  };

})();
<commit_msg>Added semicolons<commit_after>var PowerHouse = (function () {

  /**
   * A vanilla JavaScript alternative to jQuery's $(document).ready();
   *
   * @public
   * @param {function} fn - The function to be executed when the document is ready
   * @returns {function}
   */
  var ready = function (fn) {

    if (document.readyState != 'loading') {
      fn();
    } else if (document.addEventListener) {
      document.addEventListener('DOMContentLoaded', fn);
    } else {
      document.attachEvent('onreadystatechange', function() {
        if (document.readyState != 'loading') {
          fn();
        }
      });
    }

  };

  /**
   * A vanilla JavaScript alternative to jQuery's $(document).on();
   *
   * @public
   * @param {object} el - The element being targetted
   * @param {string} eventName - The name of the event
   * @param {function} callback - The callback
   */
  var addEventListener = function (el, eventName, callback) {

    if (el.addEventListener) {
      el.addEventListener(eventName, callback);
    } else {
      el.attachEvent('on' + eventName, function() {
        callback.call(el);
      });
    }

  };

  /**
   * A vanilla JS alternative to $().next()
   */

  var nextElementSibling = function(el) {

    do { el = el.nextSibling; } while (el && el.nodeType !== 1);
    return el;

  };

  /**
   * A vanilla JS alternative to $().each();
   */
  var forEachElement = function (selector, fn) {

    var elements = document.querySelectorAll(selector);
    for (var i = 0; i < elements.length; i++) {
      fn(elements[i], i);
    }

  };

  /**
   * A vanilla JS alternative to $().hasClass()
   */
  var hasClass = function (el, className) {

    return el.className && new RegExp('(^|\\s)' + className + '(\\s|$)').test(el.className);

  };

  /**
   * Get the contents of a file
   *
   * @public
   * @param {string} file - The url of the file
   * @param {function} callback - The name of the event
   * @returns {string}
   */
  var getFileContents = function (file, callback) {

    request = new XMLHttpRequest();
    request.open('GET', file, true);

    request.onreadystatechange = function() {
      if (this.readyState === 4) {
        if (this.status >= 200 && this.status < 400) {
          callback(this.responseText);
        }
      }
    };

    request.send();
    request = null;

  };

  /**
   * A vanilla JS alternative to $().insertAfter()
   */
  var insertAfter = function (newNode, referenceNode) {

    referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);

  };

  /**
   * Get the positon of an element on the page
   *
   * 1. Get the enclosing rectangle.
   * 2. Calculate the page scroll. All browsers except IE<9 support `pageXOffset/pageYOffset`, and in IE when DOCTYPE is set, the scroll can be taken from documentElement(<html>), otherwise from `body` - so we take what we can.
   * 3. The document (`html` or `body`) can be shifted from left-upper corner in IE. Get the shift.
   * 4. Add scrolls to window-relative coordinates and substract the shift of `html/body` to get coordinates in the whole document.
   */

  var getOffsetRect = function (el) {
    /* 1 */
    var box = el.getBoundingClientRect();

    var body = document.body;
    var docElement = document.documentElement;

    /* 2 */
    var scrollTop = window.pageYOffset || docElement.scrollTop || body.scrollTop;
    var scrollLeft = window.pageXOffset || docElement.scrollLeft || body.scrollLeft;

    /* 3 */
    var clientTop = docElement.clientTop || body.clientTop || 0;
    var clientLeft = docElement.clientLeft || body.clientLeft || 0;

    /* 4 */
    var top  = box.top +  scrollTop - clientTop;
    var left = box.left + scrollLeft - clientLeft;

    return {
      top: Math.round(top),
      left: Math.round(left)
    }
  }

  return {
    ready : ready,
    addEventListener : addEventListener,
    forEachElement : forEachElement,
    hasClass : hasClass,
    nextElementSibling : nextElementSibling,
    getFileContents : getFileContents,
    insertAfter: insertAfter,
    getOffsetRect: getOffsetRect
  };

})();
<|endoftext|>


<commit_before>'use strict';

/* Simplified implementation of DOM2 EventTarget.
 *   http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget
 */

function EventTarget() {
  this._listeners = {};
}

EventTarget.prototype.addEventListener = function (eventType, listener) {
  if (!(eventType in this._listeners)) {
    this._listeners[eventType] = [];
  }
  var arr = this._listeners[eventType];
  if (arr.indexOf(listener) === -1) {
    // Make a copy so as not to interfere with a current dispatchEvent.
    arr = arr.concat([listener]);
  }
  this._listeners[eventType] = arr;
  return;
};

EventTarget.prototype.removeEventListener = function (eventType, listener) {
  if (!(eventType in this._listeners)) {
    return;
  }
  var arr = this._listeners[eventType];
  var idx = arr.indexOf(listener);
  if (idx !== -1) {
    if (arr.length > 1) {
      // Make a copy so as not to interfere with a current dispatchEvent.
      this._listeners[eventType] = arr.slice(0, idx).concat(arr.slice(idx + 1));
    } else {
      delete this._listeners[eventType];
    }
    return;
  }
  return;
};

EventTarget.prototype.dispatchEvent = function (event) {
  var t = event.type;
  var args = Array.prototype.slice.call(arguments, 0);
  // TODO: This doesn't match the real behavior; per spec, onfoo get
  // their place in line from the /first/ time they're set from
  // non-null. Although WebKit bumps it to the end every time it's
  // set.
  if (this['on' + t]) {
    this['on' + t].apply(this, args);
  }
  if (t in this._listeners) {
    // Grab a reference to the listeners list. removeEventListener may alter the list.
    var listeners = this._listeners[t];
    for (var i = 0; i < listeners.length; i++) {
      listeners[i].apply(this, args);
    }
  }
};

module.exports = EventTarget;
<commit_msg>Test issue comment<commit_after>'use strict';

/* Simplified implementation of DOM2 EventTarget.
 *   http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget
 */

function EventTarget() {
  this._listeners = {};
}

EventTarget.prototype.addEventListener = function (eventType, listener) {
  if (!(eventType in this._listeners)) {
    this._listeners[eventType] = [];
  }
  var arr = this._listeners[eventType];
  // sockjs/sockjs-client#4
  if (arr.indexOf(listener) === -1) {
    // Make a copy so as not to interfere with a current dispatchEvent.
    arr = arr.concat([listener]);
  }
  this._listeners[eventType] = arr;
  return;
};

EventTarget.prototype.removeEventListener = function (eventType, listener) {
  if (!(eventType in this._listeners)) {
    return;
  }
  var arr = this._listeners[eventType];
  var idx = arr.indexOf(listener);
  if (idx !== -1) {
    if (arr.length > 1) {
      // Make a copy so as not to interfere with a current dispatchEvent.
      this._listeners[eventType] = arr.slice(0, idx).concat(arr.slice(idx + 1));
    } else {
      delete this._listeners[eventType];
    }
    return;
  }
  return;
};

EventTarget.prototype.dispatchEvent = function (event) {
  var t = event.type;
  var args = Array.prototype.slice.call(arguments, 0);
  // TODO: This doesn't match the real behavior; per spec, onfoo get
  // their place in line from the /first/ time they're set from
  // non-null. Although WebKit bumps it to the end every time it's
  // set.
  if (this['on' + t]) {
    this['on' + t].apply(this, args);
  }
  if (t in this._listeners) {
    // Grab a reference to the listeners list. removeEventListener may alter the list.
    var listeners = this._listeners[t];
    for (var i = 0; i < listeners.length; i++) {
      listeners[i].apply(this, args);
    }
  }
};

module.exports = EventTarget;
<|endoftext|>