<commit_before>/**
 * Algorithmia Lambda Function
 *
 * Calls any algorithm in the Algorithmia marketplace
 * Get an API key and free credits by creating an account at algorithmia.com
 */

var AWS = require('aws-sdk');
var apiKey, kmsEncryptedApiKey;

/*
 * Step 1: Set your API key below
 *  Basic method:
 *    Set apiKey to your Algorithmia API key:
 *
 *  Advanced method (more secure):
 *    Set kmsEncryptedApiKey to the encrypted value after using AWS-KMS to encrypt your key:
 *
 *    To create a kmsEncryptedApiKey:
 *    - Create a KMS key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html
 *    - Encrypt your Algorithmia API key using the AWS CLI
 *      aws kms encrypt --key-id alias/<KMS key name> --plaintext "<ALGORITHMIA_API_KEY>"
 *    - Copy the base-64 encoded, encrypted key (CiphertextBlob) to the kmsEncryptedApiKey variable
 *    - Give your function's role permission for the kms:Decrypt action.
 *      Example:
 *          {
 *              "Version": "2012-10-17",
 *              "Statement": [
 *                  {
 *                      "Sid": "Stmt1443036478000",
 *                      "Effect": "Allow",
 *                      "Action": [
 *                          "kms:Decrypt"
 *                      ],
 *                      "Resource": [
 *                          "<your KMS Key ARN>"
 *                      ]
 *                  }
 *              ]
 *          }
 */
// apiKey = "<your Algorithmia api key>";       // Basic Method
// kmsEncryptedApiKey = "<encrypted kms key>";  // Advanced Method

var processEvent = function(event, context) {
    /*
     * Step 2: Set the algorithm you want to call
     *  This may be any algorithm in the Algorithmia marketplace
    */
    var algorithm = "<ALGORITHM>"; // e.g. "algo://opencv/SmartThumbnail"

    /*
     * Step 3: Use your event source to set inputData according to the algorithm's input format
     *
     *  Example: Create 200x50 thumbnails for an S3 file event using algo://opencv/SmartThumbnail
     *           Algorithm expects input as [URL, WIDTH, HEIGHT]
     *           Output is a base64 encoding of the resulting PNG thumbnail
     *
     *      var s3 = new AWS.S3();
     *      var bucket = event.Records[0].s3.bucket.name;
     *      var key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " ")) ;
     *      var params = {Bucket: bucket, Key: key};
     *      var signedUrl = s3.getSignedUrl('getObject', params);
     *      var inputData = [signedUrl, 200, 50];
     */
    var inputData = "<INPUT_DATA>";

    // Run the algorithm
    var client = algorithmia(apiKey);
    client.algo(algorithm).pipe(inputData).then(function(output) {
        if(output.error) {
            console.log("Error: " + output.error.message);
            context.fail(output.error.message);
        } else {
            console.log(output.result);
            context.succeed(output.result);
        }
    });
}

/*
 * This is the lambda entrypoint (no modification necessary)
 *   it ensures apiKey is set (decrypting kmsEncryptedApiKey if provided)
 *   and then calls processEvent with the same event and context
 */
exports.handler = function(event, context) {
    if(kmsEncryptedApiKey) {
        var encryptedBuf = new Buffer(kmsEncryptedApiKey, 'base64');
        var cipherText = { CiphertextBlob: encryptedBuf };

        var kms = new AWS.KMS();
        kms.decrypt(cipherText, function(err, data) {
            if (err) {
                console.log("Decrypt error: " + err);
                context.fail(err);
            } else {
                apiKey = data.Plaintext.toString('ascii');
                processEvent(event, context);
            }
        });
    } else if(apiKey) {
        processEvent(event, context);
    } else {
        context.fail("API Key has not been set.")
    }
};

/*
 * Algorithmia NodeJS SDK below
 */
var Algorithm, AlgorithmiaClient, Data, algorithmia, https, url;
https = require('https');
url = require('url');

AlgorithmiaClient = (function() {
  function AlgorithmiaClient(key) {
    this.api_path = 'https://api.algorithmia.com/v1/';
    if (key.indexOf('Simple ') === 0) {
      this.api_key = key;
    } else {
      this.api_key = 'Simple ' + key;
    }
  }

  AlgorithmiaClient.prototype.algo = function(path) {
    return new Algorithm(this, path);
  };

  AlgorithmiaClient.prototype.file = function(path) {
    return new Data(this, path);
  };

  AlgorithmiaClient.prototype.req = function(path, method, data, cheaders, callback) {
    var dheader, key, options, req, val;
    dheader = {
      'Content-Type': 'application/JSON',
      'Accept': 'application/JSON',
      'Authorization': this.api_key,
      'User-Agent': 'NodeJS/' + process.version
    };
    for (key in cheaders) {
      val = cheaders[key];
      dheader[key] = val;
    }
    options = url.parse(this.api_path + path);
    options.method = method;
    options.headers = dheader;
    req = https.request(options, function(res) {
      var chunks;
      res.setEncoding('utf8');
      chunks = [];
      res.on('data', function(chunk) {
        return chunks.push(chunk);
      });
      res.on('end', function() {
        var body, buff;
        buff = chunks.join('');
        if (dheader['Accept'] === 'application/JSON') {
          body = JSON.parse(buff);
        } else {
          body = buff;
        }
        if (callback) {
          if (res.statusCode !== 200) {
            if (!body) {
              body = {};
            }
            if (!body.error) {
              body.error = {
                message: 'HTTP Response: ' + res.statusCode
              };
            }
          }
          callback(body);
        }
      });
      return res;
    });
    req.write(data);
    return req.end();
  };

  return AlgorithmiaClient;

})();

algorithmia = function(key) {
  return new AlgorithmiaClient(key);
};

Algorithm = (function() {
  function Algorithm(client, path) {
    this.client = client;
    this.algo_path = path;
  }

  Algorithm.prototype.pipe = function(params) {
    this.algo_params = params;
    if (typeof params === 'object' || typeof params === 'string') {
      this.algo_data = JSON.stringify(params);
    } else {
      this.algo_data = params + '';
    }
    return this;
  };

  Algorithm.prototype.then = function(callback) {
    return this.client.req('algo/' + this.algo_path, 'POST', this.algo_data, {}, callback);
  };

  return Algorithm;

})();

Data = (function() {
  function Data(client, path) {
    this.client = client;
    if (path.indexOf("data://") !== 0) {
      throw "Supplied path is invalid.";
    }
    this.data_path = path.replace(/data\:\/\//, "");
  }

  Data.prototype.putString = function(content, callback) {
    var headers;
    headers = {
      'Content-Type': 'text/plain'
    };
    return this.client.req('data/' + this.data_path, 'PUT', content, headers, callback);
  };

  Data.prototype.putJson = function(content, callback) {
    var headers;
    headers = {
      'Content-Type': 'application/JSON'
    };
    return this.client.req('data/' + this.data_path, 'PUT', content, headers, callback);
  };

  Data.prototype.getString = function(callback) {
    var headers;
    headers = {
      'Accept': 'text/plain'
    };
    return this.client.req('data/' + this.data_path, 'GET', "", headers, callback);
  };

  Data.prototype.getJson = function(callback) {
    var headers;
    headers = {
      'Accept': 'text/plain'
    };
    return this.client.req('data/' + this.data_path, 'GET', "", headers, callback);
  };

  return Data;

})();
<commit_msg>Update lambda blueprint again<commit_after>/**
 * Algorithmia Lambda Function
 *
 * Calls any algorithm in the Algorithmia marketplace
 * Get an API key and free credits by creating an account at algorithmia.com
 * For more documentation see: algorithmia.com/docs/clients/lambda
 *
 *
 * Follow these steps to encrypt your Algorithmia API Key for use in this function:
 *
 * 1. Create a KMS key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html
 *
 * 2. Encrypt the event collector token using the AWS CLI
 *      aws kms encrypt --key-id alias/<KMS key name> --plaintext "<ALGORITHMIA_API_KEY>"
 *
 * 3. Copy the base-64 encoded, encrypted key (CiphertextBlob) to the kmsEncryptedApiKey variable
 *
 * 4. Give your function's role permission for the kms:Decrypt action.
 * Example:

{
    "Version": "2012-10-17",
    "Statement": [
    {
        "Sid": "Stmt1443036478000",
        "Effect": "Allow",
        "Action": [
            "kms:Decrypt"
            ],
        "Resource": [
            "<your KMS key ARN>"
            ]
    }
    ]
}
 */

var AWS = require('aws-sdk');
var apiKey, kmsEncryptedApiKey;

// Enter the base-64 encoded, encrypted key (CiphertextBlob)
kmsEncryptedApiKey = "<kmsEncryptedApiKey>";

/*
 * This is the lambda entrypoint (no modification necessary)
 *   it ensures apiKey is set (decrypting kmsEncryptedApiKey if provided)
 *   and then calls processEvent with the same event and context
 */
exports.handler = function(event, context) {
    if(kmsEncryptedApiKey && kmsEncryptedApiKey !== "<kmsEncryptedApiKey>") {
        var encryptedBuf = new Buffer(kmsEncryptedApiKey, 'base64');
        var cipherText = { CiphertextBlob: encryptedBuf };

        var kms = new AWS.KMS();
        kms.decrypt(cipherText, function(err, data) {
            if (err) {
                console.log("Decrypt error: " + err);
                context.fail(err);
            } else {
                apiKey = data.Plaintext.toString('ascii');
                processEvent(event, context);
            }
        });
    } else if(apiKey) {
        processEvent(event, context);
    } else {
        context.fail("API Key has not been set.")
    }
};

/*
 * Configure your function to interact
*/
var processEvent = function(event, context) {
    /*
     * Step 1: Set the algorithm you want to call
     *  This may be any algorithm in the Algorithmia marketplace
    */
    var algorithm = "algo://demo/Hello"; // algorithmia.com/algorithms/demo/Hello

    /*
     * Step 2: Use your event source to set inputData according to the algorithm's input format
     *         This demo example uses the S3 Object's name as inputData
     */
    var inputData = event.Records[0].s3.object.key; // Example for algo://demo/Hello

    /*  Advanced example:
     *      Create 200x50 thumbnails for S3 file events using algo://opencv/SmartThumbnail
     *          Algorithm expects input as [URL, WIDTH, HEIGHT]
     *          Output is a base64 encoding of the resulting PNG thumbnail
     *
     *      var algorithm = "algo://opencv/SmartThumbnail"
     *      var s3 = new AWS.S3();
     *      var bucket = event.Records[0].s3.bucket.name;
     *      var key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " ")) ;
     *      var params = {Bucket: bucket, Key: key};
     *      var signedUrl = s3.getSignedUrl('getObject', params);
     *      var inputData = [signedUrl, 200, 50];
     */

    // Run the algorithm
    var client = algorithmia(apiKey);
    client.algo(algorithm).pipe(inputData).then(function(output) {
        if(output.error) {
            console.log("Error: " + output.error.message);
            context.fail(output.error.message);
        } else {
            /*
             * Step 3: Process the algorithm output here
             *         This demo example prints and succeeds with the algorithm result
             */
            console.log(output);
            context.succeed(output.result);
        }
    });
}

/*
 * Algorithmia NodeJS SDK below
 */
var Algorithm, AlgorithmiaClient, Data, algorithmia, https, url;
https = require('https');
url = require('url');

AlgorithmiaClient = (function() {
  function AlgorithmiaClient(key) {
    this.api_path = 'https://api.algorithmia.com/v1/';
    if (key.indexOf('Simple ') === 0) {
      this.api_key = key;
    } else {
      this.api_key = 'Simple ' + key;
    }
  }

  AlgorithmiaClient.prototype.algo = function(path) {
    return new Algorithm(this, path);
  };

  AlgorithmiaClient.prototype.file = function(path) {
    return new Data(this, path);
  };

  AlgorithmiaClient.prototype.req = function(path, method, data, cheaders, callback) {
    var dheader, key, options, req, val;
    dheader = {
      'Content-Type': 'application/JSON',
      'Accept': 'application/JSON',
      'Authorization': this.api_key,
      'User-Agent': 'Algorithmia.js/0.2.1 NodeJS/' + process.version + ' Lambda/1.0.0'
    };
    for (key in cheaders) {
      val = cheaders[key];
      dheader[key] = val;
    }
    options = url.parse(this.api_path + path);
    options.method = method;
    options.headers = dheader;
    req = https.request(options, function(res) {
      var chunks;
      res.setEncoding('utf8');
      chunks = [];
      res.on('data', function(chunk) {
        return chunks.push(chunk);
      });
      res.on('end', function() {
        var body, buff;
        buff = chunks.join('');
        if (dheader['Accept'] === 'application/JSON') {
          body = JSON.parse(buff);
        } else {
          body = buff;
        }
        if (callback) {
          if (res.statusCode !== 200) {
            if (!body) {
              body = {};
            }
            if (!body.error) {
              body.error = {
                message: 'HTTP Response: ' + res.statusCode
              };
            }
          }
          callback(body);
        }
      });
      return res;
    });
    req.write(data);
    return req.end();
  };

  return AlgorithmiaClient;

})();

algorithmia = function(key) {
  return new AlgorithmiaClient(key);
};

Algorithm = (function() {
  function Algorithm(client, path) {
    this.client = client;
    this.algo_path = path;
  }

  Algorithm.prototype.pipe = function(params) {
    this.algo_params = params;
    if (typeof params === 'object' || typeof params === 'string') {
      this.algo_data = JSON.stringify(params);
    } else {
      this.algo_data = params + '';
    }
    return this;
  };

  Algorithm.prototype.then = function(callback) {
    return this.client.req('algo/' + this.algo_path, 'POST', this.algo_data, {}, callback);
  };

  return Algorithm;

})();

Data = (function() {
  function Data(client, path) {
    this.client = client;
    if (path.indexOf("data://") !== 0) {
      throw "Supplied path is invalid.";
    }
    this.data_path = path.replace(/data\:\/\//, "");
  }

  Data.prototype.putString = function(content, callback) {
    var headers;
    headers = {
      'Content-Type': 'text/plain'
    };
    return this.client.req('data/' + this.data_path, 'PUT', content, headers, callback);
  };

  Data.prototype.putJson = function(content, callback) {
    var headers;
    headers = {
      'Content-Type': 'application/JSON'
    };
    return this.client.req('data/' + this.data_path, 'PUT', content, headers, callback);
  };

  Data.prototype.getString = function(callback) {
    var headers;
    headers = {
      'Accept': 'text/plain'
    };
    return this.client.req('data/' + this.data_path, 'GET', "", headers, callback);
  };

  Data.prototype.getJson = function(callback) {
    var headers;
    headers = {
      'Accept': 'text/plain'
    };
    return this.client.req('data/' + this.data_path, 'GET', "", headers, callback);
  };

  return Data;

})();
<|endoftext|>


<commit_before>angular.module('StorageApp', [])
	.provider('storage', [function () {
		var onLoad = function () {};
		var onChanged = function () {};

		return {
			set_onChanged_callback: function (cb) {
				onChanged = cb;
			},

			set_onLoad_callback: function (cb) {
				onLoad = cb;
			},

			$get: ['$q', '$rootScope', function ($q, $rootScope) {
				var ready = $q.defer();
				var storage = {
					ready: ready.promise,
					stg: {},
					set: function (data, cb) {
						chrome.storage.local.set(data, cb);
					}
				};

				chrome.storage.local.get(function (stg) {
					storage.stg = angular.copy(stg);

					onLoad(storage.stg);

					$rootScope.$apply();
					ready.resolve(storage.stg);

					chrome.storage.onChanged.addListener(function (changes) {
						onChanged(changes, storage.stg);
						$rootScope.$apply();
					});
				});

				return storage;
			}]
		};
	}]);<commit_msg>Linting StorageApp<commit_after>angular.module('StorageApp', [])
	.provider('storage', [function () {
		var onLoad = function () {};
		var onChanged = function () {};

		return {
			set_onChanged_callback: function (cb) {
				onChanged = cb;
			},

			set_onLoad_callback: function (cb) {
				onLoad = cb;
			},

			$get: ['$q', '$rootScope', function ($q, $rootScope) {
				var ready = $q.defer();
				var storage = {
					ready: ready.promise,
					stg: {},
					set: function (data, cb) {
						chrome.storage.local.set(data, cb);
					},
				};

				chrome.storage.local.get(function (stg) {
					storage.stg = angular.copy(stg);

					onLoad(storage.stg);

					$rootScope.$apply();
					ready.resolve(storage.stg);

					chrome.storage.onChanged.addListener(function (changes) {
						onChanged(changes, storage.stg);
						$rootScope.$apply();
					});
				});

				return storage;
			}],
		};
	}]);
<|endoftext|>


<commit_before>// Dependencies
var Config = require("../config")
  , Cheerio = require("cheerio")
  , Request = require("request")
  , Fs = require("fs")
  , Path = require("path")
  , FsExtra = require("fs-extra")
  ;

const DOWNLOAD_DIR = Path.resolve(__dirname + "/../downloads/");
var Artworks = module.exports = {};

// TODO JSDoc
Artworks.downloadFromArtist = function (user, callback) {

    var $ = null
      , $artworks = []
      , $cArtwork = null
      , artworks = []
      , i = 0
      , cUrl = null
      , userDir = DOWNLOAD_DIR + "/" + user.display_name "/"
      , path = ""
      ;

    try {
        Fs.mkdirSync(userDir)
    } catch (e) {}

    function getSeq(page) {
        Request.get({
            url: "https://theartstack.com" + user.profile_url + "?page=" + page
          , headers: {
                "Cookie": Config.cookie
            }
        }, function (err, res, body) {
            if (err) { return callback(err); }
            $ = Cheerio.load(body);
            $artworks = $("[data-highres-pic]");
            if (!$artworks.length) {
                return callback(null, artworks);
            }
            for (i = 0; i < $artworks.length; ++i) {
                $cArtwork = $artworks.eq(i);
                url = $cArtwork.attr("data-highres-pic");
                artworks.push({
                    url: url
                });

                function download(u, p) {
                    Request(u, function (err, res, body) {
                        if (err) {
                            return console.log("Failed: " + u);
                        }
                        console.log("Done: " + u);
                    }).pipe(Fs.createWriteStream(p))
                }

                try {
                path = userDir + url.match(/\/([0-9]+)\//)[1] + url.match(/\/.*\.(.*)\?.*$/)[1];
                } catch (e) {
                    debugger
                }
                if (!Fs.existsSync(path)) {
                    download(url, path);
                }
            }
            getSeq(page + 1);
        });
    }

    debugger
    getSeq(1);
};
<commit_msg>Syntax<commit_after>// Dependencies
var Config = require("../config")
  , Cheerio = require("cheerio")
  , Request = require("request")
  , Fs = require("fs")
  , Path = require("path")
  , FsExtra = require("fs-extra")
  ;

const DOWNLOAD_DIR = Path.resolve(__dirname + "/../downloads/");
var Artworks = module.exports = {};

// TODO JSDoc
Artworks.downloadFromArtist = function (user, callback) {

    var $ = null
      , $artworks = []
      , $cArtwork = null
      , artworks = []
      , i = 0
      , cUrl = null
      , userDir = DOWNLOAD_DIR + "/" + user.display_name + "/"
      , path = ""
      ;

    try {
        Fs.mkdirSync(userDir)
    } catch (e) {}

    function getSeq(page) {
        Request.get({
            url: "https://theartstack.com" + user.profile_url + "?page=" + page
          , headers: {
                "Cookie": Config.cookie
            }
        }, function (err, res, body) {
            if (err) { return callback(err); }
            $ = Cheerio.load(body);
            $artworks = $("[data-highres-pic]");
            if (!$artworks.length) {
                return callback(null, artworks);
            }
            for (i = 0; i < $artworks.length; ++i) {
                $cArtwork = $artworks.eq(i);
                url = $cArtwork.attr("data-highres-pic");
                artworks.push({
                    url: url
                });

                function download(u, p) {
                    Request(u, function (err, res, body) {
                        if (err) {
                            return console.log("Failed: " + u);
                        }
                        console.log("Done: " + u);
                    }).pipe(Fs.createWriteStream(p))
                }

                try {
                path = userDir + url.match(/\/([0-9]+)\//)[1] + url.match(/\/.*\.(.*)\?.*$/)[1];
                } catch (e) {
                    debugger
                }
                if (!Fs.existsSync(path)) {
                    download(url, path);
                }
            }
            getSeq(page + 1);
        });
    }

    debugger
    getSeq(1);
};
<|endoftext|>


<commit_before>/**
 * IconElement is often mixed into other classes to generate an icon.
 * Icons are graphics, about the size of normal text. They are used to aid the user
 * in locating a control or to convey information in a space-efficient way. See the
 * [OOjs UI documentation on MediaWiki] [1] for a list of icons
 * included in the library.
 *
 * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Icons,_Indicators,_and_Labels#Icons
 *
 * @abstract
 * @class
 *
 * @constructor
 * @param {Object} [config] Configuration options
 * @cfg {jQuery} [$icon] The icon element created by the class. If this configuration is omitted,
 *  the icon element will use a generated `<span>`. To use a different HTML tag, or to specify that
 *  the icon element be set to an existing icon instead of the one generated by this class, set a
 *  value using a jQuery selection. For example:
 *
 *      // Use a
 tag instead of a
 *     $icon: $("
")
 *     // Use an existing icon element instead of the one generated by the class
 *     $icon: this.$element
 *     // Use an icon element from a child widget
 *     $icon: this.childwidget.$element
 * @cfg {Object|string} [icon=''] The symbolic name of the icon (e.g., ‘remove’ or ‘menu’), or a map of
 *  symbolic names.  A map is used for i18n purposes and contains a `default` icon
 *  name and additional names keyed by language code. The `default` name is used when no icon is keyed
 *  by the user's language.
 *
 *  Example of an i18n map:
 *
 *     { default: 'bold-a', en: 'bold-b', de: 'bold-f' }
 *  See the [OOjs UI documentation on MediaWiki] [2] for a list of icons included in the library.
 * [2]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Icons,_Indicators,_and_Labels#Icons
 * @cfg {string|Function} [iconTitle] A text string used as the icon title, or a function that returns title
 *  text. The icon title is displayed when users move the mouse over the icon.
 */
OO.ui.IconElement = function OoUiIconElement( config ) {
	// Configuration initialization
	config = config || {};

	// Properties
	this.$icon = null;
	this.icon = null;
	this.iconTitle = null;

	// Initialization
	this.setIcon( config.icon || this.constructor.static.icon );
	this.setIconTitle( config.iconTitle || this.constructor.static.iconTitle );
	this.setIconElement( config.$icon || $( '' ) );
};

/* Setup */

OO.initClass( OO.ui.IconElement );

/* Static Properties */

/**
 * The symbolic name of the icon (e.g., ‘remove’ or ‘menu’), or a map of symbolic names. A map is used
 * for i18n purposes and contains a `default` icon name and additional names keyed by
 * language code. The `default` name is used when no icon is keyed by the user's language.
 *
 * Example of an i18n map:
 *
 *     { default: 'bold-a', en: 'bold-b', de: 'bold-f' }
 *
 * Note: the static property will be overridden if the #icon configuration is used.
 *
 * @static
 * @inheritable
 * @property {Object|string}
 */
OO.ui.IconElement.static.icon = null;

/**
 * The icon title, displayed when users move the mouse over the icon. The value can be text, a
 * function that returns title text, or `null` for no title.
 *
 * The static property will be overridden if the #iconTitle configuration is used.
 *
 * @static
 * @inheritable
 * @property {string|Function|null}
 */
OO.ui.IconElement.static.iconTitle = null;

/* Methods */

/**
 * Set the icon element.
 *
 * If an element is already set, it will be cleaned up before setting up the new element.
 *
 * @param {jQuery} $icon Element to use as icon
 */
OO.ui.IconElement.prototype.setIconElement = function ( $icon ) {
	if ( this.$icon ) {
		this.$icon
			.removeClass( 'oo-ui-iconElement-icon oo-ui-icon-' + this.icon )
			.removeAttr( 'title' );
	}

	this.$icon = $icon
		.addClass( 'oo-ui-iconElement-icon' )
		.toggleClass( 'oo-ui-icon-' + this.icon, !!this.icon );
	if ( this.iconTitle !== null ) {
		this.$icon.attr( 'title', this.iconTitle );
	}
};

/**
 * Set icon name.
 *
 * @param {Object|string|null} icon Symbolic icon name, or map of icon names keyed by language ID;
 *  use the 'default' key to specify the icon to be used when there is no icon in the user's
 *  language, use null to remove icon
 * @chainable
 */
OO.ui.IconElement.prototype.setIcon = function ( icon ) {
	icon = OO.isPlainObject( icon ) ? OO.ui.getLocalValue( icon, null, 'default' ) : icon;
	icon = typeof icon === 'string' && icon.trim().length ? icon.trim() : null;

	if ( this.icon !== icon ) {
		if ( this.$icon ) {
			if ( this.icon !== null ) {
				this.$icon.removeClass( 'oo-ui-icon-' + this.icon );
			}
			if ( icon !== null ) {
				this.$icon.addClass( 'oo-ui-icon-' + icon );
			}
		}
		this.icon = icon;
	}

	this.$element.toggleClass( 'oo-ui-iconElement', !!this.icon );
	this.updateThemeClasses();

	return this;
};

/**
 * Set icon title.
 *
 * @param {string|Function|null} icon Icon title text, a function that returns text or null
 *  for no icon title
 * @chainable
 */
OO.ui.IconElement.prototype.setIconTitle = function ( iconTitle ) {
	iconTitle = typeof iconTitle === 'function' ||
		( typeof iconTitle === 'string' && iconTitle.length ) ?
			OO.ui.resolveMsg( iconTitle ) : null;

	if ( this.iconTitle !== iconTitle ) {
		this.iconTitle = iconTitle;
		if ( this.$icon ) {
			if ( this.iconTitle !== null ) {
				this.$icon.attr( 'title', iconTitle );
			} else {
				this.$icon.removeAttr( 'title' );
			}
		}
	}

	return this;
};

/**
 * Get icon name.
 *
 * @return {string} Icon name
 */
OO.ui.IconElement.prototype.getIcon = function () {
	return this.icon;
};

/**
 * Get icon title.
 *
 * @return {string} Icon title text
 */
OO.ui.IconElement.prototype.getIconTitle = function () {
	return this.iconTitle;
};
<commit_msg>IconElement: Add description of methods<commit_after>/**
 * IconElement is often mixed into other classes to generate an icon.
 * Icons are graphics, about the size of normal text. They are used to aid the user
 * in locating a control or to convey information in a space-efficient way. See the
 * [OOjs UI documentation on MediaWiki] [1] for a list of icons
 * included in the library.
 *
 * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Icons,_Indicators,_and_Labels#Icons
 *
 * @abstract
 * @class
 *
 * @constructor
 * @param {Object} [config] Configuration options
 * @cfg {jQuery} [$icon] The icon element created by the class. If this configuration is omitted,
 *  the icon element will use a generated `<span>`. To use a different HTML tag, or to specify that
 *  the icon element be set to an existing icon instead of the one generated by this class, set a
 *  value using a jQuery selection. For example:
 *
 *      // Use a
 tag instead of a
 *     $icon: $("
")
 *     // Use an existing icon element instead of the one generated by the class
 *     $icon: this.$element
 *     // Use an icon element from a child widget
 *     $icon: this.childwidget.$element
 * @cfg {Object|string} [icon=''] The symbolic name of the icon (e.g., ‘remove’ or ‘menu’), or a map of
 *  symbolic names.  A map is used for i18n purposes and contains a `default` icon
 *  name and additional names keyed by language code. The `default` name is used when no icon is keyed
 *  by the user's language.
 *
 *  Example of an i18n map:
 *
 *     { default: 'bold-a', en: 'bold-b', de: 'bold-f' }
 *  See the [OOjs UI documentation on MediaWiki] [2] for a list of icons included in the library.
 * [2]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Icons,_Indicators,_and_Labels#Icons
 * @cfg {string|Function} [iconTitle] A text string used as the icon title, or a function that returns title
 *  text. The icon title is displayed when users move the mouse over the icon.
 */
OO.ui.IconElement = function OoUiIconElement( config ) {
	// Configuration initialization
	config = config || {};

	// Properties
	this.$icon = null;
	this.icon = null;
	this.iconTitle = null;

	// Initialization
	this.setIcon( config.icon || this.constructor.static.icon );
	this.setIconTitle( config.iconTitle || this.constructor.static.iconTitle );
	this.setIconElement( config.$icon || $( '' ) );
};

/* Setup */

OO.initClass( OO.ui.IconElement );

/* Static Properties */

/**
 * The symbolic name of the icon (e.g., ‘remove’ or ‘menu’), or a map of symbolic names. A map is used
 * for i18n purposes and contains a `default` icon name and additional names keyed by
 * language code. The `default` name is used when no icon is keyed by the user's language.
 *
 * Example of an i18n map:
 *
 *     { default: 'bold-a', en: 'bold-b', de: 'bold-f' }
 *
 * Note: the static property will be overridden if the #icon configuration is used.
 *
 * @static
 * @inheritable
 * @property {Object|string}
 */
OO.ui.IconElement.static.icon = null;

/**
 * The icon title, displayed when users move the mouse over the icon. The value can be text, a
 * function that returns title text, or `null` for no title.
 *
 * The static property will be overridden if the #iconTitle configuration is used.
 *
 * @static
 * @inheritable
 * @property {string|Function|null}
 */
OO.ui.IconElement.static.iconTitle = null;

/* Methods */

/**
 * Set the icon element. This method is used to retarget an icon mixin so that its functionality
 * applies to the specified icon element instead of the one created by the class. If an icon
 * element is already set, the mixin’s effect on that element is removed. Generated CSS classes
 * and mixin methods will no longer affect the element.
 *
 * @param {jQuery} $icon Element to use as icon
 */
OO.ui.IconElement.prototype.setIconElement = function ( $icon ) {
	if ( this.$icon ) {
		this.$icon
			.removeClass( 'oo-ui-iconElement-icon oo-ui-icon-' + this.icon )
			.removeAttr( 'title' );
	}

	this.$icon = $icon
		.addClass( 'oo-ui-iconElement-icon' )
		.toggleClass( 'oo-ui-icon-' + this.icon, !!this.icon );
	if ( this.iconTitle !== null ) {
		this.$icon.attr( 'title', this.iconTitle );
	}
};

/**
 * Set icon by symbolic name (e.g., ‘remove’ or ‘menu’). Use `null` to remove an icon.
 * The icon parameter can also be set to a map of icon names. See the #icon config setting
 * for an example.
 *
 * @param {Object|string|null} icon A symbolic icon name, a {@link #icon map of icon names} keyed
 *  by language code, or `null` to remove the icon.
 * @chainable
 */
OO.ui.IconElement.prototype.setIcon = function ( icon ) {
	icon = OO.isPlainObject( icon ) ? OO.ui.getLocalValue( icon, null, 'default' ) : icon;
	icon = typeof icon === 'string' && icon.trim().length ? icon.trim() : null;

	if ( this.icon !== icon ) {
		if ( this.$icon ) {
			if ( this.icon !== null ) {
				this.$icon.removeClass( 'oo-ui-icon-' + this.icon );
			}
			if ( icon !== null ) {
				this.$icon.addClass( 'oo-ui-icon-' + icon );
			}
		}
		this.icon = icon;
	}

	this.$element.toggleClass( 'oo-ui-iconElement', !!this.icon );
	this.updateThemeClasses();

	return this;
};

/**
 * Set the icon title. Use `null` to remove the title.
 *
 * @param {string|Function|null} iconTitle A text string used as the icon title,
 *  a function that returns title text, or `null` for no title.
 * @chainable
 */
OO.ui.IconElement.prototype.setIconTitle = function ( iconTitle ) {
	iconTitle = typeof iconTitle === 'function' ||
		( typeof iconTitle === 'string' && iconTitle.length ) ?
			OO.ui.resolveMsg( iconTitle ) : null;

	if ( this.iconTitle !== iconTitle ) {
		this.iconTitle = iconTitle;
		if ( this.$icon ) {
			if ( this.iconTitle !== null ) {
				this.$icon.attr( 'title', iconTitle );
			} else {
				this.$icon.removeAttr( 'title' );
			}
		}
	}

	return this;
};

/**
 * Get the symbolic name of the icon.
 *
 * @return {string} Icon name
 */
OO.ui.IconElement.prototype.getIcon = function () {
	return this.icon;
};

/**
 * Get the icon title. The title text is displayed when a user moves the mouse over the icon.
 *
 * @return {string} Icon title text
 */
OO.ui.IconElement.prototype.getIconTitle = function () {
	return this.iconTitle;
};
<|endoftext|>


<commit_before>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import LoadingSpinner from '../loadingSpinner';
import cx from 'classnames';
import theme from './theme.css';

class Button extends PureComponent {
  getSpinnerColor() {
    const { inverse, level } = this.props;

    return level === 'secondary' || (level === 'outline' && !inverse) ? 'teal' : 'white';
  }

  handleMouseUp = event => {
    this.buttonNode.blur();
    if (this.props.onMouseUp) {
      this.props.onMouseUp(event);
    }
  };

  handleMouseLeave = event => {
    this.buttonNode.blur();
    if (this.props.onMouseLeave) {
      this.props.onMouseLeave(event);
    }
  };

  render() {
    const {
      children,
      className,
      level,
      disabled,
      element,
      active,
      fullWidth,
      href,
      icon,
      iconPlacement,
      inverse,
      label,
      size,
      type,
      processing,
      ...others
    } = this.props;

    const classNames = cx(
      theme['button'],
      theme[level],
      {
        [theme['icon-only']]: !label && !children,
        [theme['inverse']]: inverse && level === 'outline',
        [theme['is-full-width']]: fullWidth,
        [theme['processing']]: processing,
        [theme['active']]: active,
        [theme[size]]: theme[size],
      },
      className,
    );

    const props = {
      ...others,
      href,
      ref: node => {
        this.buttonNode = node;
      },
      className: classNames,
      disabled,
      onMouseUp: this.handleMouseUp,
      onMouseLeave: this.handleMouseLeave,
      type: !href ? type : null,
      'data-teamleader-ui': 'button',
    };

    return React.createElement(
      element,
      props,
      icon && iconPlacement === 'left' ? icon : null,
      label || children ? (

          {label}
          {children}

      ) : null,
      icon && iconPlacement === 'right' ? icon : null,
      processing ? (
        <LoadingSpinner
          className={theme['spinner']}
          color={this.getSpinnerColor()}
          size={size === 'small' ? 'small' : 'medium'}
        />
      ) : null,
    );
  }
}

Button.propTypes = {
  /** The content to display inside the button. */
  children: PropTypes.any,
  /** A class name for the button to give custom styles. */
  className: PropTypes.string,
  /** A custom element to be rendered */
  element: PropTypes.element,
  /** Determines which kind of button to be rendered. */
  level: PropTypes.oneOf(['outline', 'primary', 'secondary', 'destructive']),
  /** If true, component will be disabled. */
  disabled: PropTypes.bool,
  /** If true, component will be shown in an active state */
  active: PropTypes.bool,
  /** If true, component will take the full width available. */
  fullWidth: PropTypes.bool,
  /** If set, button will be rendered as an anchor element. */
  href: PropTypes.string,
  /** The icon displayed inside the button. */
  icon: PropTypes.element,
  /** The position of the icon inside the button. */
  iconPlacement: PropTypes.oneOf(['left', 'right']),
  /** If true, component will be rendered in inverse mode. */
  inverse: PropTypes.bool,
  /** The textual label displayed inside the button. */
  label: PropTypes.string,
  /** Callback function that is fired when mouse leaves the component. */
  onMouseLeave: PropTypes.func,
  /** Callback function that is fired when the mouse button is released. */
  onMouseUp: PropTypes.func,
  /** If true, component will show a loading spinner instead of label or children. */
  processing: PropTypes.bool,
  /** Size of the button. */
  size: PropTypes.oneOf(['small', 'medium', 'large']),
  /** Type of the button element. */
  type: PropTypes.string,
};

Button.defaultProps = {
  className: '',
  element: 'button',
  fullWidth: false,
  level: 'secondary',
  iconPlacement: 'left',
  inverse: false,
  processing: false,
  size: 'medium',
  type: 'button',
};

export default Button;
<commit_msg>Only render 'type' attribute when element is a button<commit_after>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import LoadingSpinner from '../loadingSpinner';
import cx from 'classnames';
import theme from './theme.css';

class Button extends PureComponent {
  getSpinnerColor() {
    const { inverse, level } = this.props;

    return level === 'secondary' || (level === 'outline' && !inverse) ? 'teal' : 'white';
  }

  handleMouseUp = event => {
    this.buttonNode.blur();
    if (this.props.onMouseUp) {
      this.props.onMouseUp(event);
    }
  };

  handleMouseLeave = event => {
    this.buttonNode.blur();
    if (this.props.onMouseLeave) {
      this.props.onMouseLeave(event);
    }
  };

  render() {
    const {
      children,
      className,
      level,
      disabled,
      element,
      active,
      fullWidth,
      href,
      icon,
      iconPlacement,
      inverse,
      label,
      size,
      type,
      processing,
      ...others
    } = this.props;

    const classNames = cx(
      theme['button'],
      theme[level],
      {
        [theme['icon-only']]: !label && !children,
        [theme['inverse']]: inverse && level === 'outline',
        [theme['is-full-width']]: fullWidth,
        [theme['processing']]: processing,
        [theme['active']]: active,
        [theme[size]]: theme[size],
      },
      className,
    );

    const props = {
      ...others,
      href,
      ref: node => {
        this.buttonNode = node;
      },
      className: classNames,
      disabled,
      onMouseUp: this.handleMouseUp,
      onMouseLeave: this.handleMouseLeave,
      type: element === 'button' ? type : null,
      'data-teamleader-ui': 'button',
    };

    return React.createElement(
      element,
      props,
      icon && iconPlacement === 'left' ? icon : null,
      label || children ? (

          {label}
          {children}

      ) : null,
      icon && iconPlacement === 'right' ? icon : null,
      processing ? (
        <LoadingSpinner
          className={theme['spinner']}
          color={this.getSpinnerColor()}
          size={size === 'small' ? 'small' : 'medium'}
        />
      ) : null,
    );
  }
}

Button.propTypes = {
  /** The content to display inside the button. */
  children: PropTypes.any,
  /** A class name for the button to give custom styles. */
  className: PropTypes.string,
  /** A custom element to be rendered */
  element: PropTypes.element,
  /** Determines which kind of button to be rendered. */
  level: PropTypes.oneOf(['outline', 'primary', 'secondary', 'destructive']),
  /** If true, component will be disabled. */
  disabled: PropTypes.bool,
  /** If true, component will be shown in an active state */
  active: PropTypes.bool,
  /** If true, component will take the full width available. */
  fullWidth: PropTypes.bool,
  /** If set, button will be rendered as an anchor element. */
  href: PropTypes.string,
  /** The icon displayed inside the button. */
  icon: PropTypes.element,
  /** The position of the icon inside the button. */
  iconPlacement: PropTypes.oneOf(['left', 'right']),
  /** If true, component will be rendered in inverse mode. */
  inverse: PropTypes.bool,
  /** The textual label displayed inside the button. */
  label: PropTypes.string,
  /** Callback function that is fired when mouse leaves the component. */
  onMouseLeave: PropTypes.func,
  /** Callback function that is fired when the mouse button is released. */
  onMouseUp: PropTypes.func,
  /** If true, component will show a loading spinner instead of label or children. */
  processing: PropTypes.bool,
  /** Size of the button. */
  size: PropTypes.oneOf(['small', 'medium', 'large']),
  /** Type of the button element. */
  type: PropTypes.string,
};

Button.defaultProps = {
  className: '',
  element: 'button',
  fullWidth: false,
  level: 'secondary',
  iconPlacement: 'left',
  inverse: false,
  processing: false,
  size: 'medium',
  type: 'button',
};

export default Button;
<|endoftext|>


<commit_before>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import Portal from '../hoc/Portal';
import ActivableRenderer from '../hoc/ActivableRenderer';
import FontIcon from '../font_icon';
import InjectButton from '../button/Button.js';
import InjectIconButton from '../button/IconButton';
import InjectOverlay from '../overlay/Overlay';
import { IconCloseMediumOutline } from '@teamleader/ui-icons';
import theme from './theme.css';

const factory = (Overlay, Button, IconButton) => {
  class Dialog extends PureComponent {
    static propTypes = {
      actions: PropTypes.arrayOf(
        PropTypes.shape({
          className: PropTypes.string,
          label: PropTypes.string,
          children: PropTypes.node,
        }),
      ),
      active: PropTypes.bool,
      backdrop: PropTypes.string,
      children: PropTypes.node,
      className: PropTypes.string,
      onCloseClick: PropTypes.func,
      onEscKeyDown: PropTypes.func,
      onOverlayClick: PropTypes.func,
      onOverlayMouseDown: PropTypes.func,
      onOverlayMouseMove: PropTypes.func,
      onOverlayMouseUp: PropTypes.func,
      size: PropTypes.oneOf(['small', 'medium', 'large', 'fullscreen']),
      title: PropTypes.string,
      type: PropTypes.oneOf(['regular', 'warning']),
    };

    static defaultProps = {
      actions: [],
      active: false,
      backdrop: 'dark',
      size: 'medium',
      type: 'regular',
    };

    render() {
      const {
        actions,
        active,
        backdrop,
        children,
        className,
        onCloseClick,
        onEscKeyDown,
        onOverlayClick,
        onOverlayMouseDown,
        onOverlayMouseMove,
        onOverlayMouseUp,
        size,
        title,
        type,
      } = this.props;

      const actionButtons = actions.map((action, idx) => {
        const className = cx(theme.button, {
          [action.className]: action.className,
        });
        return <Button key={idx} {...action} className={className} />; // eslint-disable-line
      });

      const dialogClassNames = cx(
        [theme.dialog, theme[size], theme[type]],
        {
          [theme.active]: active,
        },
        className,
      );

      return (
        <Portal className={theme.wrapper}>
          <Overlay
            active={active}
            backdrop={backdrop}
            className={theme.overlay}
            onClick={onOverlayClick}
            onEscKeyDown={onEscKeyDown}
            onMouseDown={onOverlayMouseDown}
            onMouseMove={onOverlayMouseMove}
            onMouseUp={onOverlayMouseUp}
          />

              {type === 'warning' ? <FontIcon className={theme.icon} value="alert_circle" /> : null}
              {title ?
{title}
 : null}
              <IconButton icon={<IconCloseMediumOutline />} className={theme.close} onMouseUp={onCloseClick} />

              {children}

            {actionButtons.length ? (

                {actionButtons}

            ) : null}

        </Portal>
      );
    }
  }

  return ActivableRenderer()(Dialog);
};

const Dialog = factory(InjectOverlay, InjectButton, InjectIconButton);

export default Dialog;
export { Dialog, factory as dialogFactory };
<commit_msg>Replaced old FontIcon with the one from our ui-icons package<commit_after>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import Portal from '../hoc/Portal';
import ActivableRenderer from '../hoc/ActivableRenderer';
import InjectButton from '../button/Button.js';
import InjectIconButton from '../button/IconButton';
import InjectOverlay from '../overlay/Overlay';
import { IconCloseMediumOutline, IconWarningMediumOutline } from '@teamleader/ui-icons';
import theme from './theme.css';

const factory = (Overlay, Button, IconButton) => {
  class Dialog extends PureComponent {
    static propTypes = {
      actions: PropTypes.arrayOf(
        PropTypes.shape({
          className: PropTypes.string,
          label: PropTypes.string,
          children: PropTypes.node,
        }),
      ),
      active: PropTypes.bool,
      backdrop: PropTypes.string,
      children: PropTypes.node,
      className: PropTypes.string,
      onCloseClick: PropTypes.func,
      onEscKeyDown: PropTypes.func,
      onOverlayClick: PropTypes.func,
      onOverlayMouseDown: PropTypes.func,
      onOverlayMouseMove: PropTypes.func,
      onOverlayMouseUp: PropTypes.func,
      size: PropTypes.oneOf(['small', 'medium', 'large', 'fullscreen']),
      title: PropTypes.string,
      type: PropTypes.oneOf(['regular', 'warning']),
    };

    static defaultProps = {
      actions: [],
      active: false,
      backdrop: 'dark',
      size: 'medium',
      type: 'regular',
    };

    render() {
      const {
        actions,
        active,
        backdrop,
        children,
        className,
        onCloseClick,
        onEscKeyDown,
        onOverlayClick,
        onOverlayMouseDown,
        onOverlayMouseMove,
        onOverlayMouseUp,
        size,
        title,
        type,
      } = this.props;

      const actionButtons = actions.map((action, idx) => {
        const className = cx(theme.button, {
          [action.className]: action.className,
        });
        return <Button key={idx} {...action} className={className} />; // eslint-disable-line
      });

      const dialogClassNames = cx(
        [theme.dialog, theme[size], theme[type]],
        {
          [theme.active]: active,
        },
        className,
      );

      return (
        <Portal className={theme.wrapper}>
          <Overlay
            active={active}
            backdrop={backdrop}
            className={theme.overlay}
            onClick={onOverlayClick}
            onEscKeyDown={onEscKeyDown}
            onMouseDown={onOverlayMouseDown}
            onMouseMove={onOverlayMouseMove}
            onMouseUp={onOverlayMouseUp}
          />

              {type === 'warning' ? <IconWarningMediumOutline className={theme.icon} /> : null}
              {title ?
{title}
 : null}
              <IconButton icon={<IconCloseMediumOutline />} className={theme.close} onMouseUp={onCloseClick} />

              {children}

            {actionButtons.length ? (

                {actionButtons}

            ) : null}

        </Portal>
      );
    }
  }

  return ActivableRenderer()(Dialog);
};

const Dialog = factory(InjectOverlay, InjectButton, InjectIconButton);

export default Dialog;
export { Dialog, factory as dialogFactory };
<|endoftext|>


<commit_before>"use strict";

var components = require("server-components");
var Octokat = require("octokat");
var cache = require("memory-cache");

var _ = require("lodash");
var moment = require("moment");

var Github = components.newElement();
Github.createdCallback = function () {
    var github = new Octokat({
        token: process.env.GITHUB_TOKEN
    });

    var filter = JSON.parse(this.getAttribute("filter"));
    var username = this.getAttribute("username");
    var cacheId = "github-events-" + username + "/" + JSON.stringify(filter);

    function getEvents() {
        var cachedEvents = cache.get(cacheId);

        if (cachedEvents) return Promise.resolve(cachedEvents);
        else {
            return Promise.all(_.range(1, 10).map((pageNum) => {
                // Note the catch() - we just skip any pages we can't successfully load
                return github.users(username).events.public.fetch({page: pageNum}).catch(() => []);
            })).then((eventPages) => {
                var allEvents = _.flatten(eventPages);
                var relevantEvents = allEvents.filter(_.matches(filter));

                cache.put(cacheId, relevantEvents, 1000 * 60 * 1);
                return relevantEvents;
            });
        }
    }

    function eventDetails(event) {
        switch (event.type) {
            case "PullRequestEvent":
                return {
                  title: event.payload.pullRequest.title,
                  subtitle: `<i class="fa-solid fa-code-branch icon"></i>Pull request to ${event.repo.name}`,
                  url: event.payload.pullRequest.htmlUrl
                };
            case "CreateEvent":
                return {
                  title: `New repo: ${event.repo.name}`,
                  subtitle: event.payload.description ?
                    `<i class="fa-solid fa-bolt icon"></i>${event.payload.description}` : '',
                  url: `https:\/\/github.com/${event.repo.name}`
                };
            case "IssuesEvent":
                return {
                    title: event.payload.issue.title,
                    subtitle: `<i class="fa-brands fa-github-alt icon"></i>New issue on ${event.repo.name}`,
                    url: event.payload.issue.htmlUrl
                };
            default:
                console.log("Unrecognized event", event.type);
                return {
                  title: "Did something on Github"
                };
        }
    }

    return getEvents().then((events) => {
        var items = events.map((event) => {
            return _.merge({
                icon: "fa-brands fa-github",
                timestamp: moment(event.createdAt, "dd MMM DD YYYY HH:mm:ss ZZ").unix()
            }, eventDetails(event));
        });

        this.dispatchEvent(new components.dom.CustomEvent('items-ready', {
            items: items,
            bubbles: true
        }));
    });
};

components.registerElement("github-source", { prototype: Github });
<commit_msg>Pull more GitHub data, by expanding the page size<commit_after>"use strict";

var components = require("server-components");
var Octokat = require("octokat");
var cache = require("memory-cache");

var _ = require("lodash");
var moment = require("moment");

var Github = components.newElement();
Github.createdCallback = function () {
    var github = new Octokat({
        token: process.env.GITHUB_TOKEN
    });

    var filter = JSON.parse(this.getAttribute("filter"));
    var username = this.getAttribute("username");
    var cacheId = "github-events-" + username + "/" + JSON.stringify(filter);

    function getEvents() {
        var cachedEvents = cache.get(cacheId);

        if (cachedEvents) return Promise.resolve(cachedEvents);
        else {
            return Promise.all(_.range(1, 10).map((pageNum) => {
                return github.users(username).events.public.fetch({
                    page: pageNum,
                    per_page: 100
                })
                // We just skip any pages we can't successfully load:
                .catch(() => []);
            })).then((eventPages) => {
                var allEvents = _.flatten(eventPages);
                var relevantEvents = allEvents.filter(_.matches(filter));

                cache.put(cacheId, relevantEvents, 1000 * 60 * 1);
                return relevantEvents;
            });
        }
    }

    function eventDetails(event) {
        switch (event.type) {
            case "PullRequestEvent":
                return {
                  title: event.payload.pullRequest.title,
                  subtitle: `<i class="fa-solid fa-code-branch icon"></i>Pull request to ${event.repo.name}`,
                  url: event.payload.pullRequest.htmlUrl
                };
            case "CreateEvent":
                return {
                  title: `New repo: ${event.repo.name}`,
                  subtitle: event.payload.description ?
                    `<i class="fa-solid fa-bolt icon"></i>${event.payload.description}` : '',
                  url: `https:\/\/github.com/${event.repo.name}`
                };
            case "IssuesEvent":
                return {
                    title: event.payload.issue.title,
                    subtitle: `<i class="fa-brands fa-github-alt icon"></i>New issue on ${event.repo.name}`,
                    url: event.payload.issue.htmlUrl
                };
            default:
                console.log("Unrecognized event", event.type);
                return {
                  title: "Did something on Github"
                };
        }
    }

    return getEvents().then((events) => {
        var items = events.map((event) => {
            return _.merge({
                icon: "fa-brands fa-github",
                timestamp: moment(event.createdAt, "dd MMM DD YYYY HH:mm:ss ZZ").unix()
            }, eventDetails(event));
        });

        this.dispatchEvent(new components.dom.CustomEvent('items-ready', {
            items: items,
            bubbles: true
        }));
    });
};

components.registerElement("github-source", { prototype: Github });
<|endoftext|>


<commit_before>const fs = require('fs-extra');
const path = require('path');
const xcode = require('xcode');
const log = require('npmlog');
const plistParser = require('plist');
const groupFilesByType = require('../groupFilesByType');
const createGroup = require('./createGroup');
const getPlist = require('./getPlist');
const getPlistPath = require('./getPlistPath');

/**
 * This function works in a similar manner to its Android version,
 * except it does not copy fonts but creates XCode Group references
 */
module.exports = function linkAssetsIOS(files, projectConfig) {
  const project = xcode.project(projectConfig.pbxprojPath).parseSync();
  const plist = getPlist(project, projectConfig.sourceDir);

  if (!plist) {
    return log.error(
      'ERRPLIST',
      `Could not locate Info.plist. Check if your project has 'INFOPLIST_FILE' set properly`
    );
  }

  if (!project.pbxGroupByName('Resources')) {
    createGroup(project, 'Resources');

    log.warn(
      'ERRGROUP',
      `Group 'Resources' does not exist in your XCode project. We have created it automatically for you.`
    );
  }

  const assets = (files || [])
    .map(asset =>
      project.addResourceFile(
        path.relative(projectConfig.sourceDir, asset),
        { target: project.getFirstTarget().uuid }
      )
    )
    .filter(file => file)   // xcode returns false if file is already there
    .map(file => file.basename);

  const groupedAssets = groupFilesByType(files);

  plist.UIAppFonts = (plist.UIAppFonts || []).concat(groupedAssets.fonts || []);

  fs.writeFileSync(
    projectConfig.pbxprojPath,
    project.writeSync()
  );

  fs.writeFileSync(
    getPlistPath(project, projectConfig.sourceDir),
    plistParser.build(plist)
  );
};
<commit_msg>Some tweaks<commit_after>const fs = require('fs-extra');
const path = require('path');
const xcode = require('xcode');
const log = require('npmlog');
const plistParser = require('plist');
const groupFilesByType = require('../groupFilesByType');
const createGroup = require('./createGroup');
const getPlist = require('./getPlist');
const getPlistPath = require('./getPlistPath');

/**
 * This function works in a similar manner to its Android version,
 * except it does not copy fonts but creates XCode Group references
 */
module.exports = function linkAssetsIOS(files, projectConfig) {
  const project = xcode.project(projectConfig.pbxprojPath).parseSync();
  const plist = getPlist(project, projectConfig.sourceDir);

  if (!plist) {
    return log.error(
      'ERRPLIST',
      `Could not locate Info.plist. Check if your project has 'INFOPLIST_FILE' set properly`
    );
  }

  if (!project.pbxGroupByName('Resources')) {
    createGroup(project, 'Resources');

    log.warn(
      'ERRGROUP',
      `Group 'Resources' does not exist in your XCode project. We have created it automatically for you.`
    );
  }

  const assets = (files || [])
    .map(asset =>
      project.addResourceFile(
        path.relative(projectConfig.sourceDir, asset),
        { target: project.getFirstTarget().uuid }
      )
    )
    .filter(file => file)   // xcode returns false if file is already there
    .map(file => file.basename);

  const assetsByType = groupFilesByType(assets);

  plist.UIAppFonts = (plist.UIAppFonts || []).concat(assetsByType.fonts || []);

  fs.writeFileSync(
    projectConfig.pbxprojPath,
    project.writeSync()
  );

  fs.writeFileSync(
    getPlistPath(project, projectConfig.sourceDir),
    plistParser.build(plist)
  );
};
<|endoftext|>


<commit_before>import React from 'react';
import {StyleSheet, ScrollView, View, TouchableHighlight} from 'react-native';
import {NavigationContext} from 'navigation-react';
import {SharedElementAndroid, NavigationBar, SearchBarIOS} from 'navigation-react-native';

const Colors = ({colors, children}) => (
  <NavigationContext.Consumer>
    {({stateNavigator}) => (
      <ScrollView
        style={styles.scene}
        contentInsetAdjustmentBehavior="automatic">
        <View style={styles.colors}>
          {colors.map(color => (
            <TouchableHighlight
              key={color}
              style={styles.color}
              underlayColor={color}
              onPress={() => {
                stateNavigator.navigate('detail', {color});
              }}>
              <SharedElementAndroid name={color} style={{flex: 1}}>
                <View style={{backgroundColor: color, flex: 1}} />
              </SharedElementAndroid>
            </TouchableHighlight>
          ))}
          {children}
        </View>
      </ScrollView>
    )}
  </NavigationContext.Consumer>
);

export default class Grid extends React.Component {
  constructor(props) {
    super(props);
    this.state = {text: ''};
  }
  render() {
    const {colors} = this.props;
    const {text} = this.state;
    const matchedColors = colors.filter(color => (
      color.indexOf(text.toLowerCase()) !== -1
    ));
    return (
      <>
        <NavigationBar largeTitle={true} title="Colors">
          <SearchBarIOS
            text={text}
            autoCapitalize="none"
            obscureBackground={false}
            onChangeText={text => this.setState({text})}>
            <Colors colors={matchedColors} />
          </SearchBarIOS>
        </NavigationBar>
        <Colors colors={colors} />
      </>
    );
  }
}

const styles = StyleSheet.create({
  scene: {
    backgroundColor: '#fff',
  },
  colors: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    justifyContent: 'center',
    marginTop: 10,
  },
  color: {
    width: 100,
    height: 150,
    marginLeft: 10,
    marginRight: 10,
    marginBottom: 20,
  },
});<commit_msg>Scrolled content under bar with large titles<commit_after>import React from 'react';
import {StyleSheet, Platform, ScrollView, View, TouchableHighlight} from 'react-native';
import {NavigationContext} from 'navigation-react';
import {SharedElementAndroid, NavigationBar, SearchBarIOS} from 'navigation-react-native';

const Colors = ({colors, children}) => (
  <NavigationContext.Consumer>
    {({stateNavigator}) => (
      <ScrollView
        style={styles.scene}
        contentInsetAdjustmentBehavior="automatic">
        <View style={styles.colors}>
          {colors.map(color => (
            <TouchableHighlight
              key={color}
              style={styles.color}
              underlayColor={color}
              onPress={() => {
                stateNavigator.navigate('detail', {color});
              }}>
              <SharedElementAndroid name={color} style={{flex: 1}}>
                <View style={{backgroundColor: color, flex: 1}} />
              </SharedElementAndroid>
            </TouchableHighlight>
          ))}
          {children}
        </View>
      </ScrollView>
    )}
  </NavigationContext.Consumer>
);

const Container = (props) => (
  Platform.OS === 'ios' ? <ScrollView {...props}/> : <>{props.children}</>
);

export default class Grid extends React.Component {
  constructor(props) {
    super(props);
    this.state = {text: ''};
  }
  render() {
    const {colors} = this.props;
    const {text} = this.state;
    const matchedColors = colors.filter(color => (
      color.indexOf(text.toLowerCase()) !== -1
    ));
    return (
      <Container
        style={styles.scene}
        contentInsetAdjustmentBehavior="automatic">
        <NavigationBar largeTitle={true} title="Colors">
          <SearchBarIOS
            text={text}
            autoCapitalize="none"
            obscureBackground={false}
            onChangeText={text => this.setState({text})}>
            <Colors colors={matchedColors} />
          </SearchBarIOS>
        </NavigationBar>
        <Colors colors={colors} />
      </Container>
    );
  }
}

const styles = StyleSheet.create({
  scene: {
    backgroundColor: '#fff',
  },
  colors: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    justifyContent: 'center',
    marginTop: 10,
  },
  color: {
    width: 100,
    height: 150,
    marginLeft: 10,
    marginRight: 10,
    marginBottom: 20,
  },
});<|endoftext|>


<commit_before>$(document).ready(function() {
// static stuff
var ref = new Firebase("***firebase-url***");
var socket = io();
var canPost = true;
var authData;

var msgbox = $("#message");

$('.helpButton').click(function() {
  $('.about-box').fadeIn(function() {
    $('.close-button').click(function() {
      $('.about-box').fadeOut()
    });
  })
});

function showMessage(msg, user, tags, imageLink) {
  msg = emojione.toImage(msg);

  var messageElement;
  if (user == 'RubyBot') {
    messageElement = $('
').html('' + user + '' + ': ' + msg);

  } else if (user == 'Server') {
    messageElement = $('
').html('' + user + '' + ': ' + msg);

  } else {

    if (!imageLink || imageLink == ''){
      messageElement = $('
').html(
        '' +
        '
' +
        '@' + user + '' + tags + '' +
        ': ' + msg + '
'
      );
    } else {
      messageElement = $('
').html(
        '' +
        '
' +
        '@' + user + '' + tags + '' +
        '
' + msg + '

'
      );
    }
  }

  $('#messages').append(messageElement).animate({scrollTop: 1000000}, "slow");
  $('li').linkify({
    target: "_blank"
  });
}

// firebase stuff
ref.onAuth(function(data) {
  authData = data;
  if (!data){
    $('.twitter').css("display", "block")
  } else {
    socket.emit("user join", data.token, data.twitter.username, data.twitter.profileImageURL);
  }
});

$('#twitter-button').click(function() {
  ref.authWithOAuthPopup("twitter", function(error, data) {
    if (error) {
      console.log("Login Failed!", error);
    } else {
      $('.twitter').fadeOut()
    }
  });
  return false;
});

ref.getAuth();

$('form').submit(function(){
  if(canPost == false){
    showMessage('Please do not spam!', 'Server', '');
  } else {
    socket.emit('chat message',
      msgbox.val(),
      authData.token,
      function(response) {
        if (response.status == "failed"){
          showMessage(response.message, "Server", "S", "");
        }
      }
    );
    canPost=false;
    setTimeout(function(){canPost=true},500);
  }
  msgbox.val('');
  return false;
});

socket.on('chat message', function(message, user) {
  showMessage(message, user.name, user.tags, user.image);
});

socket.on("user join", function(user) {
  showMessage(user.name + " has joined!", "Server")
});

socket.on("user leave", function(user) {
  showMessage(user.name + " has left.", "Server")
});

window.onbeforeunload = function(e) {
  var result = confirm('Closing YRS Chat means you will no longer receive messages. Are you sure you want to close YRS Chat?');
  console.log(result);
  console.log(e);
  return result
};

$(window).unload(function() {
  socket.emit("user leave", token);
})
});
<commit_msg>Moved closing warning<commit_after>$(document).ready(function() {
// static stuff
var ref = new Firebase("***firebase-url***");
var socket = io();
var canPost = true;
var authData;

var msgbox = $("#message");

$('.helpButton').click(function() {
  $('.about-box').fadeIn(function() {
    $('.close-button').click(function() {
      $('.about-box').fadeOut()
    });
  })
});

function showMessage(msg, user, tags, imageLink) {
  msg = emojione.toImage(msg);

  var messageElement;
  if (user == 'RubyBot') {
    messageElement = $('
').html('' + user + '' + ': ' + msg);

  } else if (user == 'Server') {
    messageElement = $('
').html('' + user + '' + ': ' + msg);

  } else {

    if (!imageLink || imageLink == ''){
      messageElement = $('
').html(
        '' +
        '
' +
        '@' + user + '' + tags + '' +
        ': ' + msg + '
'
      );
    } else {
      messageElement = $('
').html(
        '' +
        '
' +
        '@' + user + '' + tags + '' +
        '
' + msg + '

'
      );
    }
  }

  $('#messages').append(messageElement).animate({scrollTop: 1000000}, "slow");
  $('li').linkify({
    target: "_blank"
  });
}

// firebase stuff
ref.onAuth(function(data) {
  authData = data;
  if (!data){
    $('.twitter').css("display", "block")
  } else {
    socket.emit("user join", data.token, data.twitter.username, data.twitter.profileImageURL);
  }
});

$('#twitter-button').click(function() {
  ref.authWithOAuthPopup("twitter", function(error, data) {
    if (error) {
      console.log("Login Failed!", error);
    } else {
      $('.twitter').fadeOut()
    }
  });
  return false;
});

ref.getAuth();

$('form').submit(function(){
  if(canPost == false){
    showMessage('Please do not spam!', 'Server', '');
  } else {
    socket.emit('chat message',
      msgbox.val(),
      authData.token,
      function(response) {
        if (response.status == "failed"){
          showMessage(response.message, "Server", "S", "");
        }
      }
    );
    canPost=false;
    setTimeout(function(){canPost=true},500);
  }
  msgbox.val('');
  return false;
});

socket.on('chat message', function(message, user) {
  showMessage(message, user.name, user.tags, user.image);
});

socket.on("user join", function(user) {
  showMessage(user.name + " has joined!", "Server")
});

socket.on("user leave", function(user) {
  showMessage(user.name + " has left.", "Server")
});

$(window).unload(function() {
  socket.emit("user leave", token);
})
});

window.onbeforeunload = function(e) {
  var result = confirm('Closing YRS Chat means you will no longer receive messages. Are you sure you want to close YRS Chat?');
  console.log(result);
  console.log(e);
  return result
};
<|endoftext|>


<commit_before>/**
 * NOTE: You should not need to modify
 * this file!
 *
 * You can if you want to though, of course :)
 *
 */

/** ES2015+ Polyfills */
import 'babel-polyfill';

/** Responsive Images Polyfill */
import 'picturefill';

/** Lazyload Images */
import 'lazysizes/plugins/bgset/ls.bgset.js';
import 'lazysizes';

/** Object-fit/Object-position Polyfill */
import objectFit from 'object-fit';

window.objectFit = objectFit;

const addEvent = () => window.addEventListener || window.attachEvent;
const event = ( window.addEventListener ? '' : 'on' ) + 'DOMContentLoaded';

addEvent()(event, () => {
	objectFit.polyfill({
		selector: '[data-object-fit="cover"]',
		fittype: 'cover',
		disableCrossDomain: true
	});

	objectFit.polyfill({
		selector: '[data-object-fit="contain"]',
		fittype: 'contain',
		disableCrossDomain: true
	});
});
<commit_msg>remove object-fit polyfill because it no longer supports newer IE/Edge browsers<commit_after>/**
 * NOTE: You should not need to modify
 * this file!
 *
 * You can if you want to though, of course :)
 *
 */

/** ES2015+ Polyfills */
import 'babel-polyfill';

/** Responsive Images Polyfill */
import 'picturefill';

/** Lazyload Images */
import 'lazysizes/plugins/bgset/ls.bgset.js';
import 'lazysizes';
<|endoftext|>


<commit_before>var squids = [];
var msgs = [];
var fpstime = new Date;
var A_temp_Global = [700/2, 700/2];
function startGame() {
    var offset;
    var finlength;
    var angles;
    var rates;
    for (i = 0; i < 50; i++) {
      offset = [Math.random()*20, Math.random()*20,Math.random()*20];
      finlength = [Math.random()*40, Math.random()*40, Math.random()*40];
      rates = [20+Math.random()*40, 20+Math.random()*40, 20+Math.random()*40];
      angles = [Math.random()*30+offset[0], Math.random()*30+offset[1], Math.random()*30+offset[2]];
      squids[i] = new squid(5, 'red', Math.random()*700, Math.random()*700, finlength, angles, rates, 0, offset);
    }
    msgs[0] = new msg('0', 20, 30);
    msgs[1] = new msg('hello world', 20, 50);
    msgs[2] = new msg('hello world', 20, 70);
    myGameArea.start();
}

var myGameArea = {
    canvas : document.createElement("canvas"),
    start : function() {
        this.canvas.width = 700;
        this.canvas.height = 700;
        this.context = this.canvas.getContext("2d");
        document.body.insertBefore(this.canvas, document.body.childNodes[0]);
        this.interval = setInterval(updateGameArea, 20);
    },
    clear : function() {
        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
    }
}

function squid(size, shcolor, x, y, finlength, angles, rates, cangle, offset) {
    this.size = size;
    this.x = [x,0,0,0];
    this.y = [y,0,0,0];
    this.vx = 0;
    this.vy = 0;
    this.shcolor = shcolor;
    this.offset = offset;
    this.finlength = finlength;
    this.rate = rates;
    this.angle = angles;
    this.cangle = [cangle, cangle, cangle];
    this.update = function(){
        ctx = myGameArea.context;
        //draw head
        ctx.beginPath();
        ctx.lineWidth=1;
        ctx.arc(this.x[0], this.y[0], this.size, 0, 2*Math.PI, false);
        ctx.fillStyle = this.shcolor;
        ctx.fill();
        ctx.strokeStyle = '#ffffff';
        ctx.stroke();
        //draw tail
        var x_temp = this.x[0];
        var y_temp = this.y[0];
        var vxnew = 0;
        var vynew = 0;
        var tanx = (A_temp_Global[0]-this.x[0]);
        var tany = (A_temp_Global[1]-this.y[0]);
        var A_temp = (180/Math.PI)*Math.atan(tanx/tany);
        if (tany>0){
          A_temp-=180;
        }
        if (Math.pow(Math.pow(tanx,2)+Math.pow(tany,2),0.5)<15){
          var offset2;
          var finlength2;
          var angles2;
          var rates2;
          for (i = 0; i < 50; i++) {
            offset2 = [this.offset[0]*(0.8+0.4*Math.random()),this.offset[1]*(0.8+0.4*Math.random()), this.offset[2]*(0.8+0.4*Math.random())];
            finlength2 = [this.finlength[0]*(0.8+0.4*Math.random()),this.finlength[1]*(0.8+0.4*Math.random()), this.finlength[2]*(0.8+0.4*Math.random())];
            rates2 = [this.rate[0]*(0.8+0.4*Math.random()),this.rate[1]*(0.8+0.4*Math.random()), this.rate[2]*(0.8+0.4*Math.random())];
            angles2 = [(this.angle[0]-this.offset[0])*(0.8+0.4*Math.random())+offset2[0],(this.angle[1]-this.offset[1])*(0.8+0.4*Math.random())+offset2[1], (this.angle[2]-this.offset[2])*(0.8+0.4*Math.random())+offset2[2]];
            squids[i] = new squid(5, 'red', Math.random()*700, Math.random()*700, finlength2, angles2, rates2, 0, offset2);
          }
          A_temp_Global = [700/2, 700/2];
        }

        for (i = 0; i < 3; i++) {
          //A_temp = this.angle[i]+A_temp;
          this.cangle[i] = this.cangle[i]+ ((this.angle[i]-this.cangle[i])/this.rate[i]);
          if ((this.cangle[i])/this.angle[i] > 0.95) { //if closer than 95% then
            this.angle[i] = -1 * (this.angle[i]-this.offset[i])+this.offset[i];
            if (this.angle[i]<1){
              this.rate[i] *=0.2
            } else {
              this.rate[i] *=(1/0.2)
            }
          //  this.rate[i] = -1 * this.rate[i];
          }
          msgs[i].text = this.angle[i] + '  ' + this.cangle[i];
          ctx.beginPath();
          ctx.moveTo(x_temp, y_temp);
          x_temp += this.finlength[i]*Math.sin((this.cangle[i]+A_temp)/180*Math.PI);
          y_temp += this.finlength[i]*Math.cos((this.cangle[i]+A_temp)/180*Math.PI);
          if (this.x[i+1] != 0){
            vxnew += Math.pow(this.x[i+1]-x_temp,3)*this.finlength[i]/1000;
            vynew += Math.pow(this.y[i+1]-y_temp,3)*this.finlength[i]/1000;
          }
          this.x[i+1]=x_temp;
          this.y[i+1]=y_temp;
          A_temp = this.cangle[i] + A_temp;
          ctx.lineWidth=3-i;
          ctx.lineTo(x_temp, y_temp);
          ctx.stroke();
          //this.x = this.x-1;
       }60
       var drag = 80;
       vxnew = Math.min(vxnew,2);
       vxnew = Math.max(vxnew,-2);
       this.vx = (vxnew*1+this.vx*drag)/(drag+1);
       this.x[0] += this.vx;
       vynew = Math.min(vynew,2);
       vynew = Math.max(vynew,-2);
       this.vy = (vynew*1+this.vy*drag)/(drag+1);
       this.y[0] += this.vy;
        //finish
    }
}

function msg(text, x, y){
  this.text = text;
  this.color = 'white';
  this.x = x;
  this.y = y;
  this.update = function(){
    ctx = myGameArea.context;
    ctx.font = "16px Arial";
    ctx.fillStyle = '#ffffff';
    ctx.textAlign = "left";
    ctx.fillText(this.text,this.x, this.y);//this.text, this.x, this.y);
  }
}

function updateGameArea() {
    var fpstime2 = new Date;
    //msgs[0].text = Math.round((msgs[0].text*4 + 1000/(fpstime2 - fpstime))/5);
    fpstime = fpstime2;
    myGameArea.clear();
    ctx = myGameArea.context;
    ctx.beginPath();
    ctx.lineWidth=1;
    ctx.arc(A_temp_Global[0], A_temp_Global[1], 10, 0, 2*Math.PI, false);
    ctx.fillStyle = 'yellow';
    ctx.fill();
    ctx.strokeStyle = '#ffffff';
    ctx.stroke();
    for (j = 0; j < 50; j++) {
      squids[j].update();
    }

}

function colorshaker(color){
  /*taked in a color and randomly adjusts it*/
  var p1 = parseInt(color.substring(1,3),16);
  var p2 = parseInt(color.substring(3,5),16);
  var p3 = parseInt(color.substring(5,7),16);
  p1 = p1+(-20+Math.round(40*Math.random()));
  p2 = p2+(-20+Math.round(40*Math.random()));
  p3 = p3+(-20+Math.round(40*Math.random()));
  if (p1 > 255){
    p1 = 255;
  } else if (p1 < 0){
    p1 = 0;
  }
  if (p2 > 255){
    p2 = 255;
  } else if (p2 < 0){
    p2 = 0;
  }
  if (p3 > 255){
    p3 = 255;
  } else if (p3 < 0){
    p3 = 0;
  }
  p1 = p1.toString(16);
  p2 = p2.toString(16);
  p3 = p3.toString(16);
  while (p1.length < 2) {
        p1 = "0" + p1;
    }
    while (p2.length < 2) {
          p2 = "0" + p2;
      }
      while (p3.length < 2) {
            p3 = "0" + p3;
        }
  color = '#'+p1+p2+p3;
  return color;
}
<commit_msg>evolutionis from circle after first centre hit - makes it more fair<commit_after>var squids = [];
var msgs = [];
var fpstime = new Date;
var A_temp_Global = [700/2, 700/2];
function startGame() {
    var offset;
    var finlength;
    var angles;
    var rates;
    for (i = 0; i < 50; i++) {
      offset = [Math.random()*20, Math.random()*20,Math.random()*20];
      finlength = [Math.random()*40, Math.random()*40, Math.random()*40];
      rates = [20+Math.random()*40, 20+Math.random()*40, 20+Math.random()*40];
      angles = [Math.random()*30+offset[0], Math.random()*30+offset[1], Math.random()*30+offset[2]];
      squids[i] = new squid(5, 'red', Math.random()*700, Math.random()*700, finlength, angles, rates, 0, offset);
    }
    msgs[0] = new msg('0', 20, 30);
    msgs[1] = new msg('hello world', 20, 50);
    msgs[2] = new msg('hello world', 20, 70);
    myGameArea.start();
}

var myGameArea = {
    canvas : document.createElement("canvas"),
    start : function() {
        this.canvas.width = 700;
        this.canvas.height = 700;
        this.context = this.canvas.getContext("2d");
        document.body.insertBefore(this.canvas, document.body.childNodes[0]);
        this.interval = setInterval(updateGameArea, 1);
    },
    clear : function() {
        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
    }
}

function squid(size, shcolor, x, y, finlength, angles, rates, cangle, offset) {
    this.size = size;
    this.x = [x,0,0,0];
    this.y = [y,0,0,0];
    this.vx = 0;
    this.vy = 0;
    this.shcolor = shcolor;
    this.offset = offset;
    this.finlength = finlength;
    this.rate = rates;
    this.angle = angles;
    this.cangle = [cangle, cangle, cangle];
    this.update = function(){
        ctx = myGameArea.context;
        //draw head
        ctx.beginPath();
        ctx.lineWidth=1;
        ctx.arc(this.x[0], this.y[0], this.size, 0, 2*Math.PI, false);
        ctx.fillStyle = this.shcolor;
        ctx.fill();
        ctx.strokeStyle = '#ffffff';
        ctx.stroke();
        //draw tail
        var x_temp = this.x[0];
        var y_temp = this.y[0];
        var vxnew = 0;
        var vynew = 0;
        var tanx = (A_temp_Global[0]-this.x[0]);
        var tany = (A_temp_Global[1]-this.y[0]);
        var A_temp = (180/Math.PI)*Math.atan(tanx/tany);
        if (tany>0){
          A_temp-=180;
        }
        if (Math.pow(Math.pow(tanx,2)+Math.pow(tany,2),0.5)<15){
          var offset2;
          var finlength2;
          var angles2;
          var rates2;
          var y_temp;
          var x_temp;
          var A_temp = 0;
          for (i = 0; i < 50; i++) {
            offset2 = [this.offset[0]*(0.8+0.4*Math.random()),this.offset[1]*(0.8+0.4*Math.random()), this.offset[2]*(0.8+0.4*Math.random())];
            finlength2 = [this.finlength[0]*(0.8+0.4*Math.random()),this.finlength[1]*(0.8+0.4*Math.random()), this.finlength[2]*(0.8+0.4*Math.random())];
            rates2 = [this.rate[0]*(0.8+0.4*Math.random()),this.rate[1]*(0.8+0.4*Math.random()), this.rate[2]*(0.8+0.4*Math.random())];
            angles2 = [(this.angle[0]-this.offset[0])*(0.8+0.4*Math.random())+offset2[0],(this.angle[1]-this.offset[1])*(0.8+0.4*Math.random())+offset2[1], (this.angle[2]-this.offset[2])*(0.8+0.4*Math.random())+offset2[2]];
            x_temp = 700/2+250*(Math.sin(A_temp/180*Math.PI));
            y_temp = 700/2+250*(Math.cos(A_temp/180*Math.PI));
            A_temp += (360/50);
            squids[i] = new squid(5, 'red', x_temp, y_temp, finlength2, angles2, rates2, 0, offset2);
          }
          A_temp_Global = [700/2, 700/2];
        }

        for (i = 0; i < 3; i++) {
          //A_temp = this.angle[i]+A_temp;
          this.cangle[i] = this.cangle[i]+ ((this.angle[i]-this.cangle[i])/this.rate[i]);
          if ((this.cangle[i])/this.angle[i] > 0.95) { //if closer than 95% then
            this.angle[i] = -1 * (this.angle[i]-this.offset[i])+this.offset[i];
            if (this.angle[i]<1){
              this.rate[i] *=0.2
            } else {
              this.rate[i] *=(1/0.2)
            }
          //  this.rate[i] = -1 * this.rate[i];
          }
          //msgs[i].text = this.angle[i] + '  ' + this.cangle[i];
          ctx.beginPath();
          ctx.moveTo(x_temp, y_temp);
          x_temp += this.finlength[i]*Math.sin((this.cangle[i]+A_temp)/180*Math.PI);
          y_temp += this.finlength[i]*Math.cos((this.cangle[i]+A_temp)/180*Math.PI);
          if (this.x[i+1] != 0){
            vxnew += Math.pow(this.x[i+1]-x_temp,3)*this.finlength[i]/1000;
            vynew += Math.pow(this.y[i+1]-y_temp,3)*this.finlength[i]/1000;
          }
          this.x[i+1]=x_temp;
          this.y[i+1]=y_temp;
          A_temp = this.cangle[i] + A_temp;
          ctx.lineWidth=3-i;
          ctx.lineTo(x_temp, y_temp);
          ctx.stroke();
          //this.x = this.x-1;
       }60
       var drag = 80;
       vxnew = Math.min(vxnew,2);
       vxnew = Math.max(vxnew,-2);
       this.vx = (vxnew*1+this.vx*drag)/(drag+1);
       this.x[0] += this.vx;
       vynew = Math.min(vynew,2);
       vynew = Math.max(vynew,-2);
       this.vy = (vynew*1+this.vy*drag)/(drag+1);
       this.y[0] += this.vy;
        //finish
    }
}

function msg(text, x, y){
  this.text = text;
  this.color = 'white';
  this.x = x;
  this.y = y;
  this.update = function(){
    ctx = myGameArea.context;
    ctx.font = "16px Arial";
    ctx.fillStyle = '#ffffff';
    ctx.textAlign = "left";
    ctx.fillText(this.text,this.x, this.y);//this.text, this.x, this.y);
  }
}

function updateGameArea() {
    var fpstime2 = new Date;
    msgs[0].text = Math.round((msgs[0].text*4 + 1000/(fpstime2 - fpstime))/5);
    fpstime = fpstime2;
    myGameArea.clear();
    ctx = myGameArea.context;
    ctx.beginPath();
    ctx.lineWidth=1;
    ctx.arc(A_temp_Global[0], A_temp_Global[1], 10, 0, 2*Math.PI, false);
    ctx.fillStyle = 'yellow';
    ctx.fill();
    ctx.strokeStyle = '#ffffff';
    ctx.stroke();
    for (j = 0; j < 50; j++) {
      squids[j].update();
    }
    msgs[0].update();

}

function colorshaker(color){
  /*taked in a color and randomly adjusts it*/
  var p1 = parseInt(color.substring(1,3),16);
  var p2 = parseInt(color.substring(3,5),16);
  var p3 = parseInt(color.substring(5,7),16);
  p1 = p1+(-20+Math.round(40*Math.random()));
  p2 = p2+(-20+Math.round(40*Math.random()));
  p3 = p3+(-20+Math.round(40*Math.random()));
  if (p1 > 255){
    p1 = 255;
  } else if (p1 < 0){
    p1 = 0;
  }
  if (p2 > 255){
    p2 = 255;
  } else if (p2 < 0){
    p2 = 0;
  }
  if (p3 > 255){
    p3 = 255;
  } else if (p3 < 0){
    p3 = 0;
  }
  p1 = p1.toString(16);
  p2 = p2.toString(16);
  p3 = p3.toString(16);
  while (p1.length < 2) {
        p1 = "0" + p1;
    }
    while (p2.length < 2) {
          p2 = "0" + p2;
      }
      while (p3.length < 2) {
            p3 = "0" + p3;
        }
  color = '#'+p1+p2+p3;
  return color;
}
<|endoftext|>


<commit_before>/* SMOOTH SCROLL */
$('a[href^="#"]').on('click', function(event) {
	var target = $(this.getAttribute('href'));
	if (target.length) {
		event.preventDefault();
		$('html, body').stop().animate( {
			scrollTop: target.offset().top
		}, 800);
	}
});<commit_msg>Add effect to open nav hamburguer<commit_after>/* SMOOTH SCROLL */
$('a[href^="#"]').on('click', function(event) {
	var target = $(this.getAttribute('href'));
	if (target.length) {
		event.preventDefault();
		$('html, body').stop().animate( {
			scrollTop: target.offset().top
		}, 800);
	}
});

/* NAV HAMBURGUER */
window.addEventListener('DOMContentLoaded', function(e) {
	document.querySelector('.nav.hamburguer')
		.addEventListener('click', function (e) {
			document.querySelector('.nav.menu').classList.toggle('opened')
		}, false);
}, false);<|endoftext|>


<commit_before>(function($){skel.breakpoints({wide:'(min-width: 961px) and (max-width: 1880px)',normal:'(min-width: 961px) and (max-width: 1620px)',narrow:'(min-width: 961px) and (max-width: 1320px)',narrower:'(max-width: 960px)',mobile:'(max-width: 736px)'});$(function(){var $window=$(window),$body=$('body');$body.addClass('is-loading');$window.on('load',function(){$body.removeClass('is-loading');});if(skel.vars.IEVersion<9)$(':last-child').addClass('last-child');$('form').placeholder();skel.on('+mobile -mobile',function(){$.prioritize('.important\\28 mobile\\29',skel.breakpoint('mobile').active);});$('.scrolly').scrolly();var $nav_a=$('#nav a');$nav_a.scrolly().on('click',function(e){var t=$(this),href=t.attr('href');if(href[0]!='#')return;e.preventDefault();$nav_a.removeClass('active').addClass('scrollzer-locked');t.addClass('active');});var ids=[];$nav_a.each(function(){var href=$(this).attr('href');if(href[0]!='#')return;ids.push(href.substring(1));});$.scrollzer(ids,{pad:200,lastHack:true});$('
'+''+'
').appendTo($body);$('#header').panel({delay:500,hideOnClick:true,hideOnSwipe:true,resetScroll:true,resetForms:true,side:'left',target:$body,visibleClass:'header-visible'});if(skel.vars.os=='wp'&&skel.vars.osVersion<10)$('#headerToggle, #header, #main').css('transition','none');});})(jQuery);

<commit_msg>Update main.js<commit_after>(function($){skel.breakpoints({wide:'(min-width: 961px) and (max-width: 1880px)',normal:'(min-width: 961px) and (max-width: 1620px)',narrow:'(min-width: 961px) and (max-width: 1320px)',narrower:'(max-width: 960px)',mobile:'(max-width: 736px)'});$(function(){var $window=$(window),$body=$('body');$body.addClass('is-loading');$window.on('load',function(){$body.removeClass('is-loading');});if(skel.vars.IEVersion<9)$(':last-child').addClass('last-child');$('form').placeholder();skel.on('+mobile -mobile',function(){$.prioritize('.important\\28 mobile\\29',skel.breakpoint('mobile').active);});$('.scrolly').scrolly();var $nav_a=$('#nav a');$nav_a.scrolly().on('click',function(e){var t=$(this),href=t.attr('href');if(href[0]!='#')return;e.preventDefault();$nav_a.removeClass('active').addClass('scrollzer-locked');t.addClass('active');});var ids=[];$nav_a.each(function(){var href=$(this).attr('href');if(href[0]!='#')return;ids.push(href.substring(1));});$.scrollzer(ids,{pad:200,lastHack:true});$('
'+''+'
').appendTo($body);$('#header').panel({delay:500,hideOnClick:true,hideOnSwipe:true,resetScroll:true,resetForms:true,side:'left',target:$body,visibleClass:'header-visible'});if(skel.vars.os=='wp'&&skel.vars.osVersion<10)$('#headerToggle, #header, #main').css('transition','none');});})(jQuery);
<|endoftext|>


<commit_before>const GLOBAL_ACTION = 'GLOBAL_ACTION';

export const globalAction = () => ({
  type: GLOBAL_ACTION,
});
<commit_msg>Chore: add function signature in App actions<commit_after>const GLOBAL_ACTION = 'GLOBAL_ACTION';

// globalAction :: None -> {Action}
export const globalAction = () => ({
  type: GLOBAL_ACTION,
});
<|endoftext|>


<commit_before>$(document).ready(function(){
     $(window).scroll(function () {
            if ($(this).scrollTop() > 50) {
                $('#back-to-top').fadeIn();
            } else {
                $('#back-to-top').fadeOut();
            }
        });
        // scroll body to 0px on click
        $('#back-to-top').click(function () {
            $('#back-to-top').tooltip('hide');
            $('body,html').animate({
                scrollTop: 0
            }, 800);
            return false;
        });

        $('#back-to-top').tooltip('show');

});<commit_msg>And this time I'll not mess it up.<commit_after>$(document).ready(function(){
     $(window).scroll(function () {
            if ($(this).scrollTop() > 100) {
                $('#go-to-top').fadeIn();
            } else {
                $('#go-to-top').fadeOut();
            }
        });

        $('#go-to-top').click(function () {
            $('#go-to-top').tooltip('hide');
            $('body,html').animate({
                scrollTop: 0
            }, 250);
            return false;
        });

        $('#go-to-top').tooltip('show');
});<|endoftext|>


<commit_before>function LinkedList(){
  this.head = null;
}

LinkedList.prototype.push = function(val){
    var node = {
       value: val,
       next: null
    }

    if(!this.head){
      this.head = node;
    }

    else{
      current = this.head;
      while(current.next){
        current = current.next;
      }
      current.next = node;
    }
}

/*
 * Tests
**/
var linkedList = new LinkedList();

//push node
linkedList.push(2);
linkedList.push(3);
linkedList.push(4);

console.log(linkedList.head); //Object {data: 2, next: Object}
console.log(linkedList.head.next); //Object {data: 3, next: Object}
console.log(linkedList.head.next.next); //Object {data: 4, next: null}
<commit_msg>jshint fixes<commit_after>function LinkedList(){
  this.head = null;
}

LinkedList.prototype.push = function(val){
    var current;

    var node = {
       value: val,
       next: null
    };

    if(!this.head){
      this.head = node;
    } else {
      current = this.head;
      while(current.next){
        current = current.next;
      }
      current.next = node;
    }
};

/*
 * Tests
**/
var linkedList = new LinkedList();

//push node
linkedList.push(2);
linkedList.push(3);
linkedList.push(4);

console.log(linkedList.head); //Object {data: 2, next: Object}
console.log(linkedList.head.next); //Object {data: 3, next: Object}
console.log(linkedList.head.next.next); //Object {data: 4, next: null}
<|endoftext|>


<commit_before>/*
 * Paper.js
 *
 * This file is part of Paper.js, a JavaScript Vector Graphics Library,
 * based on Scriptographer.org and designed to be largely API compatible.
 * http://paperjs.org/
 * http://scriptographer.org/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * All rights reserved.
 */

var PathStyle = this.PathStyle = Base.extend(new function() {
	var keys = ['windingRule', 'resolution', 'strokeColor', 'strokeWidth',
			'strokeCap', 'strokeJoin', 'dashOffset','dashArray', 'miterLimit',
			'strokeOverprint', 'fillColor', 'fillOverprint'];

	var fields = {
		beans: true,

		initialize: function(item, style) {
			this.item = item;
			if (style) {
				for (var i = 0, l = keys.length; i < l; i++) {
					var key = keys[i];
					if (style[key] !== undefined)
						this[key] = style[key];
				}
			}
		}
	};

	Item.inject(Base.each(keys, function(key) {
		var isColor = !!(key.match(/Color$/)),
			set = 'set' + Base.capitalize(key),
			get = 'get' + Base.capitalize(key);

		fields[set] = function(value) {
			if (this.item && this.item.children) {
				for (var i = 0, l = this.item.children.length; i < l; i++) {
					this.item.children[i]._style[set](value);
				}
			} else {
				this['_' + key] = isColor ? Color.read(arguments) : value;
			}
			return this;
		};

		fields[get] = function() {
			if (this.item && this.item.children) {
				var style;
				for (var i = 0, l = this.item.children.length; i < l; i++) {
					var childStyle = this.item.children[i]._style[get]();
					if (!style) {
						style = childStyle;
					} else if (style != childStyle) {
						// If there is another item with a different style:
						return undefined;
					}
				}
				return style;
			} else {
				return this['_' + key];
			}
		};

		this[set] = function(value) {
			this._style[set](value);
			return this;
		};

		this[get] = function() {
			return this._style[get]();
		};
	}, { beans: true }));

	return fields;
});
<commit_msg>Use _item instead of item as internal reference to PathStyle's item.<commit_after>/*
 * Paper.js
 *
 * This file is part of Paper.js, a JavaScript Vector Graphics Library,
 * based on Scriptographer.org and designed to be largely API compatible.
 * http://paperjs.org/
 * http://scriptographer.org/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * All rights reserved.
 */

var PathStyle = this.PathStyle = Base.extend(new function() {
	var keys = ['windingRule', 'resolution', 'strokeColor', 'strokeWidth',
			'strokeCap', 'strokeJoin', 'dashOffset','dashArray', 'miterLimit',
			'strokeOverprint', 'fillColor', 'fillOverprint'];

	var fields = {
		beans: true,

		initialize: function(item, style) {
			this._item = item;
			if (style) {
				for (var i = 0, l = keys.length; i < l; i++) {
					var key = keys[i];
					if (style[key] !== undefined)
						this[key] = style[key];
				}
			}
		}
	};

	Item.inject(Base.each(keys, function(key) {
		var isColor = !!(key.match(/Color$/)),
			set = 'set' + Base.capitalize(key),
			get = 'get' + Base.capitalize(key);

		fields[set] = function(value) {
			if (this._item && this._item.children) {
				for (var i = 0, l = this._item.children.length; i < l; i++) {
					this._item.children[i]._style[set](value);
				}
			} else {
				this['_' + key] = isColor ? Color.read(arguments) : value;
			}
			return this;
		};

		fields[get] = function() {
			if (this._item && this._item.children) {
				var style;
				for (var i = 0, l = this._item.children.length; i < l; i++) {
					var childStyle = this._item.children[i]._style[get]();
					if (!style) {
						style = childStyle;
					} else if (style != childStyle) {
						// If there is another item with a different style:
						return undefined;
					}
				}
				return style;
			} else {
				return this['_' + key];
			}
		};

		this[set] = function(value) {
			this._style[set](value);
			return this;
		};

		this[get] = function() {
			return this._style[get]();
		};
	}, { beans: true }));

	return fields;
});
<|endoftext|>