<commit_before>var derby = require('derby')
  , app = derby.createApp(module)
  , get = app.get
  , view = app.view
  , ready = app.ready
  , start = +new Date()

derby.use(require('../../ui'))

//Example query motif to get the last time a bin was emptied
//THIS ISN'T A WORKING EXAMPLE AT THIS POINT. JUST ILLUSTRATING HOW WE MIGHT BUILD OUR QUERIES

/*store.query.expose('list-floor', 'lastEmptied', function (bin) { //Expose query syntax: .expose(namespace, motifName, fn)
	return this
		.where('binID').equals(bin) //Get only the bin you're interested in
		.sort('emptyDates','desc') //Sort the results in descending order by the dates it was emptied
		.limit(1); //Only get the last time it was emptied
});*/

//We could now call this query in the app by doing something like this:
/*var lastEmptied = model.query('list-floor').lastEmptied(1234);*/

// ROUTES //

// Derby routes can be rendered on the client and the server
get('/', function(page, model, params) {
  page.render('home', {page_name: 'Get Started'})
})

// A route for the building select view
get('/buildings', function(page, model, params) {
    model.subscribe('bins.*', function(err, builds) {
        model.ref('_buildings', builds);
        console.log('about to print buildings');
        model.set('buildIds', ['Jones', 'WSC']);
        console.log('trying refList stuff');
        console.log(model.get('_buildings'));
        model.refList('_buildingIds', 'bins', 'buildIds');
        console.log(model.get('_buildingIds'));
        page.render('list-building', { bins: bins, page_name: 'Buildings'} );
    });
})

// A route for the floors/locations in a building
get('/buildings-:building?', function(page, model, params) {
    var building = params.building;
    building || (building = 'null');

    var buildingBins = null;
    for (build in bins){
        if (bins[build]['title']==building) {
            buildingBins = bins[build];
        }
    }

    page.render('list-floor',
        { building: buildingBins,
            page_name: 'Locations for '+buildingBins['title']} );
})

// View the bins at a location
get('/buildings-:building?/floor-:floor?/location-:loc?',
        function(page, model, params) {
    var buildName = params.building;
    buildName || (buildName = 'null');

    var floorName = params.floor;
    floorName || (floorName = 'null');

    var locName = params.loc;
    locName || (locName = 'null');

    var loc = null;
    for (build in bins){
        // for every building
        if (bins[build]['title']==buildName) {
            for (fl in bins[build]['floors']) {
                // for every floor
                if (bins[build]['floors'][fl]['title'] == floorName) {
                    for(ll in bins[build]['floors'][fl]['locations']) {
                        // for every location
                        if(bins[build]['floors'][fl]['locations'][ll]['title']
                            == locName) {
                            loc = bins[build]['floors'][fl]['locations'][ll];
                            break;
                        }
                    }
                }
            }
        }
    }

    // TODO: Need to fix this shit to use a database for bin names and such
    // Here comes the magic for our persistence and data sharing
    var pathName = buildName +'.'+ floorName +'.'+ loc['title'];
    model.subscribe('bins.' + pathName, function(err, curLoc){
        // Need underscore to keep it private for ref
    	model.ref('_bins', curLoc);

        // Now define the default bin states. Bins take on values of 'not-full',
        // 'full', and 'emptied'.
        var basicBins = loc['bins'].map(function(binName){
            var theTime = new Date();
            return {'bName': binName,
                    'activity':[{'time': theTime, 'activity': 'not-full'}]};
        });

        // Sets the value if it hasn't already been defined (should only happen on
        // first run)
        basicBins.forEach(function(oneBin) {
            curLoc.setNull(oneBin['bName'], oneBin['activity']);
        });

        page.render('list-bins',
                    { buildingName : buildName,
                      floorName : floorName,
                      locationName: loc['title'],
                      binNames: loc['bins'],
                      page_name: 'bins for '+buildName+' in '+floorName+' at '+
                        loc['title']});
	});
})

// CONTROLLER FUNCTIONS //

ready(function(model) {

    // "emptied"s a bin by adding a new event to the activity history
    exports.emptiedBin = function(e, el, next) {
        // Grab context nearest to this bin
        bin = model.at(el);
        // Add a new entry for the now emptied bin
        var theTime = new Date();
        bin.unshift({'time': theTime, 'activity': 'emptied'});
    }

    // "full"s a bin by adding a new event to the activity history
    exports.fullBin= function(e, el, next) {
        // Grab context nearest to this bin
        bin = model.at(el);
        // Add a new entry for the now emptied bin
        var theTime = new Date();
        bin.unshift({'time': theTime, 'activity': 'full'});
    }

    // "not-full"s a bin by adding a new event to the activity history
    exports.notFullBin= function(e, el, next) {
        // Grab context nearest to this bin
        bin = model.at(el);
        // Add a new entry for the now emptied bin
        var theTime = new Date();
        bin.unshift({'time': theTime, 'activity': 'not-full'});
    }

    // EXAMPLES FROM OLD CODE
//  var timer
//
//  // Functions on the app can be bound to DOM events using the "x-bind"
//  // attribute in a template.
//  this.stop = function() {
//    // Any path name that starts with an underscore is private to the current
//    // client. Nothing set under a private path is synced back to the server.
//    model.set('_stopped', true)
//    clearInterval(timer)
//  }
//
//  this.start = function() {
//    model.set('_stopped', false)
//    timer = setInterval(function() {
//      model.set('_timer', (((+new Date()) - start) / 1000).toFixed(1))
//    }, 100)
//  }
//  this.start()
//
})

// LOGIC CODE //

bins = [{'title': 'WSC',
                floors: [{'title':'Basement', locations:[
                            {'title':'Shipping-Receiving', bins:[
                                'Toter','Glass','Cardboard']},
                            {'title':'Mail Room', bins:[
                                'Toter', 'Cardboard']},
                            {'title':'Cellar', bins:[
                                'Toter 1', 'Toter 2']}]},
                         {'title':'1st Floor', locations:[
                             {'title':'Diversions', bins:[
                                 'Toter']}]},
                         {'title':'2nd Floor', locations:[
                             {'title':'Elevator', bins:[
                                 'Toter', 'Glass']},
                             {'title':'ASUPS', bins:[
                                 'Toter']}]}]},
        {'title': 'Jones',
                  floors: [{'title':'Basement', locations:[
                              {'title':'Recycling Station', bins:[
                                  'Toter 1', 'Toter 2', 'Toter 3',
                                  'Toter 4', 'Cardboard', 'Glass', ]}]},
                           {'title':'1st Floor', locations:[
                               {'title':'Staff Kitchennette', bins:[
                                   'Glass']}]},
                           {'title':'2nd Floor', locations:[
                               {'title':'Hallway-North', bins:[
                                   'Toter 1', 'Toter 2']},
                               {'title':'Hallway-South', bins:[
                                   'Toter 1', 'Glass']}]}]}
]
<commit_msg>Trying different ways to get at the refList.<commit_after>var derby = require('derby')
  , app = derby.createApp(module)
  , get = app.get
  , view = app.view
  , ready = app.ready
  , start = +new Date()

derby.use(require('../../ui'))

//Example query motif to get the last time a bin was emptied
//THIS ISN'T A WORKING EXAMPLE AT THIS POINT. JUST ILLUSTRATING HOW WE MIGHT BUILD OUR QUERIES

/*store.query.expose('list-floor', 'lastEmptied', function (bin) { //Expose query syntax: .expose(namespace, motifName, fn)
	return this
		.where('binID').equals(bin) //Get only the bin you're interested in
		.sort('emptyDates','desc') //Sort the results in descending order by the dates it was emptied
		.limit(1); //Only get the last time it was emptied
});*/

//We could now call this query in the app by doing something like this:
/*var lastEmptied = model.query('list-floor').lastEmptied(1234);*/

// ROUTES //

// Derby routes can be rendered on the client and the server
get('/', function(page, model, params) {
  page.render('home', {page_name: 'Get Started'})
})

// A route for the building select view
get('/buildings', function(page, model, params) {
    model.subscribe('bins.*', function(err, builds) {
        model.ref('_buildings', builds);
        console.log('about to print buildings');
        model.set('buildIds', ['Jones', 'WSC']);
        console.log('trying refList stuff');
        console.log(model.get('_buildings'));
        model.refList('_buildingIds', '_buildings', 'buildIds');
        console.log(model.get('_buildingIds'));
        page.render('list-building', { bins: bins, page_name: 'Buildings'} );
    });
})

// A route for the floors/locations in a building
get('/buildings-:building?', function(page, model, params) {
    var building = params.building;
    building || (building = 'null');

    var buildingBins = null;
    for (build in bins){
        if (bins[build]['title']==building) {
            buildingBins = bins[build];
        }
    }

    page.render('list-floor',
        { building: buildingBins,
            page_name: 'Locations for '+buildingBins['title']} );
})

// View the bins at a location
get('/buildings-:building?/floor-:floor?/location-:loc?',
        function(page, model, params) {
    var buildName = params.building;
    buildName || (buildName = 'null');

    var floorName = params.floor;
    floorName || (floorName = 'null');

    var locName = params.loc;
    locName || (locName = 'null');

    var loc = null;
    for (build in bins){
        // for every building
        if (bins[build]['title']==buildName) {
            for (fl in bins[build]['floors']) {
                // for every floor
                if (bins[build]['floors'][fl]['title'] == floorName) {
                    for(ll in bins[build]['floors'][fl]['locations']) {
                        // for every location
                        if(bins[build]['floors'][fl]['locations'][ll]['title']
                            == locName) {
                            loc = bins[build]['floors'][fl]['locations'][ll];
                            break;
                        }
                    }
                }
            }
        }
    }

    // TODO: Need to fix this shit to use a database for bin names and such
    // Here comes the magic for our persistence and data sharing
    var pathName = buildName +'.'+ floorName +'.'+ loc['title'];
    model.subscribe('bins.' + pathName, function(err, curLoc){
        // Need underscore to keep it private for ref
    	model.ref('_bins', curLoc);

        // Now define the default bin states. Bins take on values of 'not-full',
        // 'full', and 'emptied'.
        var basicBins = loc['bins'].map(function(binName){
            var theTime = new Date();
            return {'bName': binName,
                    'activity':[{'time': theTime, 'activity': 'not-full'}]};
        });

        // Sets the value if it hasn't already been defined (should only happen on
        // first run)
        basicBins.forEach(function(oneBin) {
            curLoc.setNull(oneBin['bName'], oneBin['activity']);
        });

        page.render('list-bins',
                    { buildingName : buildName,
                      floorName : floorName,
                      locationName: loc['title'],
                      binNames: loc['bins'],
                      page_name: 'bins for '+buildName+' in '+floorName+' at '+
                        loc['title']});
	});
})

// CONTROLLER FUNCTIONS //

ready(function(model) {

    // "emptied"s a bin by adding a new event to the activity history
    exports.emptiedBin = function(e, el, next) {
        // Grab context nearest to this bin
        bin = model.at(el);
        // Add a new entry for the now emptied bin
        var theTime = new Date();
        bin.unshift({'time': theTime, 'activity': 'emptied'});
    }

    // "full"s a bin by adding a new event to the activity history
    exports.fullBin= function(e, el, next) {
        // Grab context nearest to this bin
        bin = model.at(el);
        // Add a new entry for the now emptied bin
        var theTime = new Date();
        bin.unshift({'time': theTime, 'activity': 'full'});
    }

    // "not-full"s a bin by adding a new event to the activity history
    exports.notFullBin= function(e, el, next) {
        // Grab context nearest to this bin
        bin = model.at(el);
        // Add a new entry for the now emptied bin
        var theTime = new Date();
        bin.unshift({'time': theTime, 'activity': 'not-full'});
    }

    // EXAMPLES FROM OLD CODE
//  var timer
//
//  // Functions on the app can be bound to DOM events using the "x-bind"
//  // attribute in a template.
//  this.stop = function() {
//    // Any path name that starts with an underscore is private to the current
//    // client. Nothing set under a private path is synced back to the server.
//    model.set('_stopped', true)
//    clearInterval(timer)
//  }
//
//  this.start = function() {
//    model.set('_stopped', false)
//    timer = setInterval(function() {
//      model.set('_timer', (((+new Date()) - start) / 1000).toFixed(1))
//    }, 100)
//  }
//  this.start()
//
})

// LOGIC CODE //

bins = [{'title': 'WSC',
                floors: [{'title':'Basement', locations:[
                            {'title':'Shipping-Receiving', bins:[
                                'Toter','Glass','Cardboard']},
                            {'title':'Mail Room', bins:[
                                'Toter', 'Cardboard']},
                            {'title':'Cellar', bins:[
                                'Toter 1', 'Toter 2']}]},
                         {'title':'1st Floor', locations:[
                             {'title':'Diversions', bins:[
                                 'Toter']}]},
                         {'title':'2nd Floor', locations:[
                             {'title':'Elevator', bins:[
                                 'Toter', 'Glass']},
                             {'title':'ASUPS', bins:[
                                 'Toter']}]}]},
        {'title': 'Jones',
                  floors: [{'title':'Basement', locations:[
                              {'title':'Recycling Station', bins:[
                                  'Toter 1', 'Toter 2', 'Toter 3',
                                  'Toter 4', 'Cardboard', 'Glass', ]}]},
                           {'title':'1st Floor', locations:[
                               {'title':'Staff Kitchennette', bins:[
                                   'Glass']}]},
                           {'title':'2nd Floor', locations:[
                               {'title':'Hallway-North', bins:[
                                   'Toter 1', 'Toter 2']},
                               {'title':'Hallway-South', bins:[
                                   'Toter 1', 'Glass']}]}]}
]
<|endoftext|>


<commit_before>import Ember from 'ember';
import StyleObserver from './observers/style';
import YesNoStyleObserver from './observers/yesno';

export default Ember.Mixin.create({

	concatenatedProperties: ['styleBindings'],

	_styleObservers: null,

	_calculatedStyle: null,

	_regex: /^(([^\?:]+):)?([a-z0-9_\.-]+)(\[([a-z%]+)\])?(\?([a-z0-9_\.\-]*):([a-z0-9_\.\-]*))?$/i,

	doInit: Ember.on('didInsertElement', function() {
		this._refreshBindings();
	}),

	styleBindingsChanged: Ember.observer('styleBindings', function() {
		this._refreshBindings();
	}),

	doCleanup: Ember.on('willDestroyElement', function() {
		var observers = Ember.get(this, '_styleObservers') || {};
		// remove all bindings
		for(var property in observers) {
			if (observers.hasOwnProperty(property)) {
				observers[property].stop();
				delete observers[property];
			}
		}
		Ember.set(this, '_styleObservers', {});
	}),

	_writeStyle: Ember.observer('_calculatedStyle', function() {
		let elements = this.$();
		if (elements && elements.length > 0)
		{
			try
			{
				elements[0].setAttribute('style', Ember.get(this, '_calculatedStyle'));
			}
			catch(err)
			{
				elements.attr('style', Ember.get(this, '_calculatedStyle'));
			}
		}
	}),

	_refreshStyle() {
		var style = "";
		var observers = Ember.get(this, '_styleObservers');
		for (var key in observers)
		{
			if (key === "style" || key.indexOf(":style?") > -1 || (key.indexOf(":style") > -1 && key.indexOf(":style") === key.length-6)) {
				style = Ember.get(observers[key], 'styleChunk');
				// trim off prefix and suffix
				style = style.substring(6, style.length-1);
				break;
			}
			else
			{
				style += Ember.get(observers[key], 'styleChunk');
			}
		}
		Ember.set(this, '_calculatedStyle', style);
	},

	_refreshBindings: function() {

		var styleBindings = this.get('styleBindings') || [];

		var observers = this.get('_styleObservers') || {};
		var foundBindings = {};

		// iterate the style bindings
		for (var i=0; i< styleBindings.length; i++) {
			var binding = styleBindings[i];

			// add the observer if it's not there already
			if (!observers[binding])
			{
				observers[binding] = this._createObserver(binding);
			}
			foundBindings[binding] = true;
		}

		// look for removed bindings
		for(var property in observers) {
			if (observers.hasOwnProperty(property)) {
				if (!foundBindings[property])
				{
					observers[property].stop();
					delete observers[property];
				}
			}
		}

		this.set('_styleObservers', observers);
		this._refreshStyle();
	},

	_createObserver: function(binding) {
		var match = binding.match(this.get('_regex'));
		if (match) {
			var cssProp = match[3];
			var emberProp = match[2] || Ember.String.camelize(cssProp);
			var unit = match[5];
			var type = StyleObserver;
			var properties = {
				target: this,
				property: emberProp,
				cssName: cssProp,
				unit: unit
			};
			if (match[6]) {
				type = YesNoStyleObserver;
				properties.yesNo = {
					yes: match[7],
					no: match[8]
				};
			}
			return type.create(properties);
		}
	}

});
<commit_msg>[Fix] Add DOM manipulation to requestAnimationFrame<commit_after>import Ember from 'ember';
import StyleObserver from './observers/style';
import YesNoStyleObserver from './observers/yesno';

export default Ember.Mixin.create({

	concatenatedProperties: ['styleBindings'],

	_styleObservers: null,

	_calculatedStyle: null,

	_regex: /^(([^\?:]+):)?([a-z0-9_\.-]+)(\[([a-z%]+)\])?(\?([a-z0-9_\.\-]*):([a-z0-9_\.\-]*))?$/i,

	doInit: Ember.on('didInsertElement', function() {
		this._refreshBindings();
	}),

	styleBindingsChanged: Ember.observer('styleBindings', function() {
		this._refreshBindings();
	}),

	doCleanup: Ember.on('willDestroyElement', function() {
		var observers = Ember.get(this, '_styleObservers') || {};
		// remove all bindings
		for(var property in observers) {
			if (observers.hasOwnProperty(property)) {
				observers[property].stop();
				delete observers[property];
			}
		}
		Ember.set(this, '_styleObservers', {});
	}),

	_writeStyle: Ember.observer('_calculatedStyle', function() {
		let elements = this.$();
		if (elements && elements.length > 0)
		{
			try
			{
				let _calculatedStyle = Ember.get(this, '_calculatedStyle');
				requestAnimationFrame(() =>
					elements[0].setAttribute('style', _calculatedStyle)
				);
			}
			catch(err)
			{
				elements.attr('style', _calculatedStyle);
			}
		}
	}),

	_refreshStyle() {
		var style = "";
		var observers = Ember.get(this, '_styleObservers');
		for (var key in observers)
		{
			if (key === "style" || key.indexOf(":style?") > -1 || (key.indexOf(":style") > -1 && key.indexOf(":style") === key.length-6)) {
				style = Ember.get(observers[key], 'styleChunk');
				// trim off prefix and suffix
				style = style.substring(6, style.length-1);
				break;
			}
			else
			{
				style += Ember.get(observers[key], 'styleChunk');
			}
		}
		Ember.set(this, '_calculatedStyle', style);
	},

	_refreshBindings: function() {

		var styleBindings = this.get('styleBindings') || [];

		var observers = this.get('_styleObservers') || {};
		var foundBindings = {};

		// iterate the style bindings
		for (var i=0; i< styleBindings.length; i++) {
			var binding = styleBindings[i];

			// add the observer if it's not there already
			if (!observers[binding])
			{
				observers[binding] = this._createObserver(binding);
			}
			foundBindings[binding] = true;
		}

		// look for removed bindings
		for(var property in observers) {
			if (observers.hasOwnProperty(property)) {
				if (!foundBindings[property])
				{
					observers[property].stop();
					delete observers[property];
				}
			}
		}

		this.set('_styleObservers', observers);
		this._refreshStyle();
	},

	_createObserver: function(binding) {
		var match = binding.match(this.get('_regex'));
		if (match) {
			var cssProp = match[3];
			var emberProp = match[2] || Ember.String.camelize(cssProp);
			var unit = match[5];
			var type = StyleObserver;
			var properties = {
				target: this,
				property: emberProp,
				cssName: cssProp,
				unit: unit
			};
			if (match[6]) {
				type = YesNoStyleObserver;
				properties.yesNo = {
					yes: match[7],
					no: match[8]
				};
			}
			return type.create(properties);
		}
	}

});
<|endoftext|>


<commit_before>module.exports = {
  lang: 'en-US',
  title: 'Vuex',
  description: 'Centralized State Management for Vue.js',

  locales: {
    '/': {
      lang: 'en-US',
      title: 'Vuex',
      description: 'Centralized State Management for Vue.js'
    },
    '/ptbr/': {
      lang: 'pt-BR',
      title: 'Vuex',
      description: 'Gerenciamento de Estado Centralizado para Vue.js'
    }
  },

  head: [
    ['link', { rel: 'icon', href: `/logo.png` }],
    ['link', { rel: 'apple-touch-icon', href: `/icons/apple-touch-icon-152x152.png` }],
    ['link', { rel: 'mask-icon', href: '/icons/safari-pinned-tab.svg', color: '#3eaf7c' }],
    ['meta', { name: 'msapplication-TileImage', content: '/icons/msapplication-icon-144x144.png' }],
  ],

  themeConfig: {
    repo: 'vuejs/vuex',
    docsDir: 'docs',
    docsBranch: '4.0',

    editLinks: true,

    locales: {
      '/': {
        editLinkText: 'Edit this page on GitHub',

        nav: [
          { text: 'Guide', link: '/guide/' },
          { text: 'API Reference', link: '/api/' },
          { text: 'Release Notes', link: 'https://github.com/vuejs/vuex/releases' },
          {
            text: 'v4.x',
            items: [
              { text: 'v3.x', link: 'https://vuex.vuejs.org/' }
            ]
          }
        ],

        sidebar: [
          {
            text: 'Introduction',
            children: [
              { text: 'What is Vuex?', link: '/' },
              { text: 'Installation', link: '/installation' },
              { text: 'Getting Started', link: '/guide/' }
            ]
          },
          {
            text: 'Core Concepts',
            children: [
              { text: 'State', link: '/guide/state' },
              { text: 'Getters', link: '/guide/getters' },
              { text: 'Mutations', link: '/guide/mutations' },
              { text: 'Actions', link: '/guide/actions' },
              { text: 'Modules', link: '/guide/modules' }
            ]
          },
          {
            text: 'Advanced',
            children: [
              { text: 'Application Structure', link: '/guide/structure' },
              { text: 'Composition API', link: '/guide/composition-api' },
              { text: 'Plugins', link: '/guide/plugins' },
              { text: 'Strict Mode', link: '/guide/strict' },
              { text: 'Form Handling', link: '/guide/forms' },
              { text: 'Testing', link: '/guide/testing' },
              { text: 'Hot Reloading', link: '/guide/hot-reload' },
              { text: 'TypeScript Support', link: '/guide/typescript-support' },
            ]
          },
          {
            text: 'Migration Guide',
            children: [
              { text: 'Migrating to 4.0 from 3.x', link: '/guide/migrating-to-4-0-from-3-x' }
            ]
          }
        ]
      },
      '/ptbr/': {
        nav: [
          { text: 'Guia', link: '/ptbr/guide/' },
          { text: 'Referência da API', link: '/ptbr/api/' },
          { text: 'Notas de Lançamento', link: 'https://github.com/vuejs/vuex/releases' },
          {
            text: 'v4.x',
            items: [
              { text: 'v3.x', link: 'https://vuex.vuejs.org/ptbr/' }
            ]
          }
        ],
        sidebar: [
          {
            text: 'Introdução',
            children: [
              { text: 'O que é Vuex?', link: '/ptbr/' },
              { text: 'Instalação', link: '/ptbr/installation' },
              { text: 'Começando', link: '/ptbr/guide/' }
            ]
          },
          {
            text: 'Conceitos Básicos',
            children: [
              { text: 'Estado', link: '/ptbr/guide/state' },
              { text: 'Getters', link: '/ptbr/guide/getters' },
              { text: 'Mutações', link: '/ptbr/guide/mutations' },
              { text: 'Ações', link: '/ptbr/guide/actions' },
              { text: 'Módulos', link: '/ptbr/guide/modules' }
            ]
          },
          {
            text: 'Avançado',
            children: [
              { text: 'Estrutura da Aplicação', link: '/ptbr/guide/structure' },
              { text: 'Composition API', link: '/ptbr/guide/composition-api' },
              { text: 'Plugins', link: '/ptbr/guide/plugins' },
              { text: 'Modo Strict', link: '/ptbr/guide/strict' },
              { text: 'Manipulação de Formulários', link: '/ptbr/guide/forms' },
              { text: 'Testando', link: '/ptbr/guide/testing' },
              { text: 'Hot Reloading', link: '/ptbr/guide/hot-reload' },
              { text: 'Suporte ao TypeScript', link: '/ptbr/guide/typescript-support' },
            ]
          },
          {
            text: 'Guia de Migração',
            children: [
              { text: 'Migrando do 3.x para 4.0', link: '/ptbr/guide/migrating-to-4-0-from-3-x' }
            ]
          }
        ]
      }
    }
  }
}
<commit_msg>docs: add configs for locale selecter<commit_after>module.exports = {
  lang: 'en-US',
  title: 'Vuex',
  description: 'Centralized State Management for Vue.js',

  locales: {
    '/': {
      lang: 'en-US',
      title: 'Vuex',
      description: 'Centralized State Management for Vue.js'
    },
    '/ptbr/': {
      lang: 'pt-BR',
      title: 'Vuex',
      description: 'Gerenciamento de Estado Centralizado para Vue.js'
    }
  },

  head: [
    ['link', { rel: 'icon', href: `/logo.png` }],
    ['link', { rel: 'apple-touch-icon', href: `/icons/apple-touch-icon-152x152.png` }],
    ['link', { rel: 'mask-icon', href: '/icons/safari-pinned-tab.svg', color: '#3eaf7c' }],
    ['meta', { name: 'msapplication-TileImage', content: '/icons/msapplication-icon-144x144.png' }],
  ],

  themeConfig: {
    repo: 'vuejs/vuex',
    docsDir: 'docs',
    docsBranch: '4.0',

    editLinks: true,

    locales: {
      '/': {
        label: 'English',
        selectText: 'Languages',
        editLinkText: 'Edit this page on GitHub',

        nav: [
          { text: 'Guide', link: '/guide/' },
          { text: 'API Reference', link: '/api/' },
          { text: 'Release Notes', link: 'https://github.com/vuejs/vuex/releases' },
          {
            text: 'v4.x',
            items: [
              { text: 'v3.x', link: 'https://vuex.vuejs.org/' }
            ]
          }
        ],

        sidebar: [
          {
            text: 'Introduction',
            children: [
              { text: 'What is Vuex?', link: '/' },
              { text: 'Installation', link: '/installation' },
              { text: 'Getting Started', link: '/guide/' }
            ]
          },
          {
            text: 'Core Concepts',
            children: [
              { text: 'State', link: '/guide/state' },
              { text: 'Getters', link: '/guide/getters' },
              { text: 'Mutations', link: '/guide/mutations' },
              { text: 'Actions', link: '/guide/actions' },
              { text: 'Modules', link: '/guide/modules' }
            ]
          },
          {
            text: 'Advanced',
            children: [
              { text: 'Application Structure', link: '/guide/structure' },
              { text: 'Composition API', link: '/guide/composition-api' },
              { text: 'Plugins', link: '/guide/plugins' },
              { text: 'Strict Mode', link: '/guide/strict' },
              { text: 'Form Handling', link: '/guide/forms' },
              { text: 'Testing', link: '/guide/testing' },
              { text: 'Hot Reloading', link: '/guide/hot-reload' },
              { text: 'TypeScript Support', link: '/guide/typescript-support' },
            ]
          },
          {
            text: 'Migration Guide',
            children: [
              { text: 'Migrating to 4.0 from 3.x', link: '/guide/migrating-to-4-0-from-3-x' }
            ]
          }
        ]
      },

      '/ptbr/': {
        label: 'Português',
        selectText: 'Idiomas',
        editLinkText: 'Edite esta página no GitHub',

        nav: [
          { text: 'Guia', link: '/ptbr/guide/' },
          { text: 'Referência da API', link: '/ptbr/api/' },
          { text: 'Notas de Lançamento', link: 'https://github.com/vuejs/vuex/releases' },
          {
            text: 'v4.x',
            items: [
              { text: 'v3.x', link: 'https://vuex.vuejs.org/ptbr/' }
            ]
          }
        ],

        sidebar: [
          {
            text: 'Introdução',
            children: [
              { text: 'O que é Vuex?', link: '/ptbr/' },
              { text: 'Instalação', link: '/ptbr/installation' },
              { text: 'Começando', link: '/ptbr/guide/' }
            ]
          },
          {
            text: 'Conceitos Básicos',
            children: [
              { text: 'Estado', link: '/ptbr/guide/state' },
              { text: 'Getters', link: '/ptbr/guide/getters' },
              { text: 'Mutações', link: '/ptbr/guide/mutations' },
              { text: 'Ações', link: '/ptbr/guide/actions' },
              { text: 'Módulos', link: '/ptbr/guide/modules' }
            ]
          },
          {
            text: 'Avançado',
            children: [
              { text: 'Estrutura da Aplicação', link: '/ptbr/guide/structure' },
              { text: 'Composition API', link: '/ptbr/guide/composition-api' },
              { text: 'Plugins', link: '/ptbr/guide/plugins' },
              { text: 'Modo Strict', link: '/ptbr/guide/strict' },
              { text: 'Manipulação de Formulários', link: '/ptbr/guide/forms' },
              { text: 'Testando', link: '/ptbr/guide/testing' },
              { text: 'Hot Reloading', link: '/ptbr/guide/hot-reload' },
              { text: 'Suporte ao TypeScript', link: '/ptbr/guide/typescript-support' },
            ]
          },
          {
            text: 'Guia de Migração',
            children: [
              { text: 'Migrando do 3.x para 4.0', link: '/ptbr/guide/migrating-to-4-0-from-3-x' }
            ]
          }
        ]
      }
    }
  }
}
<|endoftext|>


<commit_before>// ==UserScript==
// @id             iitc-plugin-basemap-yandex@jonatkins
// @name           IITC plugin: Yandex maps
// @category       Map Tiles
// @version        0.1.0.@@DATETIMEVERSION@@
// @namespace      https://github.com/jonatkins/ingress-intel-total-conversion
// @updateURL      @@UPDATEURL@@
// @downloadURL    @@DOWNLOADURL@@
// @description    [@@BUILDNAME@@-@@BUILDDATE@@] Add Yandex.com (Russian/Русский) map layers
// @include        https://www.ingress.com/intel*
// @include        http://www.ingress.com/intel*
// @match          https://www.ingress.com/intel*
// @match          http://www.ingress.com/intel*
// @grant          none
// ==/UserScript==

@@PLUGINSTART@@

// PLUGIN START ////////////////////////////////////////////////////////

// use own namespace for plugin
window.plugin.mapTileYandex = function() {};

window.plugin.mapTileYandex.setup = function() {
//a few options on language are available, including en-US. Oddly, the detail available on the maps varies
//depending on the language
  var yandexApiJs = '//api-maps.yandex.ru/2.0-stable/?load=package.standard&lang=ru-RU'

  load(yandexApiJs).thenRun(window.plugin.mapTileYandex.addLayer);
}

window.plugin.mapTileYandex.addLayer = function() {

//include Yandex.js start
@@INCLUDERAW:external/Yandex.js@@
//include Yandex.js end

  var yStyles = {
    'map': "Map",
    'satellite': "Satellite",
    'hybrid': "Hybrid",
//    'publicMap': "Public Map",
//    'publicMapHybrid': "Public Hybrid",
  };

  var yOpt = {maxZoom: 18};

  $.each(yStyles, function(key,value) {
    var yMap = new L.Yandex(key, yOpt);
    layerChooser.addBaseLayer(yMap, 'Yandex '+value);
  });

};

var setup =  window.plugin.mapTileYandex.setup;

// PLUGIN END //////////////////////////////////////////////////////////

@@PLUGINEND@@
<commit_msg>yandex map layer: add dummy layers to the map immediately, then add the yandex layers once the external JS library has loaded<commit_after>// ==UserScript==
// @id             iitc-plugin-basemap-yandex@jonatkins
// @name           IITC plugin: Yandex maps
// @category       Map Tiles
// @version        0.2.0.@@DATETIMEVERSION@@
// @namespace      https://github.com/jonatkins/ingress-intel-total-conversion
// @updateURL      @@UPDATEURL@@
// @downloadURL    @@DOWNLOADURL@@
// @description    [@@BUILDNAME@@-@@BUILDDATE@@] Add Yandex.com (Russian/Русский) map layers
// @include        https://www.ingress.com/intel*
// @include        http://www.ingress.com/intel*
// @match          https://www.ingress.com/intel*
// @match          http://www.ingress.com/intel*
// @grant          none
// ==/UserScript==

@@PLUGINSTART@@

// PLUGIN START ////////////////////////////////////////////////////////

// use own namespace for plugin
window.plugin.mapTileYandex = function() {};

window.plugin.mapTileYandex.leafletSetup = function() {

//include Yandex.js start
@@INCLUDERAW:external/Yandex.js@@
//include Yandex.js end

}

window.plugin.mapTileYandex.setup = function() {

  var yStyles = {
    'map': "Map",
    'satellite': "Satellite",
    'hybrid': "Hybrid",
//    'publicMap': "Public Map",
//    'publicMapHybrid': "Public Hybrid",
  };

  // we can't directly create the L.Yandex object, as we need to async load the yandex map API
  // so we'll add empty layer groups, then in the callback we can add the yandex layers to the layer groups
  var layers = {};

  $.each(yStyles, function(key,value) {
    layers[key] = new L.LayerGroup();
    layerChooser.addBaseLayer(layers[key], 'Yandex '+value);
  });

  var callback = function() {
    window.plugin.mapTileYandex.leafletSetup();
    var yOpt = {maxZoom: 18};
    $.each(layers, function(key,layer) {
      var yMap = new L.Yandex(key, yOpt);
      layer.addLayer(yMap);
    });
  }

//a few options on language are available, including en-US. Oddly, the detail available on the maps varies
//depending on the language
  var yandexApiJs = '//api-maps.yandex.ru/2.0-stable/?load=package.standard&lang=ru-RU'

  load(yandexApiJs).thenRun(callback);
}

var setup =  window.plugin.mapTileYandex.setup;

// PLUGIN END //////////////////////////////////////////////////////////

@@PLUGINEND@@
<|endoftext|>


<commit_before>// This is a manifest file that'll be compiled into including all the files listed below.
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
//= require jquery
//= require jquery_ujs
//= require_tree .

(function($){

$(document).ready(function() {

    $('a[data-colorbox="true"]').on('click', function(e) {
        e.preventDefault();

        $.colorbox(
            {
                height: $(this).data("colorbox-height") || false,
                width: $(this).data("colorbox-width") || false,
                maxWidth: $(this).data("colorbox-max-width") || false,
                maxHeight: $(this).data("colorbox-max-height") || false,
                iframe: $(this).data("colorbox-iframe") || false,
                photo: $(this).data("colorbox-photo") || false,
                innerHeight: $(this).data("colorbox-innerheight") || false,
                innerWidth: $(this).data("colorbox-innerwidth") || false,
                title: $(this).data("colorbox-title") || false,
                className: $(this).data("colorbox-class-name") || false,
                href: $(this).attr('href'),
                inline: $(this).data("colorbox-inline") || false,
                opacity: 0.5
            });
    });

    $('a[data-colorbox-static="true"]').colorbox(
            {
                height: function() { return $(this).data("colorbox-height") || false },
                width: function() { return $(this).data("colorbox-width") || false },
                maxWidth: function() { return $(this).data("colorbox-max-width") || false },
                maxHeight: function() { return $(this).data("colorbox-max-height") || false },
                iframe: function() { return $(this).data("colorbox-iframe") || false },
                photo: function() { return $(this).data("colorbox-photo") || false },
                innerHeight: function() { return $(this).data("colorbox-innerheight") || false },
                innerWidth: function() { return $(this).data("colorbox-innerwidth") || false },
                title: function() { return $(this).data("colorbox-title") || false },
                className: function() { return $(this).data("colorbox-class-name") || false },
                href: function() { return $(this).attr('href') },
                inline: function() { return $(this).data("colorbox-inline") || false},
                opacity: 0.5
            });
});

}) (jQuery);
<commit_msg>Use event delegation<commit_after>// This is a manifest file that'll be compiled into including all the files listed below.
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
//= require jquery
//= require jquery_ujs
//= require_tree .

(function($){

$(document).ready(function() {

    $(document).on('click', 'a[data-colorbox="true"]', function(e) {
        e.preventDefault();

        $.colorbox(
            {
                height: $(this).data("colorbox-height") || false,
                width: $(this).data("colorbox-width") || false,
                maxWidth: $(this).data("colorbox-max-width") || false,
                maxHeight: $(this).data("colorbox-max-height") || false,
                iframe: $(this).data("colorbox-iframe") || false,
                photo: $(this).data("colorbox-photo") || false,
                innerHeight: $(this).data("colorbox-innerheight") || false,
                innerWidth: $(this).data("colorbox-innerwidth") || false,
                title: $(this).data("colorbox-title") || false,
                className: $(this).data("colorbox-class-name") || false,
                href: $(this).attr('href'),
                inline: $(this).data("colorbox-inline") || false,
                opacity: 0.5
            });
    });

    $('a[data-colorbox-static="true"]').colorbox(
            {
                height: function() { return $(this).data("colorbox-height") || false },
                width: function() { return $(this).data("colorbox-width") || false },
                maxWidth: function() { return $(this).data("colorbox-max-width") || false },
                maxHeight: function() { return $(this).data("colorbox-max-height") || false },
                iframe: function() { return $(this).data("colorbox-iframe") || false },
                photo: function() { return $(this).data("colorbox-photo") || false },
                innerHeight: function() { return $(this).data("colorbox-innerheight") || false },
                innerWidth: function() { return $(this).data("colorbox-innerwidth") || false },
                title: function() { return $(this).data("colorbox-title") || false },
                className: function() { return $(this).data("colorbox-class-name") || false },
                href: function() { return $(this).attr('href') },
                inline: function() { return $(this).data("colorbox-inline") || false},
                opacity: 0.5
            });
});

}) (jQuery);
<|endoftext|>


<commit_before><commit_msg>fixed date formats<commit_after><|endoftext|>


<commit_before>var test = require('tape');
var iterator = require('../iterator');

test('Gets next item', function (t) {
    t.plan(1);
	var collection = [{name:'one'}, {name:'two'}, {name:'three'}, {name:'four'}];
	var current = collection[0];
	current = iterator.next(current, collection);
	t.equal(current, collection[1]);
});

test('Gets first item if current is last', function (t) {
    t.plan(1);
	var collection = [{name:'one'}, {name:'two'}, {name:'three'}, {name:'four'}];
	var current = collection[3];
	current = iterator.next(current, collection);
	t.equal(current, collection[0]);
});

test('Gets previous item', function (t) {
    t.plan(1);
	var collection = [{name:'one'}, {name:'two'}, {name:'three'}, {name:'four'}];
	var current = collection[1];
	current = iterator.prev(current, collection);
	t.equal(current, collection[0]);
});

test('Gets last item if current is last', function (t) {
    t.plan(1);
	var collection = [{name:'one'}, {name:'two'}, {name:'three'}, {name:'four'}];
	var current = collection[0];
	current = iterator.prev(current, collection);
	t.equal(current, collection[3]);
});

test('Returns next or false', function (t) {
    t.plan(2);
	var collection = [{name:'one'}, {name:'two'}, {name:'three'}, {name:'four'}];
	var current = collection[2];
	current = iterator.nextOrFalse(current, collection);
	t.equal(current, collection[3]);
	current = iterator.nextOrFalse(current, collection);
	t.equal(current, false);
});

test('Returns prev or false', function (t) {
    t.plan(2);
	var collection = [{name:'one'}, {name:'two'}, {name:'three'}, {name:'four'}];
	var current = collection[1];
	current = iterator.prevOrFalse(current, collection);
	t.equal(current, collection[0]);
	current = iterator.prevOrFalse(current, collection);
	t.equal(current, false);
});<commit_msg>finishing tests<commit_after>var test = require('tape');
var iterator = require('../iterator');

test('Gets next item', function (t) {
    t.plan(1);
	var collection = [{name:'one'}, {name:'two'}, {name:'three'}, {name:'four'}];
	var current = collection[0];
	current = iterator.next(current, collection);
	t.equal(current, collection[1]);
});

test('Gets first item if current is last', function (t) {
    t.plan(1);
	var collection = [{name:'one'}, {name:'two'}, {name:'three'}, {name:'four'}];
	var current = collection[3];
	current = iterator.next(current, collection);
	t.equal(current, collection[0]);
});

test('Gets previous item', function (t) {
    t.plan(1);
	var collection = [{name:'one'}, {name:'two'}, {name:'three'}, {name:'four'}];
	var current = collection[1];
	current = iterator.prev(current, collection);
	t.equal(current, collection[0]);
});

test('Gets last item if current is last', function (t) {
    t.plan(1);
	var collection = [{name:'one'}, {name:'two'}, {name:'three'}, {name:'four'}];
	var current = collection[0];
	current = iterator.prev(current, collection);
	t.equal(current, collection[3]);
});

test('Returns next or false', function (t) {
    t.plan(2);
	var collection = [{name:'one'}, {name:'two'}, {name:'three'}, {name:'four'}];
	var current = collection[2];
	current = iterator.nextOrFalse(current, collection);
	t.equal(current, collection[3]);
	current = iterator.nextOrFalse(current, collection);
	t.equal(current, false);
});

test('Returns prev or false', function (t) {
    t.plan(2);
	var collection = [{name:'one'}, {name:'two'}, {name:'three'}, {name:'four'}];
	var current = collection[1];
	current = iterator.prevOrFalse(current, collection);
	t.equal(current, collection[0]);
	current = iterator.prevOrFalse(current, collection);
	t.equal(current, false);
});

test('Is first', function (t) {
    t.plan(2);
	var collection = [{name:'one'}, {name:'two'}, {name:'three'}, {name:'four'}];
	t.equal(iterator.isFirst(collection[0], collection), true);
	t.equal(iterator.isFirst(collection[1], collection), false);
});

test('Is last', function (t) {
    t.plan(2);
	var collection = [{name:'one'}, {name:'two'}, {name:'three'}, {name:'four'}];
	t.equal(iterator.isLast(collection[3], collection), true);
	t.equal(iterator.isLast(collection[2], collection), false);
});

test('Adds item to collection if doesnt exist', function (t) {
    t.plan(2);
    var obj = {name: 'five'};
	var collection = [{name:'one'}, {name:'two'}, {name:'three'}, {name:'four'}];
	iterator.add(obj, collection);
	t.equal(obj, collection[4]);
	iterator.add(obj, collection);
	t.equal(collection.length, 5);
});

test('Removes item from collection if it exist', function (t) {
    t.plan(2);
    var obj = {name: 'five'};
	var collection = [{name:'one'}, {name:'two'}, {name:'three'}, {name:'four'}, obj];
	iterator.remove(obj, collection);
	t.equal(collection.length, 4);
	iterator.remove(obj, collection);
	t.equal(collection.length, 4);
});<|endoftext|>


<commit_before>/*global define*/
define([
        'Core/BoundingSphere',
        'Core/Math',
        'Core/JulianDate',
        'Datasources/BoundingSphereState'
    ], function(
        BoundingSphere,
        CesiumMath,
        JulianDate,
        BoundingSphereState) {
    "use strict";
    /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/

    var time = new JulianDate();
    function createDynamicGeometryBoundingSphereSpecs(Updater, entity, graphics, getScene) {
        it('Computes dynamic geometry bounding sphere for fill.', function() {
            var scene = getScene();
            var updater = new Updater(entity, scene);
            graphics.fill = true;
            graphics.outline = false;
            var dynamicUpdater = updater.createDynamicUpdater(scene.primitives);
            dynamicUpdater.update(time);

            var state;
            var result = new BoundingSphere();
            waitsFor(function() {
                scene.initializeFrame();
                scene.render();
                state = dynamicUpdater.getBoundingSphere(entity, result);
                return state !== BoundingSphereState.PENDING;
            });

            runs(function() {
                var primitive = scene.primitives.get(0);
                expect(state).toBe(BoundingSphereState.DONE);
                var attributes = primitive.getGeometryInstanceAttributes(entity);
                expect(result).toEqualEpsilon(BoundingSphere.transform(attributes.boundingSphere, primitive.modelMatrix, new BoundingSphere()), CesiumMath.EPSILON6);

                updater.destroy();
                scene.primitives.removeAll();
            });
        });

        it('Computes dynamic geometry bounding sphere for outline.', function() {
            var scene = getScene();
            var updater = new Updater(entity, scene);
            graphics.fill = false;
            graphics.outline = true;

            var dynamicUpdater = updater.createDynamicUpdater(scene.primitives);
            dynamicUpdater.update(time);

            var state;
            var result = new BoundingSphere();
            waitsFor(function() {
                scene.initializeFrame();
                scene.render();
                state = dynamicUpdater.getBoundingSphere(entity, result);
                return state !== BoundingSphereState.PENDING;
            });

            runs(function() {
                var primitive = scene.primitives.get(0);
                expect(state).toBe(BoundingSphereState.DONE);
                var attributes = primitive.getGeometryInstanceAttributes(entity);
                expect(result).toEqualEpsilon(BoundingSphere.transform(attributes.boundingSphere, primitive.modelMatrix, new BoundingSphere()), CesiumMath.EPSILON6);

                updater.destroy();
                scene.primitives.removeAll();
            });
        });

        it('Compute dynamic geometry bounding sphere throws without entity.', function() {
            var scene = getScene();
            var updater = new Updater(entity, scene);
            var dynamicUpdater = updater.createDynamicUpdater(scene.primitives);

            var result = new BoundingSphere();
            expect(function() {
                dynamicUpdater.getBoundingSphere(undefined, result);
            }).toThrowDeveloperError();

            updater.destroy();
            scene.primitives.removeAll();
        });

        it('Compute dynamic geometry bounding sphere throws without result.', function() {
            var scene = getScene();
            var updater = new Updater(entity, scene);
            var dynamicUpdater = updater.createDynamicUpdater(scene.primitives);

            expect(function() {
                dynamicUpdater.getBoundingSphere(entity, undefined);
            }).toThrowDeveloperError();

            updater.destroy();
            scene.primitives.removeAll();
        });
    }

    return createDynamicGeometryBoundingSphereSpecs;
});
<commit_msg>Fix casing.<commit_after>/*global define*/
define([
        'Core/BoundingSphere',
        'Core/Math',
        'Core/JulianDate',
        'DataSources/BoundingSphereState'
    ], function(
        BoundingSphere,
        CesiumMath,
        JulianDate,
        BoundingSphereState) {
    "use strict";
    /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/

    var time = new JulianDate();
    function createDynamicGeometryBoundingSphereSpecs(Updater, entity, graphics, getScene) {
        it('Computes dynamic geometry bounding sphere for fill.', function() {
            var scene = getScene();
            var updater = new Updater(entity, scene);
            graphics.fill = true;
            graphics.outline = false;
            var dynamicUpdater = updater.createDynamicUpdater(scene.primitives);
            dynamicUpdater.update(time);

            var state;
            var result = new BoundingSphere();
            waitsFor(function() {
                scene.initializeFrame();
                scene.render();
                state = dynamicUpdater.getBoundingSphere(entity, result);
                return state !== BoundingSphereState.PENDING;
            });

            runs(function() {
                var primitive = scene.primitives.get(0);
                expect(state).toBe(BoundingSphereState.DONE);
                var attributes = primitive.getGeometryInstanceAttributes(entity);
                expect(result).toEqualEpsilon(BoundingSphere.transform(attributes.boundingSphere, primitive.modelMatrix, new BoundingSphere()), CesiumMath.EPSILON6);

                updater.destroy();
                scene.primitives.removeAll();
            });
        });

        it('Computes dynamic geometry bounding sphere for outline.', function() {
            var scene = getScene();
            var updater = new Updater(entity, scene);
            graphics.fill = false;
            graphics.outline = true;

            var dynamicUpdater = updater.createDynamicUpdater(scene.primitives);
            dynamicUpdater.update(time);

            var state;
            var result = new BoundingSphere();
            waitsFor(function() {
                scene.initializeFrame();
                scene.render();
                state = dynamicUpdater.getBoundingSphere(entity, result);
                return state !== BoundingSphereState.PENDING;
            });

            runs(function() {
                var primitive = scene.primitives.get(0);
                expect(state).toBe(BoundingSphereState.DONE);
                var attributes = primitive.getGeometryInstanceAttributes(entity);
                expect(result).toEqualEpsilon(BoundingSphere.transform(attributes.boundingSphere, primitive.modelMatrix, new BoundingSphere()), CesiumMath.EPSILON6);

                updater.destroy();
                scene.primitives.removeAll();
            });
        });

        it('Compute dynamic geometry bounding sphere throws without entity.', function() {
            var scene = getScene();
            var updater = new Updater(entity, scene);
            var dynamicUpdater = updater.createDynamicUpdater(scene.primitives);

            var result = new BoundingSphere();
            expect(function() {
                dynamicUpdater.getBoundingSphere(undefined, result);
            }).toThrowDeveloperError();

            updater.destroy();
            scene.primitives.removeAll();
        });

        it('Compute dynamic geometry bounding sphere throws without result.', function() {
            var scene = getScene();
            var updater = new Updater(entity, scene);
            var dynamicUpdater = updater.createDynamicUpdater(scene.primitives);

            expect(function() {
                dynamicUpdater.getBoundingSphere(entity, undefined);
            }).toThrowDeveloperError();

            updater.destroy();
            scene.primitives.removeAll();
        });
    }

    return createDynamicGeometryBoundingSphereSpecs;
});
<|endoftext|>


<commit_before>import React from 'react'
import { Flipper, Flipped } from 'react-flip-toolkit'
import styles from './QueueListAnimator.css'

const handleEnter = (el, i) => {
  el.addEventListener('animationend', (e) => e.target.classList.remove(styles.itemEnter))
  el.classList.add(styles.itemEnter)
  el.removeAttribute('style')
}

const handleExit = (el, i, removeEl) => {
  el.addEventListener('animationend', removeEl)
  el.classList.add(styles.itemExit)
}

const QueueListAnimator = ({ children }) => {
  const items = React.Children.map(children, child => {
    return (
      <Flipped
        key={child.key}
        flipId={child.key}
        onAppear={handleEnter}
        onExit={handleExit}
        stagger
      >

          {child}

      </Flipped>
    )
  })

  return (
    <Flipper flipKey={children} applyTransformOrigin={false}>
      {items}
    </Flipper>
  )
}

export default QueueListAnimator
<commit_msg>Prevent queue animation on header height change<commit_after>import PropTypes from 'prop-types'
import React from 'react'
import { Flipper, Flipped } from 'react-flip-toolkit'
import { useSelector } from 'react-redux'
import styles from './QueueListAnimator.css'

const handleEnter = (el, i) => {
  el.addEventListener('animationend', (e) => e.target.classList.remove(styles.itemEnter))
  el.classList.add(styles.itemEnter)
  el.removeAttribute('style')
}

const handleExit = (el, i, removeEl) => {
  el.addEventListener('animationend', removeEl)
  el.classList.add(styles.itemExit)
}

const QueueListAnimator = ({ children }) => {
  const headerHeight = useSelector(state => state.ui.headerHeight)

  const items = React.Children.map(children, child => {
    return (
      <Flipped
        flipId={child.key}
        key={child.key}
        onAppear={handleEnter}
        onExit={handleExit}
        shouldFlip={(prev, cur) => cur === prev}
        stagger
      >

          {child}

      </Flipped>
    )
  })

  return (
    <Flipper
      applyTransformOrigin={false}
      decisionData={headerHeight}
      flipKey={children}
    >
      {items}
    </Flipper>
  )
}

QueueListAnimator.propTypes = {
  children: PropTypes.node,
}

export default QueueListAnimator
<|endoftext|>


<commit_before>import { beforeNextRender, define, props, css } from '@bolt/core/utils';
import { h, withPreact } from '@bolt/core/renderers';
import Mousetrap from 'mousetrap';

let index = 0;

@define
class BoltVideo extends withPreact() {
  static is = `${bolt.namespace}-video`;

  static props = {
    videoId: props.string,
    accountId: props.string,
    playerId: props.string,
    poster: props.object,
    isBackgroundVideo: props.boolean,
    onInit: props.string,
    showMeta: props.boolean,
    showMetaTitle: props.boolean,
    closeButtonText: props.string,
    loop: props.boolean,
    controls: props.boolean,
    autoplay: props.boolean,
    resetOnFinish: props.boolean,
    directToFullscreen: props.boolean,
    hideFullScreenButton: props.boolean,
    overlayAlignment: {
      ...props.string,
      ...{ default: 'bottom' },
    },
    overlayBackground: props.boolean,
  };

  constructor(self) {
    self = super(self);

    index += 1;

    this.onPlay = this.onPlay.bind(this);
    this.onPause = this.onPause.bind(this);
    this.onEnded = this.onEnded.bind(this);
    this.onDurationChange = this.onDurationChange.bind(this);
    this.onSeeked = this.onSeeked.bind(this);
    this.handleClose = this.handleClose.bind(this);

    this.collapseOnClickAway = this.collapseOnClickAway.bind(this);

    // BoltVideo.globalErrors.forEach(this.props.onError);

    // Ensure that 'this' inside the _onWindowResize event handler refers to <bolt-nav-link>
    // even if the handler is attached to another element (window in this case)
    this._onWindowResize = this._onWindowResize.bind(this);

    return self;
  }

  get renderRoot() {
    return this;
  }

  get expandedHeight() {
    return this.getAttribute('expandedHeight');
  }

  /**
   * Properties and their corresponding attributes should mirror one another.
   * To this effect, the property setter for `expanded` handles truthy/falsy
   * values and reflects those to the state of the attribute. It’s important
   * to note that there are no side effects taking place in the property
   * setter. For example, the setter does not set `aria-expanded`. Instead,
   * that work happens in the `attributeChangedCallback`. As a general rule,
   * make property setters very dumb, and if setting a property or attribute
   * should cause a side effect (like setting a corresponding ARIA attribute)
   * do that work in the `attributeChangedCallback`. This will avoid having to
   * manage complex attribute/property reentrancy scenarios.
   */
  set expandedHeight(value) {
    // Properties can be set to all kinds of string values. This makes sure
    // it’s converted to a proper boolean value using JavaScript’s truthiness
    // & falsiness principles.
    // value = Boolean(value);
    if (value) {
      this.setAttribute('expandedHeight', value);
    } else {
      this.removeAttribute('expandedHeight');
    }

    this.dispatchEvent(
      new CustomEvent('videoExpandedHeightSet', {
        detail: { expandedHeight: this.expandedHeight },
        bubbles: true,
      }),
    );
  }

  // Called to check whether or not the component should call
  // updated(), much like React's shouldComponentUpdate().
  // updating(props, state) {
  //   console.log(props);
  //   console.log(state);
  // }

  _setMetaTitle(title) {
    if (this.props.showMeta && this.props.showMetaTitle) {
      this.querySelector(`${bolt.namespace}-video-meta`).setAttribute(
        'title',
        title,
      );
    }
  }

  _setMetaDuration(seconds) {
    if (this.props.showMeta) {
      const durationFormatted = BoltVideo._formatDuration(seconds);
      this.querySelector(`${bolt.namespace}-video-meta`).setAttribute(
        'duration',
        durationFormatted,
      );
    }
  }

  static _formatDuration(seconds) {
    const mm = Math.floor(seconds / 60) || 0;
    const ss = ('0' + Math.floor(seconds % 60)).slice(-2);

    return mm + ':' + ss;
  }

  _setVideoDimensions(width, height) {
    this.srcWidth = width;
    this.srcHeight = height;
  }

  static handlePlayerReady(context) {
    const player = this;
    const elem = context;

    elem.setPlayer(player);

    // If the option to show controls is set to false (meaning, no controls will be shown), make sure the video is also muted.
    if (elem.controls === false) {
      elem.player.muted(true);
    }

    player.on('loadedmetadata', function() {
      const duration = player.mediainfo.duration;
      const title = player.mediainfo.name;
      const width = player.mediainfo.sources[1].width;
      const height = player.mediainfo.sources[1].height;

      elem._setMetaTitle(title);
      elem._setMetaDuration(duration);
      elem._setVideoDimensions(width, height);

      if (this.earlyToggle) {
        this.earlyToggle = false;
        this.toggle();
      } else if (this.earlyPlay) {
        this.earlyPlay = false;
        this.play();
      } else if (this.earlyPause) {
        this.earlyPause = false;
        this.pause();
      }
    });

    player.on('play', function() {
      elem.onPlay(player);
    });

    player.on('pause', function() {
      elem.onPause(player);
    });

    player.on('seeked', function() {
      elem.onSeeked(player);
    });

    player.on('timeupdate', function() {
      // elem.onPlay(player);
    });

    player.on('durationchange', function() {
      elem.onDurationChange(player);
    });

    player.on('ended', function() {
      elem.onEnded(player);
    });

    // this.contextmenu({ disabled: true });
  }

  static appendScript(s) {
    document.body.appendChild(s);
  }

  static getScriptUrl(accountId, playerId) {
    return `//players.brightcove.net/${accountId}/${playerId}_default/index.min.js`;
  }

  static getCurrentTimeMs(player) {
    return Math.round(player.currentTime() * 1000);
  }

  static getDurationMs(player) {
    return Math.round(player.duration() * 1000);
  }

  // static isBackgroundVideo() {
  //   return this.props.isBackgroundVideo;
  // }

  handleClose() {
    this.close();
  }

  connecting() {
    this.state = {
      // IDs can't start with numbers so adding the "v" prefix to prevent JS errors
      id: `v${this.props.videoId}-${this.props.accountId}-${index}`,
      // errors: BoltVideo.globalErrors !== undefined  ? [].concat(BoltVideo.globalErrors) : [],
      isPlaying: 'paused',
      isFinished: false,
      progress: 0,
    };

    if (this.props.isBackgroundVideo) {
      this._calculateIdealVideoSize();
    }

    if (BoltVideo.globalErrors !== undefined && BoltVideo.globalErrors.length) {
      // console.log('adding default errors');
      // console.log(this.state.errors);
      this.state.errors = [].concat(BoltVideo.globalErrors);
    } else {
      this.state.errors = [];
    }

    if (this.state.errors.length) {
      // console.log(this.state.errors);
      // console.log('error length');
      return;
    }

    // only ever append script once
    if (!BoltVideo.players) {
      BoltVideo.players = [];

      const s = this.createScript();

      s.onload = () => {
        BoltVideo.players.forEach(function(player) {
          player.initVideoJS(player.state.id);
        });
      };

      // handle script not loading
      s.onerror = err => {
        const uriErr = {
          code: '',
          message: `The script ${err.target.src} is not accessible.`,
        };

        BoltVideo.globalErrors.push(uriErr);

        this.props.onError(uriErr);
      };

      BoltVideo.appendScript(s);
    }

    this.init();

    // If onInit event exists on element, run that instead of auto initializing
    if (this.props.onInit) {
      if (window[this.props.onInit]) {
        window[this.props.onInit](this);
      }
    }

    // If our video can expand/collapse we add the collapse listener and "close on escape" behavior
    if (this.props.isBackgroundVideo) {
      window.addEventListener('resize', this._onWindowResize);
      Mousetrap.bind('esc', this.handleClose, 'keyup');
      document.addEventListener('click', this.collapseOnClickAway);
    }
  }

  _onWindowResize(event) {
    this._calculateIdealVideoSize();
  }

  // If we click outside the video wrapper div collapse the video
  collapseOnClickAway(event) {
    const videoWrapper = this.querySelector('.c-bolt-video--background');
    if (!videoWrapper.contains(event.target)) {
      // @todo: debug why videos don't autoplay when this is enabled
      // this.close();
    }
  }

  disconnecting() {
    if (this.props.isBackgroundVideo) {
      window.removeEventListener('optimizedResize', this._onWindowResize);
    }

    if (this.player) {
      this.player.dispose();
    }
  }

  onError(player) {
    this.props.onError(player.error());
  }

  onPlay(player) {
    this.classList.add('is-playing');
    this.classList.remove('is-finished', 'is-paused');

    // @TODO: implement internal setState method
    // elem.setState({
    //   isPlaying: true,
    //   progress: BoltVideo.getCurrentTimeMs(player),
    //   isFinished: false
    // });

    // Dispatch an event that signals a request to expand to the
    // `<howto-accordion>` element.
    this.state.isPlaying = true;
    this.state.progress = BoltVideo.getCurrentTimeMs(player);
    this.state.isFinished = false;

    this.dispatchEvent(
      new CustomEvent('playing', {
        detail: {
          isBackgroundVideo: this.props.isBackgroundVideo,
        },
        bubbles: true,
      }),
    );
  }

  onPause(player) {
    const progress = BoltVideo.getCurrentTimeMs(player);

    this.classList.add('is-paused');
    this.classList.remove('is-playing');

    // @TODO: implement internal setState method
    // this.setState({
    //   isPlaying: false,
    //   progress
    // });

    this.state.isPlaying = false;
    this.state.progress = progress;

    this.dispatchEvent(
      new CustomEvent('pause', {
        detail: {
          isBackgroundVideo: this.props.isBackgroundVideo,
        },
        bubbles: true,
      }),
    );
  }

  onSeeked(player) {
    const progress = BoltVideo.getCurrentTimeMs(player);

    // @TODO: implement internal setState method
    // this.setState({
    //   progress: BoltVideo.getCurrentTimeMs(player),
    //   isFinished: false
    // });
    this.state.isFinished = false;
    this.state.progress = progress;
  }

  onDurationChange(player) {
    const duration = BoltVideo.getDurationMs(player);

    // @TODO: implement internal setState method
    // this.setState({ duration: BoltVideo.getDurationMs(player) });

    this.state.duration = duration;
  }

  onEnded() {
    // calling syncronously here inteferes with player and causes errors to be thrown

    setTimeout(() => {
      this.state.isFinished = true;

      this.classList.add('is-finished');
      this.classList.remove('is-paused');

      this.dispatchEvent(
        new CustomEvent('ended', {
          detail: {
            isBackgroundVideo: this.props.isBackgroundVideo,
          },
          bubbles: true,
        }),
      );
      // this.setState({ isFinished: true });
    }, 0);
  }

  _calculateIdealVideoSize() {
    this.expandedHeight = this.getBoundingClientRect().height;
  }

  setPlayer(player) {
    this.player = player;
  }

  createScript() {
    const s = document.createElement('script');

    s.src = BoltVideo.getScriptUrl(this.props.accountId, this.props.playerId);
    s.async = true;

    return s;
  }

  initVideoJS(id) {
    const self = this;

    beforeNextRender(this, function() {
      const player = videojs(id);
      const handler = BoltVideo.handlePlayerReady.bind(player, self);
      player.ready(handler);
    });
  }

  initVideo(id) {
    const self = this;

    beforeNextRender(this, function() {
      bc(self.querySelector(`#${id}`), {
        controlBar: {
          fullscreenToggle: !self.props.hideFullScreenButton,
        },
      });
      self.initVideoJS(id);
    });
  }

  init() {
    const self = this;

    beforeNextRender(this, function() {
      if (window.bc && window.videojs) {
        self.initVideo(self.state.id);
      } else {
        BoltVideo.players.push(self);
      }
    });
  }

  play() {
    if (this.player) {
      this.player.play();
    } else {
      this.earlyPlay = true;

      this.dispatchEvent(
        new CustomEvent('playing', {
          detail: {
            isBackgroundVideo: this.props.isBackgroundVideo,
          },
          bubbles: true,
        }),
      );
    }
  }

  close() {
    this.pause();

    this.dispatchEvent(
      new CustomEvent('close', {
        detail: {
          isBackgroundVideo: this.props.isBackgroundVideo,
        },
        bubbles: true,
      }),
    );
  }

  toggle() {
    if (this.player) {
      if (this.state.isPlaying === false || this.state.isPlaying === 'paused') {
        this.play();
      } else {
        this.pause();
      }
    } else {
      this.earlyToggle = true;

      this.dispatchEvent(
        new CustomEvent('playing', {
          detail: {
            isBackgroundVideo: this.props.isBackgroundVideo,
          },
          bubbles: true,
        }),
      );
    }
  }

  pause() {
    if (this.player) {
      this.player.pause();
    } else {
      this.earlyPause = true;
    }
  }

  render({ state, props }) {
    // console.log('render callback');
    // data-email-subject="Pega - Intelligent Virtual Assistant for Email"
    // data-email-body="Check out this video from Pega"
    // data-email-videourl="https://local.d8.pega.com/insights/resources/intelligent-virtual-assistant-email"

    // const playIconEmoji = () => (
    //
    //     ▶
    //
    // );
    /* eslint jsx-a11y/media-has-caption: "off" */
    // Added a wrapping div as brightcove adds siblings to the video tag
    const dataAttributes = datasetToObject(this);

    let closeButtonText = null;
    if (this.props.closeButtonText) {
      closeButtonText = this.props.closeButtonText;
    } else {
      closeButtonText = 'Close';
    }

    const classes = css(
      `c-${bolt.namespace}-video`,
      this.props.controls === false
        ? `c-${bolt.namespace}-video--hide-controls`
        : '',
      this.props.isBackgroundVideo
        ? `c-${bolt.namespace}-video--background`
        : '',
    );

    const videoMetaTag = `${bolt.namespace}-video-meta`;

    return (

        <video
          {...dataAttributes}
          id={this.state.id}
          {...(this.props.poster ? { poster: this.props.poster.uri } : {})}
          data-embed="default"
          data-video-id={this.props.videoId}
          preload="none"
          data-account={this.props.accountId}
          data-player={this.props.playerId}
          // playIcon={playIconEmoji()}
          // following 'autoplay' can not expected to always work on web
          // see: https://docs.brightcove.com/en/player/brightcove-player/guides/in-page-embed-player-implementation.html
          autoPlay={this.props.autoplay}
          data-application-id
          loop={this.props.loop}
          className="video-js"
          controls={this.props.controls === false ? false : true}
        />
        {this.props.showMeta && h(videoMetaTag)}
        {this.props.isBackgroundVideo && (
          <a
            className={css(
              `c-${bolt.namespace}-video__close-button`,
              `c-${bolt.namespace}-video__close-button--icon-to-text`,
            )}
            href="javascript:"
            onClick={this.handleClose}>
            <span className={`c-${bolt.namespace}-video__close-button-icon`}>

                  <bolt-icon name="close" size="small" />

            <span className={`c-${bolt.namespace}-video__close-button-text`}>
              {closeButtonText}

        )}

    );
  }
}

export default BoltVideo;

export { BoltVideo };
<commit_msg>chore: clean up video component JS<commit_after>import { beforeNextRender, define, props, css } from '@bolt/core/utils';
import { h, withPreact } from '@bolt/core/renderers';
import Mousetrap from 'mousetrap';

let index = 0;

@define
class BoltVideo extends withPreact() {
  static is = `${bolt.namespace}-video`;

  static props = {
    videoId: props.string,
    accountId: props.string,
    playerId: props.string,
    poster: props.object,
    isBackgroundVideo: props.boolean,
    onInit: props.string,
    showMeta: props.boolean,
    showMetaTitle: props.boolean,
    closeButtonText: props.string,
    loop: props.boolean,
    controls: props.boolean,
    autoplay: props.boolean,
    resetOnFinish: props.boolean,
    directToFullscreen: props.boolean,
    hideFullScreenButton: props.boolean,
    overlayAlignment: {
      ...props.string,
      ...{ default: 'bottom' },
    },
    overlayBackground: props.boolean,
  };

  constructor(self) {
    self = super(self);
    self.useShadow = false;

    index += 1;

    // These bindings are necessary to make `this` work in the callback
    this.onPlay = this.onPlay.bind(this);
    this.onPause = this.onPause.bind(this);
    this.onEnded = this.onEnded.bind(this);
    this.onDurationChange = this.onDurationChange.bind(this);
    this.onSeeked = this.onSeeked.bind(this);
    this.handleClose = this.handleClose.bind(this);
    this.collapseOnClickAway = this.collapseOnClickAway.bind(this);

    // BoltVideo.globalErrors.forEach(this.props.onError);

    // Ensure that 'this' inside the _onWindowResize event handler refers to <bolt-nav-link>
    // even if the handler is attached to another element (window in this case)
    this._onWindowResize = this._onWindowResize.bind(this);

    return self;
  }

  get expandedHeight() {
    return this.getAttribute('expandedHeight');
  }

  /**
   * Properties and their corresponding attributes should mirror one another.
   * To this effect, the property setter for `expanded` handles truthy/falsy
   * values and reflects those to the state of the attribute. It’s important
   * to note that there are no side effects taking place in the property
   * setter. For example, the setter does not set `aria-expanded`. Instead,
   * that work happens in the `attributeChangedCallback`. As a general rule,
   * make property setters very dumb, and if setting a property or attribute
   * should cause a side effect (like setting a corresponding ARIA attribute)
   * do that work in the `attributeChangedCallback`. This will avoid having to
   * manage complex attribute/property reentrancy scenarios.
   */
  set expandedHeight(value) {
    // Properties can be set to all kinds of string values. This makes sure
    // it’s converted to a proper boolean value using JavaScript’s truthiness
    // & falsiness principles.
    // value = Boolean(value);
    if (value) {
      this.setAttribute('expandedHeight', value);
    } else {
      this.removeAttribute('expandedHeight');
    }

    this.dispatchEvent(
      new CustomEvent('videoExpandedHeightSet', {
        detail: { expandedHeight: this.expandedHeight },
        bubbles: true,
      }),
    );
  }

  _setMetaTitle(title) {
    if (this.props.showMeta && this.props.showMetaTitle) {
      this.querySelector(`${bolt.namespace}-video-meta`).setAttribute(
        'title',
        title,
      );
    }
  }

  _setMetaDuration(seconds) {
    if (this.props.showMeta) {
      const durationFormatted = formatVideoDuration(seconds);
      this.querySelector(`${bolt.namespace}-video-meta`).setAttribute(
        'duration',
        durationFormatted,
      );
    }
  }

  _setVideoDimensions(width, height) {
    this.srcWidth = width;
    this.srcHeight = height;
  }

  static handlePlayerReady(context) {
    const player = this;
    const elem = context;

    elem.setPlayer(player);

    // If the option to show controls is set to false (meaning, no controls will be shown), make sure the video is also muted.
    if (elem.controls === false) {
      elem.player.muted(true);
    }

    player.on('loadedmetadata', function() {
      const duration = player.mediainfo.duration;
      const title = player.mediainfo.name;
      const width = player.mediainfo.sources[1].width;
      const height = player.mediainfo.sources[1].height;

      elem._setMetaTitle(title);
      elem._setMetaDuration(duration);
      elem._setVideoDimensions(width, height);

      if (this.earlyToggle) {
        this.earlyToggle = false;
        this.toggle();
      } else if (this.earlyPlay) {
        this.earlyPlay = false;
        this.play();
      } else if (this.earlyPause) {
        this.earlyPause = false;
        this.pause();
      }
    });

    player.on('play', function() {
      elem.onPlay(player);
    });

    player.on('pause', function() {
      elem.onPause(player);
    });

    player.on('seeked', function() {
      elem.onSeeked(player);
    });

    player.on('timeupdate', function() {
      // elem.onPlay(player);
    });

    player.on('durationchange', function() {
      elem.onDurationChange(player);
    });

    player.on('ended', function() {
      elem.onEnded(player);
    });
  }

  static appendScript(s) {
    document.body.appendChild(s);
  }

  static getScriptUrl(accountId, playerId) {
    return `//players.brightcove.net/${accountId}/${playerId}_default/index.min.js`;
  }

  static getCurrentTimeMs(player) {
    return Math.round(player.currentTime() * 1000);
  }

  static getDurationMs(player) {
    return Math.round(player.duration() * 1000);
  }

  handleClose() {
    this.close();
  }

  connecting() {
    this.state = {
      // IDs can't start with numbers so adding the "v" prefix to prevent JS errors
      id: `v${this.props.videoId}-${this.props.accountId}-${index}`,
      // errors: BoltVideo.globalErrors !== undefined  ? [].concat(BoltVideo.globalErrors) : [],
      isPlaying: 'paused',
      isFinished: false,
      progress: 0,
    };

    if (this.props.isBackgroundVideo) {
      this._calculateIdealVideoSize();
    }

    if (BoltVideo.globalErrors !== undefined && BoltVideo.globalErrors.length) {
      // console.log('adding default errors');
      // console.log(this.state.errors);
      this.state.errors = [].concat(BoltVideo.globalErrors);
    } else {
      this.state.errors = [];
    }

    if (this.state.errors.length) {
      // console.log(this.state.errors);
      // console.log('error length');
      return;
    }

    // only ever append script once
    if (!BoltVideo.players) {
      BoltVideo.players = [];

      const s = this.createScript();

      s.onload = () => {
        BoltVideo.players.forEach(function(player) {
          player.initVideoJS(player.state.id);
        });
      };

      // handle script not loading
      s.onerror = err => {
        const uriErr = {
          code: '',
          message: `The script ${err.target.src} is not accessible.`,
        };

        BoltVideo.globalErrors.push(uriErr);

        this.props.onError(uriErr);
      };

      BoltVideo.appendScript(s);
    }

    this.init();

    // If onInit event exists on element, run that instead of auto initializing
    if (this.props.onInit) {
      if (window[this.props.onInit]) {
        window[this.props.onInit](this);
      }
    }

    // If our video can expand/collapse we add the collapse listener and "close on escape" behavior
    if (this.props.isBackgroundVideo) {
      window.addEventListener('resize', this._onWindowResize);
      Mousetrap.bind('esc', this.handleClose, 'keyup');
      document.addEventListener('click', this.collapseOnClickAway);
    }
  }

  _onWindowResize(event) {
    this._calculateIdealVideoSize();
  }

  // If we click outside the video wrapper div collapse the video
  collapseOnClickAway(event) {
    const videoWrapper = this.querySelector('.c-bolt-video--background');
    if (!videoWrapper.contains(event.target)) {
      // @todo: debug why videos don't autoplay when this is enabled
      // this.close();
    }
  }

  disconnecting() {
    if (this.props.isBackgroundVideo) {
      window.removeEventListener('optimizedResize', this._onWindowResize);
    }

    if (this.player) {
      this.player.dispose();
    }
  }

  onError(player) {
    this.props.onError(player.error());
  }

  onPlay(player) {
    this.classList.add('is-playing');
    this.classList.remove('is-finished', 'is-paused');

    // @TODO: implement internal setState method
    // elem.setState({
    //   isPlaying: true,
    //   progress: BoltVideo.getCurrentTimeMs(player),
    //   isFinished: false
    // });

    // Dispatch an event that signals a request to expand to the
    // `<howto-accordion>` element.
    this.state.isPlaying = true;
    this.state.progress = BoltVideo.getCurrentTimeMs(player);
    this.state.isFinished = false;

    this.dispatchEvent(
      new CustomEvent('playing', {
        detail: {
          isBackgroundVideo: this.props.isBackgroundVideo,
        },
        bubbles: true,
      }),
    );
  }

  onPause(player) {
    const progress = BoltVideo.getCurrentTimeMs(player);

    this.classList.add('is-paused');
    this.classList.remove('is-playing');

    // @TODO: implement internal setState method
    // this.setState({
    //   isPlaying: false,
    //   progress
    // });

    this.state.isPlaying = false;
    this.state.progress = progress;

    this.dispatchEvent(
      new CustomEvent('pause', {
        detail: {
          isBackgroundVideo: this.props.isBackgroundVideo,
        },
        bubbles: true,
      }),
    );
  }

  onSeeked(player) {
    const progress = BoltVideo.getCurrentTimeMs(player);

    // @TODO: implement internal setState method
    // this.setState({
    //   progress: BoltVideo.getCurrentTimeMs(player),
    //   isFinished: false
    // });
    this.state.isFinished = false;
    this.state.progress = progress;
  }

  onDurationChange(player) {
    const duration = BoltVideo.getDurationMs(player);

    // @TODO: implement internal setState method
    // this.setState({ duration: BoltVideo.getDurationMs(player) });

    this.state.duration = duration;
  }

  onEnded() {
    // calling syncronously here inteferes with player and causes errors to be thrown

    setTimeout(() => {
      this.state.isFinished = true;

      this.classList.add('is-finished');
      this.classList.remove('is-paused');

      this.dispatchEvent(
        new CustomEvent('ended', {
          detail: {
            isBackgroundVideo: this.props.isBackgroundVideo,
          },
          bubbles: true,
        }),
      );
      // this.setState({ isFinished: true });
    }, 0);
  }

  _calculateIdealVideoSize() {
    this.expandedHeight = this.getBoundingClientRect().height;
  }

  setPlayer(player) {
    this.player = player;
  }

  createScript() {
    const s = document.createElement('script');

    s.src = BoltVideo.getScriptUrl(this.props.accountId, this.props.playerId);
    s.async = true;

    return s;
  }

  initVideoJS(id) {
    const self = this;

    beforeNextRender(this, function() {
      const player = videojs(id);
      const handler = BoltVideo.handlePlayerReady.bind(player, self);
      player.ready(handler);
    });
  }

  initVideo(id) {
    const self = this;

    beforeNextRender(this, function() {
      bc(self.querySelector(`#${id}`), {
        controlBar: {
          fullscreenToggle: !self.props.hideFullScreenButton,
        },
      });
      self.initVideoJS(id);
    });
  }

  init() {
    const self = this;

    beforeNextRender(this, function() {
      if (window.bc && window.videojs) {
        self.initVideo(self.state.id);
      } else {
        BoltVideo.players.push(self);
      }
    });
  }

  play() {
    if (this.player) {
      this.player.play();
    } else {
      this.earlyPlay = true;

      this.dispatchEvent(
        new CustomEvent('playing', {
          detail: {
            isBackgroundVideo: this.props.isBackgroundVideo,
          },
          bubbles: true,
        }),
      );
    }
  }

  close() {
    this.pause();

    this.dispatchEvent(
      new CustomEvent('close', {
        detail: {
          isBackgroundVideo: this.props.isBackgroundVideo,
        },
        bubbles: true,
      }),
    );
  }

  toggle() {
    if (this.player) {
      if (this.state.isPlaying === false || this.state.isPlaying === 'paused') {
        this.play();
      } else {
        this.pause();
      }
    } else {
      this.earlyToggle = true;

      this.dispatchEvent(
        new CustomEvent('playing', {
          detail: {
            isBackgroundVideo: this.props.isBackgroundVideo,
          },
          bubbles: true,
        }),
      );
    }
  }

  pause() {
    if (this.player) {
      this.player.pause();
    } else {
      this.earlyPause = true;
    }
  }

  render({ state, props }) {
    // data-email-subject="Pega - Intelligent Virtual Assistant for Email"
    // data-email-body="Check out this video from Pega"
    // data-email-videourl="https://local.d8.pega.com/insights/resources/intelligent-virtual-assistant-email"

    // const playIconEmoji = () => (
    //
    //     ▶
    //
    // );
    /* eslint jsx-a11y/media-has-caption: "off" */
    // Added a wrapping div as brightcove adds siblings to the video tag
    const dataAttributes = datasetToObject(this);

    let closeButtonText = null;
    if (this.props.closeButtonText) {
      closeButtonText = this.props.closeButtonText;
    } else {
      closeButtonText = 'Close';
    }

    const classes = css(
      `c-${bolt.namespace}-video`,
      this.props.controls === false
        ? `c-${bolt.namespace}-video--hide-controls`
        : '',
      this.props.isBackgroundVideo
        ? `c-${bolt.namespace}-video--background`
        : '',
    );

    const videoMetaTag = `${bolt.namespace}-video-meta`;

    return (

        <video
          {...dataAttributes}
          id={this.state.id}
          {...(this.props.poster ? { poster: this.props.poster.uri } : {})}
          data-embed="default"
          data-video-id={this.props.videoId}
          preload="none"
          data-account={this.props.accountId}
          data-player={this.props.playerId}
          // playIcon={playIconEmoji()}
          // following 'autoplay' can not expected to always work on web
          // see: https://docs.brightcove.com/en/player/brightcove-player/guides/in-page-embed-player-implementation.html
          autoPlay={this.props.autoplay}
          data-application-id
          loop={this.props.loop}
          className="video-js"
          controls={this.props.controls === false ? false : true}
        />
        {this.props.showMeta && h(videoMetaTag)}
        {this.props.isBackgroundVideo && (
          <a
            className={css(
              `c-${bolt.namespace}-video__close-button`,
              `c-${bolt.namespace}-video__close-button--icon-to-text`,
            )}
            href="javascript:"
            onClick={this.handleClose}>
            <span className={`c-${bolt.namespace}-video__close-button-icon`}>

                  <bolt-icon name="close" size="small" />

            <span className={`c-${bolt.namespace}-video__close-button-text`}>
              {closeButtonText}

        )}

    );
  }
}

export default BoltVideo;

export { BoltVideo };
<|endoftext|>


<commit_before>import React from 'react';
import Landing from '../landing';
import Dashboard from '../dashboard';
import axios from 'axios';
import { BrowserRouter, Route, Switch} from 'react-router-dom';

class App extends React.Component {

  render() {
    return (
      <BrowserRouter>

          <Switch>
            <Route exact path="/" component={Landing}/>
            <Route exact path="/play" component={Dashboard} question={this.state}/>
          </Switch>

      </BrowserRouter>
    );
  }
}

export default App;
<commit_msg>removed question var component<commit_after>import React from 'react';
import Landing from '../landing';
import Dashboard from '../dashboard';
import axios from 'axios';
import { BrowserRouter, Route, Switch} from 'react-router-dom';

class App extends React.Component {

  render() {
    return (
      <BrowserRouter>

          <Switch>
            <Route exact path="/" component={Landing}/>
            <Route exact path="/play" component={Dashboard} />
          </Switch>

      </BrowserRouter>
    );
  }
}

export default App;
<|endoftext|>


<commit_before>app.controller('BackupAndRestoreController', ['$scope', '$route', '$window', 'OptionsService', function ($scope, $route, $window, OptionsService) {
    $scope.messages = { success: false, error: false, errorMessage: null };

    $scope.openFileDialog = function () {
        var element = angular.element('#restoreFileSelector');
        element.trigger('click');
    };

    $scope.exportSettings = function () {
        var options = OptionsService.getOptions(),
            encodedData = $window.btoa(angular.toJson(options)),
            dateStamp = moment().format('YYYY-MM-DD');

        try {
            var blob = new Blob([encodedData], {type: 'text/plain;charset=utf-8'});
            saveAs(blob, 'form-filler-' + dateStamp + '.txt');
        } catch (e) {
            $scope.messages.errorMessage = 'Error creating a backup file: ' + e.toString();
            $scope.messages.error = true;
            console.error(e);
        }
    };

    $scope.importSettings = function ($event) {
        var inputElement = $event.target;
        if (inputElement.files.length == 1 && inputElement.files[0].name.length > 0) {
            if (confirm('Are you sure you want to restore the settings?\n\nNote: Existing settings will be replaced.')) {
                var fileReader = new FileReader();
                fileReader.onload = function (e) {
                    try {
                        var decodedData = $window.atob(e.target.result),
                            options = angular.fromJson(decodedData);

                        OptionsService.saveImportedOptions(options);
                        $scope.$apply(function () {
                            $scope.messages.error = false;
                            $scope.messages.success = true;
                        });
                    }
                    catch (e) {
                        $scope.$apply(function () {
                            $scope.messages.errorMessage = 'Error importing from file: ' + e.toString();
                            $scope.messages.error = true;
                        });
                        console.error(e);
                    }
                };
                fileReader.onerror = function () {
                    $scope.$apply(function () {
                        $scope.messages.errorMessage = 'Error reading backup file.';
                        $scope.messages.error = true;
                    });
                };
                fileReader.readAsText(inputElement.files[0]);
            }
        }
    };
}]);<commit_msg>Support non Latin chars in Export and Import.<commit_after>app.controller('BackupAndRestoreController', ['$scope', '$route', '$window', 'OptionsService', function ($scope, $route, $window, OptionsService) {
    $scope.messages = { success: false, error: false, errorMessage: null };

    $scope.openFileDialog = function () {
        var element = angular.element('#restoreFileSelector');
        element.trigger('click');
    };

    $scope.exportSettings = function () {
        var options = OptionsService.getOptions(),
            encodedData = $scope.utf8_to_b64(angular.toJson(options)),
            dateStamp = moment().format('YYYY-MM-DD');

        try {
            var blob = new Blob([encodedData], {type: 'text/plain;charset=utf-8'});
            saveAs(blob, 'form-filler-' + dateStamp + '.txt');
        } catch (e) {
            $scope.messages.errorMessage = 'Error creating a backup file: ' + e.toString();
            $scope.messages.error = true;
            console.error(e);
        }
    };

    $scope.importSettings = function ($event) {
        var inputElement = $event.target;
        if (inputElement.files.length == 1 && inputElement.files[0].name.length > 0) {
            if (confirm('Are you sure you want to restore the settings?\n\nNote: Existing settings will be replaced.')) {
                var fileReader = new FileReader();
                fileReader.onload = function (e) {
                    try {
                        var decodedData = $scope.b64_to_utf8(e.target.result),
                            options = angular.fromJson(decodedData);

                        OptionsService.saveImportedOptions(options);
                        $scope.$apply(function () {
                            $scope.messages.error = false;
                            $scope.messages.success = true;
                        });
                    }
                    catch (e) {
                        $scope.$apply(function () {
                            $scope.messages.errorMessage = 'Error importing from file: ' + e.toString();
                            $scope.messages.error = true;
                        });
                        console.error(e);
                    }
                };
                fileReader.onerror = function () {
                    $scope.$apply(function () {
                        $scope.messages.errorMessage = 'Error reading backup file.';
                        $scope.messages.error = true;
                    });
                };
                fileReader.readAsText(inputElement.files[0]);
            }
        }
    };

    $scope.utf8_to_b64 = function (str) {
      return $window.btoa(unescape(encodeURIComponent(str)));
    };

    $scope.b64_to_utf8 = function (str) {
      return decodeURIComponent(escape($window.atob(str)));
    };
}]);
<|endoftext|>