<commit_before>/**
 * @author fernandojsg / http://fernandojsg.com
 * @author Takahiro https://github.com/takahirox
 */

import { WebGLMultiviewRenderTarget } from '../WebGLMultiviewRenderTarget.js';
import { Matrix3 } from '../../math/Matrix3.js';
import { Matrix4 } from '../../math/Matrix4.js';
import { Vector2 } from '../../math/Vector2.js';

function WebGLMultiview( renderer, requested, options ) {

	options = Object.assign( {}, { debug: false }, options );

	var DEFAULT_NUMVIEWS = 2;
	var gl = renderer.context;
	var capabilities = renderer.capabilities;
	var properties = renderer.properties;

	var renderTarget, currentRenderTarget;
	var mat3, mat4, cameraArray, renderSize;

	function getMaxViews() {

		return capabilities.maxMultiviewViews;

	}

	function getNumViews() {

		if ( renderTarget && renderer.getRenderTarget() === renderTarget ) {

			return renderTarget.numViews;

		}

		return 0;

	}

	function getCameraArray( camera ) {

		if ( camera.isArrayCamera ) return camera.cameras;

		cameraArray[ 0 ] = camera;

		return cameraArray;

	}

	//

	function isAvailable() {

		return capabilities.multiview;

	}

	function isEnabled() {

		return requested && isAvailable();

	}

	if ( options.debug ) {

		if ( requested && ! isAvailable() ) {

			console.warn( 'WebGLRenderer: Multiview requested but not supported by the browser' );

		} else if ( requested !== false && isAvailable() ) {

			console.info( 'WebGLRenderer: Multiview enabled' );

		}

	}

	function updateCameraProjectionMatricesUniform( camera, uniforms ) {

		var cameras = getCameraArray( camera );

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

			mat4[ i ].copy( cameras[ i ].projectionMatrix );

		}

		uniforms.setValue( gl, 'projectionMatrices', mat4 );

	}

	function updateCameraViewMatricesUniform( camera, uniforms ) {

		var cameras = getCameraArray( camera );

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

			mat4[ i ].copy( cameras[ i ].matrixWorldInverse );

		}

		uniforms.setValue( gl, 'viewMatrices', mat4 );

	}

	function updateObjectMatricesUniforms( object, camera, uniforms ) {

		var cameras = getCameraArray( camera );

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

			mat4[ i ].multiplyMatrices( cameras[ i ].matrixWorldInverse, object.matrixWorld );
			mat3[ i ].getNormalMatrix( mat4[ i ] );

		}

		uniforms.setValue( gl, 'modelViewMatrices', mat4 );
		uniforms.setValue( gl, 'normalMatrices', mat3 );

	}

	function resizeRenderTarget( camera ) {

		if ( currentRenderTarget ) {

			renderSize.set( currentRenderTarget.width, currentRenderTarget.height );

		} else {

			renderer.getDrawingBufferSize( renderSize );

		}

		if ( camera.isArrayCamera ) {

			var bounds = camera.cameras[ 0 ].bounds;

			renderTarget.setSize( bounds.z * renderSize.x, bounds.w * renderSize.y );
			renderTarget.setNumViews( camera.cameras.length );

		} else {

			renderTarget.setSize( renderSize.x, renderSize.y );
			renderTarget.setNumViews( DEFAULT_NUMVIEWS );

		}

	}

	function attachRenderTarget( camera ) {

		currentRenderTarget = renderer.getRenderTarget();
		resizeRenderTarget( camera );
		renderer.setRenderTarget( renderTarget );

	}

	function detachRenderTarget( camera ) {

		renderer.setRenderTarget( currentRenderTarget );
		flush( camera );

	}

	function flush( camera ) {

		var srcRenderTarget = renderTarget;
		var numViews = srcRenderTarget.numViews;

		var srcFramebuffers = properties.get( srcRenderTarget ).__webglViewFramebuffers;

		var viewWidth = srcRenderTarget.width;
		var viewHeight = srcRenderTarget.height;

		if ( camera.isArrayCamera ) {

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

				var bounds = camera.cameras[ i ].bounds;

				var x1 = bounds.x * renderSize.x;
				var y1 = bounds.y * renderSize.y;
				var x2 = x1 + bounds.z * renderSize.x;
				var y2 = y1 + bounds.w * renderSize.y;

				gl.bindFramebuffer( gl.READ_FRAMEBUFFER, srcFramebuffers[ i ] );
				gl.blitFramebuffer( 0, 0, viewWidth, viewHeight, x1, y1, x2, y2, gl.COLOR_BUFFER_BIT, gl.NEAREST );

			}

		} else {

			gl.bindFramebuffer( gl.READ_FRAMEBUFFER, srcFramebuffers[ 0 ] );
			gl.blitFramebuffer( 0, 0, viewWidth, viewHeight, 0, 0, renderSize.x, renderSize.y, gl.COLOR_BUFFER_BIT, gl.NEAREST );

		}

	}

	if ( isEnabled() ) {

		renderTarget = new WebGLMultiviewRenderTarget( 0, 0, DEFAULT_NUMVIEWS );

		renderSize = new Vector2();
		mat4 = [];
		mat3 = [];
		cameraArray = [];

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

			mat4[ i ] = new Matrix4();
			mat3[ i ] = new Matrix3();

		}

	}

	this.attachRenderTarget = attachRenderTarget;
	this.detachRenderTarget = detachRenderTarget;
	this.isAvailable = isAvailable;
	this.isEnabled = isEnabled;
	this.getNumViews = getNumViews;
	this.updateCameraProjectionMatricesUniform = updateCameraProjectionMatricesUniform;
	this.updateCameraViewMatricesUniform = updateCameraViewMatricesUniform;
	this.updateObjectMatricesUniforms = updateObjectMatricesUniforms;

}

export { WebGLMultiview };
<commit_msg>Check if camera is compatible with multiview<commit_after>/**
 * @author fernandojsg / http://fernandojsg.com
 * @author Takahiro https://github.com/takahirox
 */

import { WebGLMultiviewRenderTarget } from '../WebGLMultiviewRenderTarget.js';
import { Matrix3 } from '../../math/Matrix3.js';
import { Matrix4 } from '../../math/Matrix4.js';
import { Vector2 } from '../../math/Vector2.js';

function WebGLMultiview( renderer, requested, options ) {

	options = Object.assign( {}, { debug: false }, options );

	var DEFAULT_NUMVIEWS = 2;
	var gl = renderer.context;

	var maxNumViews = capabilities.maxMultiviewViews;

	var capabilities = renderer.capabilities;
	var properties = renderer.properties;

	var renderTarget, currentRenderTarget;
	var mat3, mat4, cameraArray, renderSize;

	function getMaxViews() {

		return capabilities.maxMultiviewViews;

	}

	function getNumViews() {

		if ( renderTarget && renderer.getRenderTarget() === renderTarget ) {

			return renderTarget.numViews;

		}

		return 0;

	}

	function getCameraArray( camera ) {

		if ( camera.isArrayCamera ) return camera.cameras;

		cameraArray[ 0 ] = camera;

		return cameraArray;

	}

	//

	function isAvailable() {

		return capabilities.multiview;

	}

	function isEnabled() {

		return requested && isAvailable();

	}

	if ( options.debug ) {

		if ( requested && ! isAvailable() ) {

			console.warn( 'WebGLRenderer: Multiview requested but not supported by the browser' );

		} else if ( requested !== false && isAvailable() ) {

			console.info( 'WebGLRenderer: Multiview enabled' );

		}

	}

	function updateCameraProjectionMatricesUniform( camera, uniforms ) {

		var cameras = getCameraArray( camera );

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

			mat4[ i ].copy( cameras[ i ].projectionMatrix );

		}

		uniforms.setValue( gl, 'projectionMatrices', mat4 );

	}

	function updateCameraViewMatricesUniform( camera, uniforms ) {

		var cameras = getCameraArray( camera );

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

			mat4[ i ].copy( cameras[ i ].matrixWorldInverse );

		}

		uniforms.setValue( gl, 'viewMatrices', mat4 );

	}

	function updateObjectMatricesUniforms( object, camera, uniforms ) {

		var cameras = getCameraArray( camera );

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

			mat4[ i ].multiplyMatrices( cameras[ i ].matrixWorldInverse, object.matrixWorld );
			mat3[ i ].getNormalMatrix( mat4[ i ] );

		}

		uniforms.setValue( gl, 'modelViewMatrices', mat4 );
		uniforms.setValue( gl, 'normalMatrices', mat3 );

	}

	function isMultiviewCompatible( camera ) {

		if ( ! camera.isArrayCamera ) return true;

		var cameras = camera.cameras;

		if ( cameras.length > maxNumViews ) return false;

		for ( var i = 1, il = cameras.length; i < il; i ++ ) {

			if ( cameras[ 0 ].bounds.z !== cameras[ i ].bounds.z ||
				cameras[ 0 ].bounds.w !== cameras[ i ].bounds.w ) return false;

		}

		return true;

	}

	function resizeRenderTarget( camera ) {

		if ( currentRenderTarget ) {

			renderSize.set( currentRenderTarget.width, currentRenderTarget.height );

		} else {

			renderer.getDrawingBufferSize( renderSize );

		}

		if ( camera.isArrayCamera ) {

			var bounds = camera.cameras[ 0 ].bounds;

			renderTarget.setSize( bounds.z * renderSize.x, bounds.w * renderSize.y );
			renderTarget.setNumViews( camera.cameras.length );

		} else {

			renderTarget.setSize( renderSize.x, renderSize.y );
			renderTarget.setNumViews( DEFAULT_NUMVIEWS );

		}

	}

	function attachRenderTarget( camera ) {

		if ( ! isMultiviewCompatible( camera ) ) return;

		currentRenderTarget = renderer.getRenderTarget();
		resizeRenderTarget( camera );
		renderer.setRenderTarget( renderTarget );

	}

	function detachRenderTarget( camera ) {

		if ( renderTarget !== renderer.getRenderTarget() ) return false;

		renderer.setRenderTarget( currentRenderTarget );
		flush( camera );

	}

	function flush( camera ) {

		var srcRenderTarget = renderTarget;
		var numViews = srcRenderTarget.numViews;

		var srcFramebuffers = properties.get( srcRenderTarget ).__webglViewFramebuffers;

		var viewWidth = srcRenderTarget.width;
		var viewHeight = srcRenderTarget.height;

		if ( camera.isArrayCamera ) {

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

				var bounds = camera.cameras[ i ].bounds;

				var x1 = bounds.x * renderSize.x;
				var y1 = bounds.y * renderSize.y;
				var x2 = x1 + bounds.z * renderSize.x;
				var y2 = y1 + bounds.w * renderSize.y;

				gl.bindFramebuffer( gl.READ_FRAMEBUFFER, srcFramebuffers[ i ] );
				gl.blitFramebuffer( 0, 0, viewWidth, viewHeight, x1, y1, x2, y2, gl.COLOR_BUFFER_BIT, gl.NEAREST );

			}

		} else {

			gl.bindFramebuffer( gl.READ_FRAMEBUFFER, srcFramebuffers[ 0 ] );
			gl.blitFramebuffer( 0, 0, viewWidth, viewHeight, 0, 0, renderSize.x, renderSize.y, gl.COLOR_BUFFER_BIT, gl.NEAREST );

		}

	}

	if ( isEnabled() ) {

		renderTarget = new WebGLMultiviewRenderTarget( 0, 0, DEFAULT_NUMVIEWS );

		renderSize = new Vector2();
		mat4 = [];
		mat3 = [];
		cameraArray = [];

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

			mat4[ i ] = new Matrix4();
			mat3[ i ] = new Matrix3();

		}

	}

	this.attachRenderTarget = attachRenderTarget;
	this.detachRenderTarget = detachRenderTarget;
	this.isAvailable = isAvailable;
	this.isEnabled = isEnabled;
	this.getNumViews = getNumViews;
	this.updateCameraProjectionMatricesUniform = updateCameraProjectionMatricesUniform;
	this.updateCameraViewMatricesUniform = updateCameraViewMatricesUniform;
	this.updateObjectMatricesUniforms = updateObjectMatricesUniforms;

}

export { WebGLMultiview };
<|endoftext|>


<commit_before>'use strict'
var yo = require('yo-yo')
var csjs = require('csjs-inject')
var css = csjs`
  .li_tv {
    list-style-type: none;
    -webkit-margin-before: 0px;
    -webkit-margin-after: 0px;
    -webkit-margin-start: 0px;
    -webkit-margin-end: 0px;
    -webkit-padding-start: 0px;
    margin-left: 10px;
  }
  .ul_tv {
    list-style-type: none;
    -webkit-margin-before: 0px;
    -webkit-margin-after: 0px;
    -webkit-margin-start: 0px;
    -webkit-margin-end: 0px;
    -webkit-padding-start: 0px;
  }
  .caret_tv {
    margin-top: 3px;
    width: 10px;
  }
  .label_tv {
    display: flex;
    align-items: center;
  }
`

var remixLib = require('remix-lib')
var EventManager = remixLib.EventManager

/**
 * TreeView
 *  - extendable by specifying custom `extractData` and `formatSelf` function
 *  - trigger `nodeClick` and `leafClick`
 */
class TreeView {

  constructor (opts) {
    this.event = new EventManager()
    this.extractData = opts.extractData || this.extractDataDefault
    this.formatSelf = opts.formatSelf || this.formatSelfDefault
    this.view = null
    this.nodes = {}
    this.labels = {}
    this.carets = {}
  }

  render (json, expand) {
    var view = this.renderProperties(json, expand)
    if (!this.view) {
      this.view = view
    }
    return view
  }

  update (json) {
    if (this.view) {
      yo.update(this.view, this.render(json))
    }
  }

  renderObject (item, parent, key, expand, keyPath) {
    var data = this.extractData(item, parent, key)
    var children = (data.children || []).map((child, index) => {
      return this.renderObject(child.value, data, child.key, expand, keyPath + '/' + child.key)
    })
    return this.formatData(key, data, children, expand, keyPath)
  }

  renderProperties (json, expand) {
    var children = Object.keys(json).map((innerkey) => {
      return this.renderObject(json[innerkey], json, innerkey, expand, innerkey)
    })
    return yo`<ul class="${css.ul_tv}">${children}</ul>`
  }

  formatData (key, data, children, expand, keyPath) {
    var self = this
    var li = yo`<li class=${css.li_tv}></li>`
    var caret = yo`<div class="fa fa-caret-right ${css.caret_tv}"></div>`
    var label = yo`

        ${caret}
        ${self.formatSelf(key, data, li)}

`
    li.appendChild(label)
    if (data.children) {
      var list = yo`<ul class=${css.ul_tv}>${children}</ul>`
      this.nodes[keyPath] = list
      this.labels[keyPath] = label
      this.carets[keyPath] = caret
      list.style.display = 'none'
      caret.className = list.style.display === 'none' ? 'fa fa-caret-right' : 'fa fa-caret-down'
      label.onclick = function () {
        self.expand(keyPath)
      }
      li.appendChild(list)
    } else {
      caret.style.visibility = 'hidden'
    }
    return li
  }

  expand (path) {
    if (this.labels[path]) {
      this.carets[path].className = this.carets[path].className === 'fa fa-caret-right' ? 'fa fa-caret-down' : 'fa fa-caret-right'
      this.nodes[path].style.display = this.nodes[path].style.display === 'none' ? 'block' : 'none'
      this.event.trigger('nodeClick', [path, this.nodes[path]])
    }
  }

  nodeAt (path) {
    return this.nodes[path]
  }

  formatSelfDefault (key, data) {
    return yo`<label>${key}: ${data.self}</label>`
  }

  extractDataDefault (item, parent, key) {
    var ret = {}
    if (item instanceof Array) {
      ret.children = item.map((item, index) => {
        return {key: index, value: item}
      })
      ret.self = 'Array'
      ret.isNode = true
      ret.isLeaf = false
    } else if (item instanceof Object) {
      ret.children = Object.keys(item).map((key) => {
        return {key: key, value: item[key]}
      })
      ret.self = 'Object'
      ret.isNode = true
      ret.isLeaf = false
    } else {
      ret.self = item
      ret.children = []
      ret.isNode = false
      ret.isLeaf = true
    }
    return ret
  }
}

module.exports = TreeView
<commit_msg>add isExpanded && updateNode function<commit_after>'use strict'
var yo = require('yo-yo')
var csjs = require('csjs-inject')
var css = csjs`
  .li_tv {
    list-style-type: none;
    -webkit-margin-before: 0px;
    -webkit-margin-after: 0px;
    -webkit-margin-start: 0px;
    -webkit-margin-end: 0px;
    -webkit-padding-start: 0px;
    margin-left: 10px;
  }
  .ul_tv {
    list-style-type: none;
    -webkit-margin-before: 0px;
    -webkit-margin-after: 0px;
    -webkit-margin-start: 0px;
    -webkit-margin-end: 0px;
    -webkit-padding-start: 0px;
  }
  .caret_tv {
    margin-top: 3px;
    width: 10px;
  }
  .label_tv {
    display: flex;
    align-items: center;
  }
`

var remixLib = require('remix-lib')
var EventManager = remixLib.EventManager

/**
 * TreeView
 *  - extendable by specifying custom `extractData` and `formatSelf` function
 *  - trigger `nodeClick` and `leafClick`
 */
class TreeView {

  constructor (opts) {
    this.event = new EventManager()
    this.extractData = opts.extractData || this.extractDataDefault
    this.formatSelf = opts.formatSelf || this.formatSelfDefault
    this.view = null
    this.nodes = {}
    this.labels = {}
    this.carets = {}
  }

  render (json, expand) {
    var view = this.renderProperties(json, expand)
    if (!this.view) {
      this.view = view
    }
    return view
  }

  update (json) {
    if (this.view) {
      yo.update(this.view, this.render(json))
    }
  }

  renderObject (item, parent, key, expand, keyPath) {
    var data = this.extractData(item, parent, key)
    var children = (data.children || []).map((child, index) => {
      return this.renderObject(child.value, data, child.key, expand, keyPath + '/' + child.key)
    })
    return this.formatData(key, data, children, expand, keyPath)
  }

  renderProperties (json, expand) {
    var children = Object.keys(json).map((innerkey) => {
      return this.renderObject(json[innerkey], json, innerkey, expand, innerkey)
    })
    return yo`<ul class="${css.ul_tv}">${children}</ul>`
  }

  formatData (key, data, children, expand, keyPath) {
    var self = this
    var li = yo`<li class=${css.li_tv}></li>`
    var caret = yo`<div class="fa fa-caret-right ${css.caret_tv}"></div>`
    var label = yo`

        ${caret}
        ${self.formatSelf(key, data, li)}

`
    li.appendChild(label)
    if (data.children) {
      var list = yo`<ul class=${css.ul_tv}>${children}</ul>`
      this.nodes[keyPath] = list
      this.labels[keyPath] = label
      this.carets[keyPath] = caret
      list.style.display = 'none'
      caret.className = list.style.display === 'none' ? 'fa fa-caret-right' : 'fa fa-caret-down'
      label.onclick = function () {
        self.expand(keyPath)
      }
      li.appendChild(list)
    } else {
      caret.style.visibility = 'hidden'
    }
    return li
  }

  isExpanded (path) {
    var current = this.nodeAt(path)
    if (current) {
      return current.style.display !== 'none'
    }
    return false
  }

  expand (path) {
    if (this.labels[path]) {
      this.carets[path].className = this.carets[path].className === 'fa fa-caret-right' ? 'fa fa-caret-down' : 'fa fa-caret-right'
      this.nodes[path].style.display = this.nodes[path].style.display === 'none' ? 'block' : 'none'
      this.event.trigger('nodeClick', [path, this.nodes[path]])
    }
  }

  nodeAt (path) {
    return this.nodes[path]
  }

  updateNode (path, newNode) {
    var current = this.nodeAt(path)
    if (current) {
      var parent = current.parentNode
      if (parent) {
        parent.replaceChild(newNode, current)
        this.nodes[path] = newNode
      }
    }
  }

  formatSelfDefault (key, data) {
    return yo`<label>${key}: ${data.self}</label>`
  }

  extractDataDefault (item, parent, key) {
    var ret = {}
    if (item instanceof Array) {
      ret.children = item.map((item, index) => {
        return {key: index, value: item}
      })
      ret.self = 'Array'
      ret.isNode = true
      ret.isLeaf = false
    } else if (item instanceof Object) {
      ret.children = Object.keys(item).map((key) => {
        return {key: key, value: item[key]}
      })
      ret.self = 'Object'
      ret.isNode = true
      ret.isLeaf = false
    } else {
      ret.self = item
      ret.children = []
      ret.isNode = false
      ret.isLeaf = true
    }
    return ret
  }
}

module.exports = TreeView
<|endoftext|>


<commit_before>'use strict';

var $ = require('jquery'),
    _ = require('underscore'),
    React = require('react'),
    asset = require('../../core/utils').asset;

var DropdownMenu = React.createBackboneClass({
    menuItems: [
        { id: 'library', name: 'Library', url: '/', icon: 'rf-icon-book' },
        '---',
        { id: 'account', name: 'Account', url: '/account', icon: 'rf-icon-user' },
        { id: 'logout', name: 'Logout', url: '/logout', icon: 'rf-icon-logout' }
    ],

    componentDidMount: function() {
        $('#dl-menu').dlmenu();
    },

    componentWillUnmount: function() {
        $('#dl-menu').off('.dlmenu');
    },

    render: function() {
        var selected = this.props.selected || 'library',
            selectedItem = _.find(this.menuItems, { id: selected });
        return (

                    <button className="dl-trigger">

                        {selectedItem.name}
                    </button>

                        {/*

 Mosaic Projects

                            New Mosaic Project
                            Project Name 6
                            Project Name 2
                            Project Name 1

                            More Mosaic Projects

New Mosaic Project

Project Name 1

Project Name 2

Project Name 3

Project Name 4

Project Name 5

Project Name 6

                        */}
                        {this.menuItems.map(function(item) {
                            if (item === '---') {
                                return

;
                            }
                            return (

                                     {item.name}

                            );
                        })}

        );
    }
});

var HeaderMenu = React.createBackboneClass({
    render: function() {
        var selected = this.props.selected;
        return (

                {this.props.items.map(function(item) {
                    return {item.name};
                })}

       );
    }
});

module.exports = {
    DropdownMenu: DropdownMenu,
    HeaderMenu: HeaderMenu
};
<commit_msg>Confirm logout if uploading<commit_after>'use strict';

var $ = require('jquery'),
    _ = require('underscore'),
    React = require('react'),
    asset = require('../../core/utils').asset,
    router = require('../../router').router,
    settings = require('../../settings');

function confirmLogout(e) {
    e.preventDefault();
    var pendingLayers = settings.getPendingLayers(),
        confirmMessage = 'Leaving this page will cancel uploads in progress.';
    if (!pendingLayers.existsUploading() || confirm(confirmMessage)) {
        router.go('/logout');
    }
}

var DropdownMenu = React.createBackboneClass({
    menuItems: [
        { id: 'library', name: 'Library', url: '/', icon: 'rf-icon-book' },
        '---',
        { id: 'account', name: 'Account', url: '/account', icon: 'rf-icon-user' },
        { id: 'logout', name: 'Logout', url: '#', onClick: confirmLogout, icon: 'rf-icon-logout' }
    ],

    componentDidMount: function() {
        $('#dl-menu').dlmenu();
    },

    componentWillUnmount: function() {
        $('#dl-menu').off('.dlmenu');
    },

    render: function() {
        var selected = this.props.selected || 'library',
            selectedItem = _.find(this.menuItems, { id: selected });
        return (

                    <button className="dl-trigger">

                        {selectedItem.name}
                    </button>

                        {/*

 Mosaic Projects

                            New Mosaic Project
                            Project Name 6
                            Project Name 2
                            Project Name 1

                            More Mosaic Projects

New Mosaic Project

Project Name 1

Project Name 2

Project Name 3

Project Name 4

Project Name 5

Project Name 6

                        */}
                        {this.menuItems.map(function(item) {
                            if (item === '---') {
                                return

;
                            }
                            return (

                                     {item.name}

                            );
                        })}

        );
    }
});

var HeaderMenu = React.createBackboneClass({
    render: function() {
        var selected = this.props.selected;
        return (

                {this.props.items.map(function(item) {
                    return {item.name};
                })}

       );
    }
});

module.exports = {
    DropdownMenu: DropdownMenu,
    HeaderMenu: HeaderMenu
};
<|endoftext|>


<commit_before><commit_msg>Cleanup in the parsers.<commit_after><|endoftext|>


<commit_before>// ==UserScript==
// @name  		Dollchan Extension Tools
// @version			2011-12-14
// @namespace		http://www.freedollchan.org/scripts
// @author			Sthephan Shinkufag @ FreeDollChan
// @copyright		(C)2084, Bender Bending Rodriguez
// @description		Doing some profit for imageboards
// @updateURL		https://github.com/SthephanShinkufag/Dollchan-Extension-Tools/raw/master/Dollchan_Extension_Tools.meta.js
// @include			*
// ==/UserScript==<commit_msg>Version upd.<commit_after>// ==UserScript==
// @name  		Dollchan Extension Tools
// @version			2011-12-19
// @namespace		http://www.freedollchan.org/scripts
// @author			Sthephan Shinkufag @ FreeDollChan
// @copyright		(C)2084, Bender Bending Rodriguez
// @description		Doing some profit for imageboards
// @updateURL		https://github.com/SthephanShinkufag/Dollchan-Extension-Tools/raw/master/Dollchan_Extension_Tools.meta.js
// @include			*
// ==/UserScript==<|endoftext|>


<commit_before>function (user, context, callback) {
  // dictionary of applications and their related mozillians groups to worry about

  const applicationGroupMapping = {
    'EnEylt4OZW6i7yCWzZmCxyCxDRp6lOY0': 'mozilliansorg_ghe_saml-test-integrations_users',
  };

  const fetch = require('node-fetch@2.6.0');
  const AUTH0_TIMEOUT = 5000;  // milliseconds
  const PERSONAPI_BEARER_TOKEN_REFRESH_AGE = 64770;  // 18 hours - 30 seconds for refresh timeout allowance
  const PERSONAPI_TIMEOUT = 5000;  // milliseconds
  const USER_ID = context.primaryUser || user.user_id;
  const getBearerToken = async () => {
    // if we have the bearer token stored, we don't need to fetch it again
   if (global.personapi_bearer_token &&
        global.personapi_bearer_token_creation_time &&
        Date.now() - global.personapi_bearer_token_creation_time < PERSONAPI_BEARER_TOKEN_REFRESH_AGE) {
      return global.personapi_bearer_token;
   }

    const options = {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      timeout: AUTH0_TIMEOUT,
      body: JSON.stringify({
        audience: configuration.personapi_audience,
        client_id: configuration.personapi_client_id,
        client_secret: configuration.personapi_secret_id,
        grant_type: 'client_credentials',
      })
    };

    try {
      //console.log(configuration.personapi_oauth_url);
      const response = await fetch(configuration.personapi_oauth_url, options);
      const data = await response.json();
      // store the bearer token in the global object, so it's not constantly retrieved
      global.personapi_bearer_token = data.access_token;
      global.personapi_bearer_token_creation_time = Date.now();

      console.log(`Successfully retrieved bearer token from Auth0`);
      return global.personapi_bearer_token;
    } catch (error) {
      throw Error(`Unable to retrieve bearer token from Auth0: ${error.message}`);
    }
  };

const getPersonProfile = async () => {
    // Retrieve a bearer token to gain access to the person api
    // return the profile data
    const bearer = await getBearerToken();
    const options = {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${bearer}`,
      },
      timeout: PERSONAPI_TIMEOUT,
    };

    const url = `${configuration.personapi_url}/v2/user/user_id/${encodeURI(USER_ID)}`;
    //console.log(`Fetching person profile of ${USER_ID}`);
    //console.log("url is " + url);
    const response = await fetch(url, options);
    return await response.json();
};

  // We only care about SSO applications that exist in the applicationGroupMapping
  // If the SSO ID is undefined in applicationGroupMapping, skip processing and return callback()

  if(applicationGroupMapping[context.clientID] !== undefined) {
        getPersonProfile().then(profile => {
          let githubUsername = null;
          // Get githubUsername from person api, otherwise we'll redirect
          try {
            githubUsername = profile.usernames.values['HACK#GITHUB'];
            // If somehow dinopark allows a user to store an empty value
            // Let's set to null to be redirected later
            if(githubUsername.length === 0) {
              console.log("empty HACK#GITHUB");
              githubUsername = null;
            }
            //console.log("githubUsername: " +  githubUsername);
          } catch (e) {
            // Unable to do the githubUsername lookup
          }

          // Confirm the user has the group defined from mozillians matching the application id
          // confirm the user has a githubUsername stored in mozillians, otherwise redirect
          if(!user.app_metadata.groups.includes(applicationGroupMapping[context.clientID]) || githubUsername === null){
            context.redirect = {
               url: configuration.github_enterprise_wiki_url
             };
          }
          return callback(null, user, context);
        });

  // Nothing matched, return callback() and proceed rules processing
  } else {
    return callback(null, user, context);
  }
}
<commit_msg>Setting proper and tested person api credentials in rule<commit_after>function (user, context, callback) {
  // dictionary of applications and their related mozillians groups to worry about

  const applicationGroupMapping = {
    'EnEylt4OZW6i7yCWzZmCxyCxDRp6lOY0': 'mozilliansorg_ghe_saml-test-integrations_users',
  };

  const fetch = require('node-fetch@2.6.0');
  const AUTH0_TIMEOUT = 5000;  // milliseconds
  const PERSONAPI_BEARER_TOKEN_REFRESH_AGE = 64770;  // 18 hours - 30 seconds for refresh timeout allowance
  const PERSONAPI_TIMEOUT = 5000;  // milliseconds
  const USER_ID = context.primaryUser || user.user_id;
  const getBearerToken = async () => {
    // if we have the bearer token stored, we don't need to fetch it again
   if (global.personapi_bearer_token &&
        global.personapi_bearer_token_creation_time &&
        Date.now() - global.personapi_bearer_token_creation_time < PERSONAPI_BEARER_TOKEN_REFRESH_AGE) {
      return global.personapi_bearer_token;
   }

    const options = {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      timeout: AUTH0_TIMEOUT,
      body: JSON.stringify({
        audience: configuration.personapi_audience,
        client_id: configuration.personapi_read_profile_api_client_id,
        client_secret: configuration.personapi_read_profile_api_secret,
        grant_type: 'client_credentials',
      })
    };

    try {
      //console.log(configuration.personapi_oauth_url);
      const response = await fetch(configuration.personapi_oauth_url, options);
      const data = await response.json();
      // store the bearer token in the global object, so it's not constantly retrieved
      global.personapi_bearer_token = data.access_token;
      global.personapi_bearer_token_creation_time = Date.now();

      console.log(`Successfully retrieved bearer token from Auth0`);
      return global.personapi_bearer_token;
    } catch (error) {
      throw Error(`Unable to retrieve bearer token from Auth0: ${error.message}`);
    }
  };

const getPersonProfile = async () => {
    // Retrieve a bearer token to gain access to the person api
    // return the profile data
    const bearer = await getBearerToken();
    const options = {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${bearer}`,
      },
      timeout: PERSONAPI_TIMEOUT,
    };

    const url = `${configuration.personapi_url}/v2/user/user_id/${encodeURI(USER_ID)}`;
    //console.log(`Fetching person profile of ${USER_ID}`);
    //console.log("url is " + url);
    const response = await fetch(url, options);
    return await response.json();
};

  // We only care about SSO applications that exist in the applicationGroupMapping
  // If the SSO ID is undefined in applicationGroupMapping, skip processing and return callback()

  if(applicationGroupMapping[context.clientID] !== undefined) {
        getPersonProfile().then(profile => {
          let githubUsername = null;
          // Get githubUsername from person api, otherwise we'll redirect
          try {
            githubUsername = profile.usernames.values['HACK#GITHUB'];
            // If somehow dinopark allows a user to store an empty value
            // Let's set to null to be redirected later
            if(githubUsername.length === 0) {
              console.log("empty HACK#GITHUB");
              githubUsername = null;
            }
            //console.log("githubUsername: " +  githubUsername);
          } catch (e) {
            // Unable to do the githubUsername lookup
          }

          // Confirm the user has the group defined from mozillians matching the application id
          // confirm the user has a githubUsername stored in mozillians, otherwise redirect
          if(!user.app_metadata.groups.includes(applicationGroupMapping[context.clientID]) || githubUsername === null){
            context.redirect = {
               url: configuration.github_enterprise_wiki_url
             };
          }
          return callback(null, user, context);
        });

  // Nothing matched, return callback() and proceed rules processing
  } else {
    return callback(null, user, context);
  }
}
<|endoftext|>


<commit_before>#! /usr/bin/env node

var _      = require("lodash")
 , Bundle  = require("../plugins/bundle")
 , config  = require("../plugins/config")
 , program = require('commander');

program
  .version('0.1.0')
  .option('-e, --external <modules>', 'external modules', "externals")
  .option('-f, --factorbundle', "use factor bundle")
  .option('-m, --minify' , 'minify scripts')
  .option('-s, --input <name>', 'input file')
  .option('-o, --outputFile <name>', 'output file')
  .option('-i, --ignore', 'ignore <modules>', "ignore", [])
  .option('-r, --required', 'required <modules>', "required", [])
  .option('-x, --separate', 'compile file list into separate bundles')
  .option('-w, --watch', 'Watch scripts')
  .option('-v, --vendors', 'Vendor Bundle')
  .parse(process.argv);

var files;
if(program.input){
  files = program.input;
} else if(program.vendors) {
  files = []
}

var options = ["external", "factorbundle", "minify", "outputFile", "required", "separate"]

options.forEach(function(op){
  if(!_.isEmpty(program[op]) || program[op]){
    config.set(op, program[op])
  }
});

files =  files || config.get("files");

if(program.separate){
  files.forEach(function(f){
    Bundle(config.get("minify"), f)
    .setOutput(f)
    .setVendors(program.vendors)
    .setFactor(config.get("factorbundle"))
    .build(program.watch)
  })
} else {
  Bundle(config.get("minify"), files)
    .setVendors(program.vendors)
    .setFactor(config.get("factorbundle"))
    .build(program.watch)
}

<commit_msg>add production enviroment<commit_after>#! /usr/bin/env node

var _      = require("lodash")
 , Bundle  = require("../plugins/bundle")
 , config  = require("../plugins/config")
 , program = require('commander');

program
  .version('0.1.0')
  .option('-e, --external <modules>', 'external modules', "externals")
  .option('-f, --factorbundle', "use factor bundle")
  .option('-m, --minify' , 'minify scripts')
  .option('-s, --input <name>', 'input file')
  .option('-o, --outputFile <name>', 'output file')
  .option('-i, --ignore', 'ignore <modules>', "ignore", [])
  .option('-r, --required', 'required <modules>', "required", [])
  .option('-x, --separate', 'compile file list into separate bundles')
  .option('-w, --watch', 'Watch scripts')
  .option('-v, --vendors', 'Vendor Bundle')
  .option('-p, --production', 'Set production')
  .parse(process.argv);

var files;
if (program.input){
  files = program.input;
} else if(program.vendors) {
  files = []
}

if (program.production){
   process.env.NODE_ENV = 'production';
}

var options = ["external", "factorbundle", "minify", "outputFile", "required", "separate"]

options.forEach(function(op){
  if(!_.isEmpty(program[op]) || program[op]){
    config.set(op, program[op])
  }
});

files =  files || config.get("files");

if(program.separate){
  files.forEach(function(f){
    Bundle(config.get("minify"), f)
    .setOutput(f)
    .setVendors(program.vendors)
    .setFactor(config.get("factorbundle"))
    .build(program.watch)
  })
} else {
  Bundle(config.get("minify"), files)
    .setVendors(program.vendors)
    .setFactor(config.get("factorbundle"))
    .build(program.watch)
}

<|endoftext|>


<commit_before>#!/usr/bin/env node

/**
  @author Josh Perez <josh@goatslacker.com>
  @version 1.0

  @depends jshint, uglify, gzip, less
  */

const loadDefaults = function (obj, fallback) {
  Object.keys(fallback).forEach(function (key) {
    obj[key] = (typeof obj[key] === "undefined") ? fallback[key] : obj[key];
  });

  return obj;
};

const args = (function (argv) {
  var obj = {};

  argv.forEach(function (item) {
    if (item.indexOf("--") !== -1) {
      obj[item.replace("--", "")] = argv.pop();
    }
  });

  return loadDefaults(obj, { js: 'src' });
}(process.argv.splice(2)));

// Requires
const fs = require("fs");

// Forge Settings
// pulled from forge.json if it exists, otherwise uses default settings
const config = (function () {
  var options = {};

  try {
    options = JSON.parse(fs.readFileSync("forge.json"));
  } catch (e) {
  }

  return loadDefaults(options, {
    /* appName = the directory name */
    appName: (function () {
      var real = fs.realpathSync("."),
          dir = real.split("/");

      return dir.pop();
    }()),

    /* the build directory */
    buildDirectory: 'build',

    /* use lint to check the code */
    lint: true,

    /* uglify-js compresses the code */
    compress: true,

    /* apply gzip after compression */
    gzip: true,

    /* less for stylesheets */
    less: false,

    /* no logging for Forge */
    quiet: false
  });
}());

// Other requires from options given

var Forge = function (file) {
  this.fileName = file;
},

requireModule = function (module) {
  var requirement = null;

  try {
    requirement = require(module);
  } catch (e) {
    if (!config.quiet) {
      console.error(module + " is not installed. Try npm install " + module + " -g\n");
    }
  }

  return requirement;
},

jshint = null,
uglify = null,
gzip = null,
less = null;

if (config.lint) {
  jshint = requireModule("jshint");
}

if (config.compress) {
  uglify = requireModule("uglify-js");
}

if (config.gzip) {
  gzip = requireModule("gzip")
}

if (config.less) {
  less = requireModule("less");
}
// TODO jsdocs
// node module doesn't exist :(

// Forge Object
Forge.prototype = {

  forge: function (files, ext) {
    const log = (!config.quiet);

    var code = "";

    if (log) {
      console.log('\nReading...');
    }

    ext = ext || 'js';

    // loop through each file in the directory
    files.forEach(function (fileName) {
      var file = fileName + '.' + ext;

      if (log) {
        console.log('> ./' + file);
      }

      // read the contents of the files
      code = code + fs.readFileSync(file, 'utf8');
    });

    // write output file
    fs.writeFileSync(this.fileName, code);

    if (log) {
      console.log('Wrote to: ./' + this.fileName);
    }

    return code;
  },

  compress: function (code) {
    this.minFile = Forge.getBuildFile("min.js");

    const jsp = uglify.parser;
    const pro = uglify.uglify;

    const log = (!config.quiet);

    var parsed = "",
        mangled = "",
        squeeze = "",
        compressed = "";

    try {
      parsed = jsp.parse(code);
      mangled = pro.ast_mangle(parsed);
      squeeze = pro.ast_squeeze(mangled);
      compressed = pro.gen_code(squeeze);
    } catch (e) {
      // if there's any errors
    }

    if (log) {
      console.log('\nCompressing ./' + this.fileName + ' using uglify-js');
    }

    fs.writeFileSync(this.minFile, compressed);

    if (log) {
      console.log('Compressed into ./' + this.minFile);
    }
  },

  jshint: function (code) {
    const log = (!config.quiet);

    const lint = jshint.JSHINT;

    var data = "",
        self = this;

    if (log) {
      console.log('\nValidating ./' + this.fileName + ' with jshint');
    }

    // run jshint on the code
    lint(code);

    // get data
    data = lint.data();

    // if there are no errors
    if (!data.errors) {
      if (log) {
        console.log('Lint Free!');
      }

      return;
    }

    if (log) {
      console.log('\nErrors found in ' + this.fileName);
    }

    // output errors to console
    data.errors.forEach(function (error) {
      if (error) {
        console.log(self.fileName + ':' + error.line + ':' + error.character + ' ' + error.reason);
      }
    });
  },

  gzip: function () {
    this.gzipFile = Forge.getBuildFile("js.gz");

    const log = (!config.quiet);

    if (log) {
      console.log('\nApplying gzip compression');
    }

    var self = this,
        file = this.minFile || this.fileName,
        code = fs.readFileSync(file);

    gzip(code, function (err, data) {
      fs.writeFileSync(self.gzipFile, data);
    });
  }
};

Forge.getBuildFile = function (ext) {
  return config.buildDirectory + "/" + config.appName + "." + ext;
};

/** */
(function () {
  const log = (!config.quiet);

  var files = config.files ? config.files : (function () {
    var obj = {};

    Object.keys(args).forEach(function (ext) {
      var src = [];

      fs.readdirSync(args[ext]).forEach(function (file) {
        if (file.indexOf("." + ext) !== -1) {
          src.push(args[ext] + "/" + file.replace("." + ext, ""));
        }
      });

      obj[ext] = src;
    });

    return obj;
  }()),

  doForge = function (ext) {
    var buildFile = Forge.getBuildFile(ext),

        // create new forging object
        forger = new Forge(buildFile),

        // the code in all it's glory
        code = forger.forge(files[ext], ext);

    // jshint
    if (jshint) {
      forger.jshint(code);
    }

    // compress code
    if (uglify) {
      forger.compress(code);
    }

    // gzip
    if (gzip) {
      forger.gzip();
    }
  };

  if (log) {
    console.log('Forging ' + config.appName);
  }

  // create build directory
  try {
    fs.mkdirSync(config.buildDirectory, 0777);
  } catch (e) {
    // may return a file exists error...
  }

  // do forge
  Object.keys(files).forEach(doForge);

  // Done :)
  if (log) {
    console.log('\nDone!');
  }
}());
<commit_msg>basic documentation<commit_after>#!/usr/bin/env node

/**
  @author Josh Perez <josh@goatslacker.com>
  @version 1.0

  @depends jshint, uglify, gzip, less
  */

/**
  If property isn't set, it sets the default value
  @param obj {Object} the base object
  @param defaults {Object} the object with the default values
  @return {Object}
  */
const fallback = function (obj, defaults) {
  Object.keys(defaults).forEach(function (key) {
    obj[key] = (typeof obj[key] === "undefined") ? defaults[key] : obj[key];
  });

  return obj;
};

/**
  App arguments
  */
const args = (function (argv) {
  var obj = {};

  argv.forEach(function (item) {
    if (item.indexOf("--") !== -1) {
      obj[item.replace("--", "")] = argv.pop();
    }
  });

  return fallback(obj, { js: 'src' });
}(process.argv.splice(2)));

// Requires
const fs = require("fs");

/**
  Forge Settings
  pulled from forge.json if it exists, otherwise uses default settings
  */
const config = (function () {
  var options = {};

  try {
    options = JSON.parse(fs.readFileSync("forge.json"));
  } catch (e) {
  }

  return fallback(options, {
    /* appName = the directory name */
    appName: (function () {
      var real = fs.realpathSync("."),
          dir = real.split("/");

      return dir.pop();
    }()),

    /* the build directory */
    buildDirectory: 'build',

    /* use lint to check the code */
    lint: true,

    /* uglify-js compresses the code */
    compress: true,

    /* apply gzip after compression */
    gzip: true,

    /* less for stylesheets */
    less: false,

    /* no logging for Forge */
    quiet: false
  });
}());

/**
  Forges a file
  */
var Forge = function (file) {
  this.fileName = file;
},

/**
  Tries to load a module, throws a non fatal error if not found
  */
requireModule = function (module) {
  var requirement = null;

  try {
    requirement = require(module);
  } catch (e) {
    if (!config.quiet) {
      console.error(module + " is not installed. Try npm install " + module + " -g\n");
    }
  }

  return requirement;
},

jshint = null,
uglify = null,
gzip = null,
less = null;

if (config.lint) {
  jshint = requireModule("jshint");
}

if (config.compress) {
  uglify = requireModule("uglify-js");
}

if (config.gzip) {
  gzip = requireModule("gzip")
}

if (config.less) {
  less = requireModule("less");
}
// TODO jsdocs
// node module doesn't exist :(

// Forge Object
Forge.prototype = {

  forge: function (files, ext) {
    const log = (!config.quiet);

    var code = "";

    if (log) {
      console.log('\nReading...');
    }

    ext = ext || 'js';

    // loop through each file in the directory
    files.forEach(function (fileName) {
      var file = fileName + '.' + ext;

      if (log) {
        console.log('> ./' + file);
      }

      // read the contents of the files
      code = code + fs.readFileSync(file, 'utf8');
    });

    // write output file
    fs.writeFileSync(this.fileName, code);

    if (log) {
      console.log('Wrote to: ./' + this.fileName);
    }

    return code;
  },

  compress: function (code) {
    this.minFile = Forge.getBuildFile("min.js");

    const jsp = uglify.parser;
    const pro = uglify.uglify;

    const log = (!config.quiet);

    var parsed = "",
        mangled = "",
        squeeze = "",
        compressed = "";

    try {
      parsed = jsp.parse(code);
      mangled = pro.ast_mangle(parsed);
      squeeze = pro.ast_squeeze(mangled);
      compressed = pro.gen_code(squeeze);
    } catch (e) {
      // if there's any errors
    }

    if (log) {
      console.log('\nCompressing ./' + this.fileName + ' using uglify-js');
    }

    fs.writeFileSync(this.minFile, compressed);

    if (log) {
      console.log('Compressed into ./' + this.minFile);
    }
  },

  jshint: function (code) {
    const log = (!config.quiet);

    const lint = jshint.JSHINT;

    var data = "",
        self = this;

    if (log) {
      console.log('\nValidating ./' + this.fileName + ' with jshint');
    }

    // run jshint on the code
    lint(code);

    // get data
    data = lint.data();

    // if there are no errors
    if (!data.errors) {
      if (log) {
        console.log('Lint Free!');
      }

      return;
    }

    if (log) {
      console.log('\nErrors found in ' + this.fileName);
    }

    // output errors to console
    data.errors.forEach(function (error) {
      if (error) {
        console.log(self.fileName + ':' + error.line + ':' + error.character + ' ' + error.reason);
      }
    });
  },

  gzip: function () {
    this.gzipFile = Forge.getBuildFile("js.gz");

    const log = (!config.quiet);

    if (log) {
      console.log('\nApplying gzip compression');
    }

    var self = this,
        file = this.minFile || this.fileName,
        code = fs.readFileSync(file);

    gzip(code, function (err, data) {
      fs.writeFileSync(self.gzipFile, data);
    });
  }
};

Forge.getBuildFile = function (ext) {
  return config.buildDirectory + "/" + config.appName + "." + ext;
};

/** Application */
(function () {
  const log = (!config.quiet);

  /**
    @return {Array} files that need to be forged
    */
  var files = config.files ? config.files : (function () {
    var obj = {};

    Object.keys(args).forEach(function (ext) {
      var src = [];

      fs.readdirSync(args[ext]).forEach(function (file) {
        if (file.indexOf("." + ext) !== -1) {
          src.push(args[ext] + "/" + file.replace("." + ext, ""));
        }
      });

      obj[ext] = src;
    });

    return obj;
  }()),

  /**
    Forging logic
    */
  doForge = function (ext) {
    var buildFile = Forge.getBuildFile(ext),

        // create new forging object
        forger = new Forge(buildFile),

        // the code in all it's glory
        code = forger.forge(files[ext], ext);

    // jshint
    if (jshint) {
      forger.jshint(code);
    }

    // compress code
    if (uglify) {
      forger.compress(code);
    }

    // gzip
    if (gzip) {
      forger.gzip();
    }
  };

  if (log) {
    console.log('Forging ' + config.appName);
  }

  // create build directory
  try {
    fs.mkdirSync(config.buildDirectory, 0777);
  } catch (e) {
    // may return a file exists error...
  }

  // do forge
  Object.keys(files).forEach(doForge);

  // Done :)
  if (log) {
    console.log('\nDone!');
  }
}());
<|endoftext|>


<commit_before>var hoverZoomPlugins = hoverZoomPlugins || [];
hoverZoomPlugins.push({
    name:'GoogleUserContent',
    version:'1.1',
    prepareImgLinks:function (callback) {

        var res = [];

        //sample url: https://lh3.googleusercontent.com/oAO8qHLtaT5JHCvojKRL0IvjoXPM1aR22eDXh17eCsCgjeCL1_A6mIIUQD19kF3kVg=w192-c-h192-fcrop64=1,00000b5cffffdde9-rw-v1
        //         -> https://lh3.googleusercontent.com/oAO8qHLtaT5JHCvojKRL0IvjoXPM1aR22eDXh17eCsCgjeCL1_A6mIIUQD19kF3kVg=s0
        var regex1 = /(.*?=)(.*)/;
        var patch1 = '$1s0';

        //sample url: https://lh3.googleusercontent.com/-pjJcqQ567-8/AAAAAAAAAAI/AAAAAAAAAAA/AMZuuckcnEaqf2P_2Kp0ITTsXt4bzL54Ww.CMID/s32-c/photo.jpg
        //         -> https://lh3.googleusercontent.com/-pjJcqQ567-8/AAAAAAAAAAI/AAAAAAAAAAA/AMZuuckcnEaqf2P_2Kp0ITTsXt4bzL54Ww.CMID/s0/photo.jpg
        var regex2 = /(.*)\/.*\/(photo\.jpg.*){0,1}/;
        var patch2 = '$1/s0/';

        hoverZoom.urlReplace(res,
            'img[src*=".googleusercontent.com/"], img[src*=".ggpht.com/"]',
            [regex1, regex2],
            [patch1, patch2]
        );

        $('[style*=background]').each(function() {
            var link = $(this);
            // extract url from style
            var backgroundImage = this.style.backgroundImage;
            if (backgroundImage.indexOf("url") != -1 && (backgroundImage.indexOf("googleusercontent") != -1 || backgroundImage.indexOf("ggpht") != -1)) {
                var reUrl = /.*url\s*\(\s*(.*)\s*\).*/i
                backgroundImage = backgroundImage.replace(reUrl, '$1');
                // remove leading & trailing quotes
                var backgroundImageUrl = backgroundImage.replace(/^['"]/, "").replace(/['"]+$/, "");

                $([{r:regex1, p:patch1},{r:regex2, p:patch2}]).each(function() {

                    var fullsizeUrl = backgroundImageUrl.replace(this.r, this.p);
                    if (fullsizeUrl != backgroundImageUrl) {

                        if (link.data().hoverZoomSrc == undefined) { link.data().hoverZoomSrc = [] }
                        if (link.data().hoverZoomSrc.indexOf(fullsizeUrl) == -1) {
                            link.data().hoverZoomSrc.unshift(fullsizeUrl);
                            res.push(link);
                        }
                    }
                });
            }
        });

        callback($(res));
    }
});
<commit_msg>Fix for plug-in : google_a.js<commit_after>var hoverZoomPlugins = hoverZoomPlugins || [];
hoverZoomPlugins.push({
    name:'GoogleUserContent',
    version:'1.2',
    prepareImgLinks:function (callback) {

        var res = [];

        //sample url: https://lh3.googleusercontent.com/oAO8qHLtaT5JHCvojKRL0IvjoXPM1aR22eDXh17eCsCgjeCL1_A6mIIUQD19kF3kVg=w192-c-h192-fcrop64=1,00000b5cffffdde9-rw-v1
        //         -> https://lh3.googleusercontent.com/oAO8qHLtaT5JHCvojKRL0IvjoXPM1aR22eDXh17eCsCgjeCL1_A6mIIUQD19kF3kVg=s0
        var regex1 = /(.*?=)(.*)/;
        var patch1 = '$1s0';

        //sample url: https://lh3.googleusercontent.com/-pjJcqQ567-8/AAAAAAAAAAI/AAAAAAAAAAA/AMZuuckcnEaqf2P_2Kp0ITTsXt4bzL54Ww.CMID/s32-c/
        //         -> https://lh3.googleusercontent.com/-pjJcqQ567-8/AAAAAAAAAAI/AAAAAAAAAAA/AMZuuckcnEaqf2P_2Kp0ITTsXt4bzL54Ww.CMID/s0/
        //sample url: https://lh3.googleusercontent.com/-pjJcqQ567-8/AAAAAAAAAAI/AAAAAAAAAAA/AMZuuckcnEaqf2P_2Kp0ITTsXt4bzL54Ww.CMID/s32-c/photo.jpg
        //         -> https://lh3.googleusercontent.com/-pjJcqQ567-8/AAAAAAAAAAI/AAAAAAAAAAA/AMZuuckcnEaqf2P_2Kp0ITTsXt4bzL54Ww.CMID/s0/photo.jpg
        var regex2 = /(.*)\/.*\//;
        var patch2 = '$1/s0/';

        //sample url: http://geo3.ggpht.com/cbk?panoid=50XRgCiXEq6wuqYWcGQ3BQ&output=thumbnail&cb_client=search.gws-prod.gps&thumb=0&w=100&h=100&yaw=277.2657&pitch=0&thumbfov=100
        //         -> http://geo3.ggpht.com/cbk?panoid=50XRgCiXEq6wuqYWcGQ3BQ&output=thumbnail&cb_client=search.gws-prod.gps&thumb=0&w=9999&h=9999&yaw=277.2657&pitch=0&thumbfov=100
        var regex3 = /(&[hw]{1})=\d+/g;
        var patch3 = '$1=9999';

        hoverZoom.urlReplace(res,
            'img[src*=".googleusercontent.com/"], img[src*=".ggpht.com/"]',
            regex1,
            patch1
        );

        hoverZoom.urlReplace(res,
            'img[src*=".googleusercontent.com/"], img[src*=".ggpht.com/"]',
            regex2,
            patch2
        );

        hoverZoom.urlReplace(res,
            'img[src*=".googleusercontent.com/"], img[src*=".ggpht.com/"]',
            regex3,
            patch3
        );

        $('[style*=url]').each(function() {
            var link = $(this);
            // extract url from style
            var backgroundImage = this.style.backgroundImage;
            if (backgroundImage.indexOf(".googleusercontent.com") == -1 && backgroundImage.indexOf(".ggpht.com") == -1) return;
            var reUrl = /.*url\s*\(\s*(.*)\s*\).*/i
            backgroundImage = backgroundImage.replace(reUrl, '$1');
            // remove leading & trailing quotes
            var backgroundImageUrl = backgroundImage.replace(/^['"]/, "").replace(/['"]+$/, "");

            $([{r:regex1, p:patch1},{r:regex2, p:patch2},{r:regex3, p:patch3}]).each(function() {

                var fullsizeUrl = backgroundImageUrl.replace(this.r, this.p);
                if (fullsizeUrl != backgroundImageUrl) {

                    if (link.data().hoverZoomSrc == undefined) { link.data().hoverZoomSrc = [] }
                    if (link.data().hoverZoomSrc.indexOf(fullsizeUrl) == -1) {
                        link.data().hoverZoomSrc.unshift(fullsizeUrl);
                        res.push(link);
                    }
                }
            });
        });

        callback($(res), this.name);
    }
});
<|endoftext|>