<commit_before>/* eslint-disable class-methods-use-this */
import React from 'react';
import { mount } from 'enzyme';
import Align from '../src';

describe('element align', () => {
  beforeEach(() => {
    jest.useFakeTimers();
  });

  afterEach(() => {
    jest.useRealTimers();
  });

  const align = {
    points: ['bc', 'tc'],
  };

  class Test extends React.Component {
    getTarget = () => this.$target;

    targetRef = ele => {
      this.$target = ele;
    };

    render() {
      return (

            target

          <Align target={this.getTarget} align={align} {...this.props}>

              source

          </Align>

      );
    }
  }

  it('resize', () => {
    const onAlign = jest.fn();

    const wrapper = mount(<Test monitorWindowResize onAlign={onAlign} />);
    expect(onAlign).toHaveBeenCalled();

    // Window resize
    onAlign.mockReset();
    window.dispatchEvent(new Event('resize'));
    jest.runAllTimers();
    expect(onAlign).toHaveBeenCalled();

    // Not listen resize
    onAlign.mockReset();
    wrapper.setProps({ monitorWindowResize: false });
    window.dispatchEvent(new Event('resize'));
    jest.runAllTimers();
    expect(onAlign).not.toHaveBeenCalled();

    // Remove should not crash
    wrapper.setProps({ monitorWindowResize: true });
    wrapper.unmount();
  });

  it('disabled should trigger align', () => {
    const onAlign = jest.fn();

    const wrapper = mount(<Test monitorWindowResize onAlign={onAlign} disabled />);
    expect(onAlign).not.toHaveBeenCalled();

    wrapper.setProps({ disabled: false });
    jest.runAllTimers();
    expect(onAlign).toHaveBeenCalled();
  });
});
/* eslint-enable */
<commit_msg>test: fix test case<commit_after>/* eslint-disable class-methods-use-this */
import React from 'react';
import { mount } from 'enzyme';
import { spyElementPrototype } from 'rc-util/lib/test/domHook';
import Align from '../src';

describe('element align', () => {
  beforeAll(() => {
    spyElementPrototype(HTMLElement, 'offsetParent', {
      get: () => ({}),
    });
  });

  beforeEach(() => {
    jest.useFakeTimers();
  });

  afterEach(() => {
    jest.useRealTimers();
  });

  const align = {
    points: ['bc', 'tc'],
  };

  class Test extends React.Component {
    getTarget = () => this.$target;

    targetRef = ele => {
      this.$target = ele;
    };

    render() {
      return (

            target

          <Align target={this.getTarget} align={align} {...this.props}>

              source

          </Align>

      );
    }
  }

  it('resize', () => {
    const onAlign = jest.fn();

    const wrapper = mount(<Test monitorWindowResize onAlign={onAlign} />);
    expect(onAlign).toHaveBeenCalled();

    // Window resize
    onAlign.mockReset();
    window.dispatchEvent(new Event('resize'));
    jest.runAllTimers();
    expect(onAlign).toHaveBeenCalled();

    // Not listen resize
    onAlign.mockReset();
    wrapper.setProps({ monitorWindowResize: false });
    window.dispatchEvent(new Event('resize'));
    jest.runAllTimers();
    expect(onAlign).not.toHaveBeenCalled();

    // Remove should not crash
    wrapper.setProps({ monitorWindowResize: true });
    wrapper.unmount();
  });

  it('disabled should trigger align', () => {
    const onAlign = jest.fn();

    const wrapper = mount(<Test monitorWindowResize onAlign={onAlign} disabled />);
    expect(onAlign).not.toHaveBeenCalled();

    wrapper.setProps({ disabled: false });
    jest.runAllTimers();
    expect(onAlign).toHaveBeenCalled();
  });
});
/* eslint-enable */
<|endoftext|>


<commit_before>'use strict';

const playerBar = '[class*=BottomFixed]';
const controlBar = '[data-test=controls-container]';

Connector.playerSelector = playerBar;

Connector.pauseButtonSelector = `${controlBar} button[data-test-state=PLAYING]`;

Connector.artistSelector = `${playerBar} [data-test=line-text]:nth-child(3)`;

Connector.trackSelector = `${playerBar} [data-test=line-text]:nth-child(2)`;

Connector.isScrobblingAllowed = () => {
	const track = Connector.getTrack();
	return track && !track.startsWith('Thanks for listening');
};
<commit_msg>Fix iheartradio connector<commit_after>'use strict';

const playerBar = '[data-test=player-container]';
const controlBar = '[data-test=controls-container]';

Connector.playerSelector = playerBar;

Connector.pauseButtonSelector = `${controlBar} button[data-test-state=PLAYING]`;

Connector.artistSelector = `${playerBar} [data-test=line-text]:nth-child(3)`;

Connector.trackSelector = `${playerBar} [data-test=line-text]:nth-child(2)`;

Connector.isScrobblingAllowed = () => {
	const track = Connector.getTrack();
	return track && !track.startsWith('Thanks for listening');
};
<|endoftext|>


<commit_before>/*
 * node-website-copier
 * https://github.com/mxcoder/node-website-copier
 *
 * Copyright (c) 2014 Ricardo Vega
 * Licensed under the MIT license.
 */

'use strict';
module.exports = function() {

    var fs = require('fs'),
        path = require('path');

    function isFile(fn) {
        try {
            var ss = fs.statSync(fn);
            return ss ? ss.isFile() : false;
        } catch (e) {
            return false;
        }
    }

    function download(url, verbose) {
        var parseUrl = require('parse-url'),
            exec = require('child_process').exec,
            parsedUrl, folder, domain, wgetCmd, childproc, indexFile, indexFileOld;

        // Parses url to detect hostname, for folder name
        parsedUrl = parseUrl(url);
        if (!parsedUrl) {
            throw new Error('Cannot understand the URL: ' + url);
        }
        domain = parsedUrl.baseUrl.replace('www.','');
        folder = domain.replace(/\W/g,'_');

        // TODO - Replace wget with node request on workers
        wgetCmd = [
            'wget', // common
            '--random-wait','--wait=1','--timeout=2', // connection
            // request
            //'--header="accept-encoding: gzip,deflate"',
            '--header="accept-encoding: deflate"',
            '--execute="robots=off"','--user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.19 (KHTML, like Gecko) Ubuntu/12.04 Chromium/18.0.1025.168 Chrome/18.0.1025.168 Safari/535.19"',
            '--no-parent','--reject=js,*ord=*,*php*','--ignore-case', '--span-hosts', // spider
            '--page-requisites','--adjust-extension','--convert-links', // parser
            '--no-directories','--content-disposition','--directory-prefix='+(folder), // saving
            url
        ].join(' ');
        if (verbose) {
            console.log("WGET command: "+wgetCmd);
        }
        childproc = exec(wgetCmd, {maxBuffer:1024*500}, function(error, stdout, stderr){
            if (verbose) {
                console.log(stderr);
                console.log(stdout);
            }
            // TODO handle gzipped files accordingly
            if (error !== null) {
                throw new Error('Wget Error:' + error);
            } else {
                // gzip -d gzipped files && removes pixel files
                exec([
                    'cd '+(folder),
                    'for f in *',
                        'do if [ "1" -eq `file $f | grep -c gzip` ]',
                            'then mv "$f" "$f.gz"',
                            'gzip -d "$f.gz"',
                        'fi',
                    'done',
                    'for f in *',
                        'do if [ "1" -eq `file $f | grep -c "1 x 1"` ]',
                            'then rm "$f"',
                        'fi',
                    'done',
                ].join(';'));

                // beautifies index.html, if none, it creates it
                indexFile = path.join(folder,'index.html');
                indexFileOld = path.join(folder, parsedUrl.file);
                if (isFile(indexFileOld) && !isFile(indexFile)) {
                    fs.renameSync(indexFileOld, indexFile);
                }
                beautify(indexFile);
            }
        });
    }

    function beautify(filename, verbose) {
        if (!isFile(filename)) {
            throw new Error('Cannot read the file' + filename)
        }
        fs.readFile(filename, "utf8", function(err, contents){
            if (err !== null) {
                throw err;
            }
            var htmlParser = require("html-parser"),
                sanitized = htmlParser.sanitize(contents, {
                    elements: ['script','iframe','noscript'],
                    attributes: function(name, value){
                        switch(true) {
                            case /prefix/.test(name):
                            case /xmlns/.test(name):
                            case /data-/.test(name):
                            case /item/.test(name):
                            case /on[click|mouse]/.test(name):
                                return true;
                        }
                    },
                    comments: false
                });
            writeFile(filename, sanitized);
        });
    }

    function writeFile(filename, content) {
        if (!isFile(filename)) {
            throw new Error('Cannot write the file: ' + filename);
        }
        // Write to file
        fs.writeFile(filename, require("html/lib/html").prettyPrint(content, {indent_size: 4, max_char: 3000, brace_style: 'collapse', unformatted:[]}), function(err){
            if (err) throw err;
        });
    }

    return {
        download: download,
        beautify: beautify
    }
}()
<commit_msg>Removing href parameters, unless its for a css file<commit_after>/*
 * node-website-copier
 * https://github.com/mxcoder/node-website-copier
 *
 * Copyright (c) 2014 Ricardo Vega
 * Licensed under the MIT license.
 */

'use strict';
module.exports = function() {

    var fs = require('fs'),
        path = require('path');

    function isFile(fn) {
        try {
            var ss = fs.statSync(fn);
            return ss ? ss.isFile() : false;
        } catch (e) {
            return false;
        }
    }

    function download(url, verbose) {
        var parseUrl = require('parse-url'),
            exec = require('child_process').exec,
            parsedUrl, folder, domain, wgetCmd, childproc, indexFile, indexFileOld;

        // Parses url to detect hostname, for folder name
        parsedUrl = parseUrl(url);
        if (!parsedUrl) {
            throw new Error('Cannot understand the URL: ' + url);
        }
        domain = parsedUrl.baseUrl.replace('www.','');
        folder = domain.replace(/\W/g,'_');

        // TODO - Replace wget with node request on workers
        wgetCmd = [
            'wget', // common
            '--random-wait','--wait=1','--timeout=2', // connection
            // request
            //'--header="accept-encoding: gzip,deflate"',
            '--header="accept-encoding: deflate"',
            '--execute="robots=off"','--user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.19 (KHTML, like Gecko) Ubuntu/12.04 Chromium/18.0.1025.168 Chrome/18.0.1025.168 Safari/535.19"',
            '--no-parent','--reject=js,*ord=*,*php*','--ignore-case', '--span-hosts', // spider
            '--page-requisites','--adjust-extension','--convert-links', // parser
            '--no-directories','--content-disposition','--directory-prefix='+(folder), // saving
            url
        ].join(' ');
        if (verbose) {
            console.log("WGET command: "+wgetCmd);
        }
        childproc = exec(wgetCmd, {maxBuffer:1024*500}, function(error, stdout, stderr){
            if (verbose) {
                console.log(stderr);
                console.log(stdout);
            }
            // TODO handle gzipped files accordingly
            if (error !== null) {
                throw new Error('Wget Error:' + error);
            } else {
                // gzip -d gzipped files && removes pixel files
                exec([
                    'cd '+(folder),
                    'for f in *',
                        'do if [ "1" -eq `file $f | grep -c gzip` ]',
                            'then mv "$f" "$f.gz"',
                            'gzip -d "$f.gz"',
                        'fi',
                    'done',
                    'for f in *',
                        'do if [ "1" -eq `file $f | grep -c "1 x 1"` ]',
                            'then rm "$f"',
                        'fi',
                    'done',
                ].join(';'));

                // beautifies index.html, if none, it creates it
                indexFile = path.join(folder,'index.html');
                indexFileOld = path.join(folder, parsedUrl.file);
                if (isFile(indexFileOld) && !isFile(indexFile)) {
                    fs.renameSync(indexFileOld, indexFile);
                }
                beautify(indexFile);
            }
        });
    }

    function beautify(filename, verbose) {
        if (!isFile(filename)) {
            throw new Error('Cannot read the file' + filename)
        }
        fs.readFile(filename, "utf8", function(err, contents){
            if (err !== null) {
                throw err;
            }
            var htmlParser = require("html-parser"),
                sanitized = htmlParser.sanitize(contents, {
                    elements: ['script','iframe','noscript'],
                    attributes: function(name, value){
                        switch(true) {
                            case (/href/.test(name) && !/css/.test(value)):
                            case /prefix/.test(name):
                            case /xmlns/.test(name):
                            case /data-/.test(name):
                            case /item/.test(name):
                            case /on[click|mouse]/.test(name):
                                return true;
                        }
                    },
                    comments: false
                });
            writeFile(filename, sanitized);
        });
    }

    function writeFile(filename, content) {
        if (!isFile(filename)) {
            throw new Error('Cannot write the file: ' + filename);
        }
        // Write to file
        fs.writeFile(filename, require("html/lib/html").prettyPrint(content, {indent_size: 4, max_char: 3000, brace_style: 'collapse', unformatted:[]}), function(err){
            if (err) throw err;
        });
    }

    return {
        download: download,
        beautify: beautify
    }
}()
<|endoftext|>


<commit_before>/*global define, Candy */
/*jshint -W027*/

define([
		'intern!bdd'
	, 'intern/chai!expect'
	, 'intern/order!jquery'
	, 'intern/order!candy/libs.bundle.js'
	, 'intern/order!candy/src/candy.js'
	, 'intern/order!candy/src/core.js'
	, 'intern/order!candy/src/util.js'
], function (bdd, expect) {
	bdd.describe('Candy.Util', function () {
		bdd.describe('jidToId', function () {
			bdd.it('should MD5 hash a JID', function () {
				expect(Candy.Util.jidToId('foo@bar.com')).to.equal('f3ada405ce890b6f8204094deb12d8a8');
			});
		});

		bdd.describe('escapeJid', function () {
			bdd.it('should escape JIDs per XEP-0106', function () {
				expect(Candy.Util.escapeJid("space cadet@example.com")).to.equal("space\\20cadet@example.com");
			});
			bdd.it('should escape JIDs per XEP-0106', function () {
				expect(Candy.Util.escapeJid("call me \"ishmael\"@example.com")).to.equal("call\\20me\\20\\22ishmael\\22@example.com");
			});
			bdd.it('should escape JIDs per XEP-0106', function () {
				expect(Candy.Util.escapeJid("at&t guy@example.com")).to.equal("at\\26t\\20guy@example.com");
			});
			bdd.it('should escape JIDs per XEP-0106', function () {
				expect(Candy.Util.escapeJid("d'artagnan@example.com")).to.equal("d\\27artagnan@example.com");
			});
			bdd.it('should escape JIDs per XEP-0106', function () {
				expect(Candy.Util.escapeJid("/.fanboy@example.com")).to.equal("\\2f.fanboy@example.com");
			});
			bdd.it('should escape JIDs per XEP-0106', function () {
				expect(Candy.Util.escapeJid("::foo::@example.com")).to.equal("\\3a\\3afoo\\3a\\3a@example.com");
			});
			bdd.it('should escape JIDs per XEP-0106', function () {
				expect(Candy.Util.escapeJid("<foo>@example.com")).to.equal("\\3cfoo\\3e@example.com");
			});
			// Skip this for now. See https://github.com/theintern/intern/pull/195
			bdd.skip('should escape JIDs per XEP-0106', function () {
				expect(Candy.Util.escapeJid("user@host@example.com")).to.equal("user\\40host@example.com");
			});
			bdd.it('should escape JIDs per XEP-0106', function () {
				expect(Candy.Util.escapeJid("c:\\net@example.com")).to.equal('c\\3a\\5cnet@example.com');
			});
			bdd.it('should escape JIDs per XEP-0106', function () {
				expect(Candy.Util.escapeJid("c:\\net@example.com")).to.equal("c\\3a\\5cnet@example.com");
			});
			bdd.it('should escape JIDs per XEP-0106', function () {
				expect(Candy.Util.escapeJid("c:\\cool stuff@example.com")).to.equal("c\\3a\\5ccool\\20stuff@example.com");
			});
			bdd.it('should escape JIDs per XEP-0106', function () {
				expect(Candy.Util.escapeJid("c:\\5commas@example.com")).to.equal("c\\3a\\5c5commas@example.com");
			});
		});

		bdd.describe('unescapeJid', function () {
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid("space\\20cadet@example.com")).to.equal("space cadet@example.com");
			});
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid("call\\20me\\20\\22ishmael\\22@example.com")).to.equal("call me \"ishmael\"@example.com");
			});
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid("at\\26t\\20guy@example.com")).to.equal("at&t guy@example.com");
			});
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid("d\\27artagnan@example.com")).to.equal("d'artagnan@example.com");
			});
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid("\\2f.fanboy@example.com")).to.equal("/.fanboy@example.com");
			});
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid("\\3a\\3afoo\\3a\\3a@example.com")).to.equal("::foo::@example.com");
			});
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid("\\3cfoo\\3e@example.com")).to.equal("<foo>@example.com");
			});
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid("user\\40host@example.com")).to.equal("user@host@example.com");
			});
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid('c\\3a\\5cnet@example.com')).to.equal("c:\\net@example.com");
			});
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid("c\\3a\\5cnet@example.com")).to.equal("c:\\net@example.com");
			});
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid("c\\3a\\5ccool\\20stuff@example.com")).to.equal("c:\\cool stuff@example.com");
			});
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid("c\\3a\\5c5commas@example.com")).to.equal("c:\\5commas@example.com");
			});
		});

		bdd.describe('crop', function () {
			bdd.describe('with a string longer than the crop length', function () {
				bdd.it('crops the string to the specified length and replaces the end with elipses', function () {
					expect(Candy.Util.crop('FooBarBaz', 6)).to.equal('Foo...');
				});
			});

			bdd.describe('with a string the same length as the crop length', function () {
				bdd.it('does not modify the string', function () {
					expect(Candy.Util.crop('FooBar', 6)).to.equal('FooBar');
				});
			});

			bdd.describe('with a string shorter than the crop length', function () {
				bdd.it('does not modify the string', function () {
					expect(Candy.Util.crop('FooBar', 9)).to.equal('FooBar');
				});
			});
		});

		bdd.describe('Parser', function () {
			bdd.describe('jid', function () {
				bdd.it('should parse JIDs per RFC6122', function () {
					var jid = Candy.Util.Parser.jid("space cadet@example.com");
					expect(jid.node).to.equal("space cadet");
					expect(jid.domain).to.equal("example.com");
					expect(jid.resource).to.equal(undefined);
				});
				bdd.it('should parse JIDs per RFC6122', function () {
					var jid = Candy.Util.Parser.jid("call me \"ishmael\"@example.com");
					expect(jid.node).to.equal("call me \"ishmael\"");
					expect(jid.domain).to.equal("example.com");
					expect(jid.resource).to.equal(undefined);
				});
				bdd.it('should parse JIDs per RFC6122', function () {
					var jid = Candy.Util.Parser.jid("at&t guy@example.com");
					expect(jid.node).to.equal("at&t guy");
					expect(jid.domain).to.equal("example.com");
					expect(jid.resource).to.equal(undefined);
				});
				bdd.it('should parse JIDs per RFC6122', function () {
					var jid = Candy.Util.Parser.jid("d'artagnan@example.com");
					expect(jid.node).to.equal("d'artagnan");
					expect(jid.domain).to.equal("example.com");
					expect(jid.resource).to.equal(undefined);
				});
				bdd.it('should parse JIDs per RFC6122', function () {
					var jid = Candy.Util.Parser.jid("/.fanboy@example.com");
					expect(jid.node).to.equal("/.fanboy");
					expect(jid.domain).to.equal("example.com");
					expect(jid.resource).to.equal(undefined);
				});
				bdd.it('should parse JIDs per RFC6122', function () {
					var jid = Candy.Util.Parser.jid("::foo::@example.com");
					expect(jid.node).to.equal("::foo::");
					expect(jid.domain).to.equal("example.com");
					expect(jid.resource).to.equal(undefined);
				});
				bdd.it('should parse JIDs per RFC6122', function () {
					var jid = Candy.Util.Parser.jid("<foo>@example.com");
					expect(jid.node).to.equal("<foo>");
					expect(jid.domain).to.equal("example.com");
					expect(jid.resource).to.equal(undefined);
				});
				// Skip this for now. See https://github.com/theintern/intern/pull/195
				bdd.skip('should parse JIDs per RFC6122', function () {
					var jid = Candy.Util.Parser.jid("user@host@example.com");
					expect(jid.node).to.equal("user@host");
					expect(jid.domain).to.equal("example.com");
					expect(jid.resource).to.equal(undefined);
				});
				bdd.it('should parse JIDs per RFC6122', function () {
					var jid = Candy.Util.Parser.jid("c:\\net@example.com");
					expect(jid.node).to.equal('c:\\net');
					expect(jid.domain).to.equal('example.com');
					expect(jid.resource).to.equal(undefined);
				});
				bdd.it('should parse JIDs per RFC6122', function () {
					var jid = Candy.Util.Parser.jid("c:\\net@example.com");
					expect(jid.node).to.equal("c:\\net");
					expect(jid.domain).to.equal("example.com");
					expect(jid.resource).to.equal(undefined);
				});
				bdd.it('should parse JIDs per RFC6122', function () {
					var jid = Candy.Util.Parser.jid("c:\\cool stuff@example.com");
					expect(jid.node).to.equal("c:\\cool stuff");
					expect(jid.domain).to.equal("example.com");
					expect(jid.resource).to.equal(undefined);
				});
				bdd.it('should parse JIDs per RFC6122', function () {
					var jid = Candy.Util.Parser.jid("c:\\5commas@example.com");
					expect(jid.node).to.equal("c:\\5commas");
					expect(jid.domain).to.equal("example.com");
					expect(jid.resource).to.equal(undefined);
				});
			});
		});
	});
});
<commit_msg>Revert "Skip tests in the nice way"<commit_after>/*global define, Candy */
/*jshint -W027*/

define([
		'intern!bdd'
	, 'intern/chai!expect'
	, 'intern/order!jquery'
	, 'intern/order!candy/libs.bundle.js'
	, 'intern/order!candy/src/candy.js'
	, 'intern/order!candy/src/core.js'
	, 'intern/order!candy/src/util.js'
], function (bdd, expect) {
	bdd.describe('Candy.Util', function () {
		bdd.describe('jidToId', function () {
			bdd.it('should MD5 hash a JID', function () {
				expect(Candy.Util.jidToId('foo@bar.com')).to.equal('f3ada405ce890b6f8204094deb12d8a8');
			});
		});

		bdd.describe('escapeJid', function () {
			bdd.it('should escape JIDs per XEP-0106', function () {
				expect(Candy.Util.escapeJid("space cadet@example.com")).to.equal("space\\20cadet@example.com");
			});
			bdd.it('should escape JIDs per XEP-0106', function () {
				expect(Candy.Util.escapeJid("call me \"ishmael\"@example.com")).to.equal("call\\20me\\20\\22ishmael\\22@example.com");
			});
			bdd.it('should escape JIDs per XEP-0106', function () {
				expect(Candy.Util.escapeJid("at&t guy@example.com")).to.equal("at\\26t\\20guy@example.com");
			});
			bdd.it('should escape JIDs per XEP-0106', function () {
				expect(Candy.Util.escapeJid("d'artagnan@example.com")).to.equal("d\\27artagnan@example.com");
			});
			bdd.it('should escape JIDs per XEP-0106', function () {
				expect(Candy.Util.escapeJid("/.fanboy@example.com")).to.equal("\\2f.fanboy@example.com");
			});
			bdd.it('should escape JIDs per XEP-0106', function () {
				expect(Candy.Util.escapeJid("::foo::@example.com")).to.equal("\\3a\\3afoo\\3a\\3a@example.com");
			});
			bdd.it('should escape JIDs per XEP-0106', function () {
				expect(Candy.Util.escapeJid("<foo>@example.com")).to.equal("\\3cfoo\\3e@example.com");
			});
			bdd.it('should escape JIDs per XEP-0106', function () {
				return true; // Skip this for now. See https://github.com/theintern/intern/pull/195
				expect(Candy.Util.escapeJid("user@host@example.com")).to.equal("user\\40host@example.com");
			});
			bdd.it('should escape JIDs per XEP-0106', function () {
				expect(Candy.Util.escapeJid("c:\\net@example.com")).to.equal('c\\3a\\5cnet@example.com');
			});
			bdd.it('should escape JIDs per XEP-0106', function () {
				expect(Candy.Util.escapeJid("c:\\net@example.com")).to.equal("c\\3a\\5cnet@example.com");
			});
			bdd.it('should escape JIDs per XEP-0106', function () {
				expect(Candy.Util.escapeJid("c:\\cool stuff@example.com")).to.equal("c\\3a\\5ccool\\20stuff@example.com");
			});
			bdd.it('should escape JIDs per XEP-0106', function () {
				expect(Candy.Util.escapeJid("c:\\5commas@example.com")).to.equal("c\\3a\\5c5commas@example.com");
			});
		});

		bdd.describe('unescapeJid', function () {
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid("space\\20cadet@example.com")).to.equal("space cadet@example.com");
			});
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid("call\\20me\\20\\22ishmael\\22@example.com")).to.equal("call me \"ishmael\"@example.com");
			});
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid("at\\26t\\20guy@example.com")).to.equal("at&t guy@example.com");
			});
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid("d\\27artagnan@example.com")).to.equal("d'artagnan@example.com");
			});
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid("\\2f.fanboy@example.com")).to.equal("/.fanboy@example.com");
			});
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid("\\3a\\3afoo\\3a\\3a@example.com")).to.equal("::foo::@example.com");
			});
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid("\\3cfoo\\3e@example.com")).to.equal("<foo>@example.com");
			});
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid("user\\40host@example.com")).to.equal("user@host@example.com");
			});
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid('c\\3a\\5cnet@example.com')).to.equal("c:\\net@example.com");
			});
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid("c\\3a\\5cnet@example.com")).to.equal("c:\\net@example.com");
			});
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid("c\\3a\\5ccool\\20stuff@example.com")).to.equal("c:\\cool stuff@example.com");
			});
			bdd.it('should unescape JIDs per XEP-0106', function () {
				expect(Candy.Util.unescapeJid("c\\3a\\5c5commas@example.com")).to.equal("c:\\5commas@example.com");
			});
		});

		bdd.describe('crop', function () {
			bdd.describe('with a string longer than the crop length', function () {
				bdd.it('crops the string to the specified length and replaces the end with elipses', function () {
					expect(Candy.Util.crop('FooBarBaz', 6)).to.equal('Foo...');
				});
			});

			bdd.describe('with a string the same length as the crop length', function () {
				bdd.it('does not modify the string', function () {
					expect(Candy.Util.crop('FooBar', 6)).to.equal('FooBar');
				});
			});

			bdd.describe('with a string shorter than the crop length', function () {
				bdd.it('does not modify the string', function () {
					expect(Candy.Util.crop('FooBar', 9)).to.equal('FooBar');
				});
			});
		});

		bdd.describe('Parser', function () {
			bdd.describe('jid', function () {
				bdd.it('should parse JIDs per RFC6122', function () {
					var jid = Candy.Util.Parser.jid("space cadet@example.com");
					expect(jid.node).to.equal("space cadet");
					expect(jid.domain).to.equal("example.com");
					expect(jid.resource).to.equal(undefined);
				});
				bdd.it('should parse JIDs per RFC6122', function () {
					var jid = Candy.Util.Parser.jid("call me \"ishmael\"@example.com");
					expect(jid.node).to.equal("call me \"ishmael\"");
					expect(jid.domain).to.equal("example.com");
					expect(jid.resource).to.equal(undefined);
				});
				bdd.it('should parse JIDs per RFC6122', function () {
					var jid = Candy.Util.Parser.jid("at&t guy@example.com");
					expect(jid.node).to.equal("at&t guy");
					expect(jid.domain).to.equal("example.com");
					expect(jid.resource).to.equal(undefined);
				});
				bdd.it('should parse JIDs per RFC6122', function () {
					var jid = Candy.Util.Parser.jid("d'artagnan@example.com");
					expect(jid.node).to.equal("d'artagnan");
					expect(jid.domain).to.equal("example.com");
					expect(jid.resource).to.equal(undefined);
				});
				bdd.it('should parse JIDs per RFC6122', function () {
					var jid = Candy.Util.Parser.jid("/.fanboy@example.com");
					expect(jid.node).to.equal("/.fanboy");
					expect(jid.domain).to.equal("example.com");
					expect(jid.resource).to.equal(undefined);
				});
				bdd.it('should parse JIDs per RFC6122', function () {
					var jid = Candy.Util.Parser.jid("::foo::@example.com");
					expect(jid.node).to.equal("::foo::");
					expect(jid.domain).to.equal("example.com");
					expect(jid.resource).to.equal(undefined);
				});
				bdd.it('should parse JIDs per RFC6122', function () {
					var jid = Candy.Util.Parser.jid("<foo>@example.com");
					expect(jid.node).to.equal("<foo>");
					expect(jid.domain).to.equal("example.com");
					expect(jid.resource).to.equal(undefined);
				});
				bdd.it('should parse JIDs per RFC6122', function () {
					return true; // Skip this for now. See https://github.com/theintern/intern/pull/195
					var jid = Candy.Util.Parser.jid("user@host@example.com");
					expect(jid.node).to.equal("user@host");
					expect(jid.domain).to.equal("example.com");
					expect(jid.resource).to.equal(undefined);
				});
				bdd.it('should parse JIDs per RFC6122', function () {
					var jid = Candy.Util.Parser.jid("c:\\net@example.com");
					expect(jid.node).to.equal('c:\\net');
					expect(jid.domain).to.equal('example.com');
					expect(jid.resource).to.equal(undefined);
				});
				bdd.it('should parse JIDs per RFC6122', function () {
					var jid = Candy.Util.Parser.jid("c:\\net@example.com");
					expect(jid.node).to.equal("c:\\net");
					expect(jid.domain).to.equal("example.com");
					expect(jid.resource).to.equal(undefined);
				});
				bdd.it('should parse JIDs per RFC6122', function () {
					var jid = Candy.Util.Parser.jid("c:\\cool stuff@example.com");
					expect(jid.node).to.equal("c:\\cool stuff");
					expect(jid.domain).to.equal("example.com");
					expect(jid.resource).to.equal(undefined);
				});
				bdd.it('should parse JIDs per RFC6122', function () {
					var jid = Candy.Util.Parser.jid("c:\\5commas@example.com");
					expect(jid.node).to.equal("c:\\5commas");
					expect(jid.domain).to.equal("example.com");
					expect(jid.resource).to.equal(undefined);
				});
			});
		});
	});
});
<|endoftext|>


<commit_before>import path from 'path'
import slash from 'slash'
import fs from 'fs-extra'
import { chunkNameFromFile } from '../utils/chunkBuilder'

export default async ({ config }) => {
  const { templates, routes, paths } = config

  const route404 = routes.find(route => route.path === '404')
  const id404 = route404.templateIndex

  const productionImports = `
import universal, { setHasBabelPlugin } from '${
    process.env.REACT_STATIC_UNIVERSAL_PATH
  }'
  `
  const developmentImports = ''

  const productionTemplates = `
setHasBabelPlugin()

const universalOptions = {
  loading: () => null,
  error: props => {
    console.error(props.error);
    return
An error occurred loading this page's template. More information is available in the console.
;
  },
}

${templates
    .map((template, index) => {
      let templatePath = path.relative(
        paths.DIST,
        path.resolve(paths.ROOT, template)
      )

      let chunkName = ''

      // relative resolving produces the wrong path, a "../" is missing
      // as the files looks equal, we simple use an absolute path then
      if (!paths.DIST.startsWith(paths.ROOT)) {
        templatePath = path.resolve(paths.ROOT, template)

        chunkName = `/* webpackChunkName: "${chunkNameFromFile(template)}" */`
      }

      return `const t_${index} = universal(import('${slash(
        templatePath
      )}'${chunkName}), universalOptions)`
    })
    .join('\n')}
`

  const developmentTemplates = templates
    .map((template, index) => {
      const templatePath = path.relative(
        paths.DIST,
        path.resolve(paths.ROOT, template)
      )
      return `import t_${index} from '${slash(templatePath)}'`
    })
    .join('\n')

  const file = `
${
    process.env.NODE_ENV === 'production'
      ? productionImports
      : developmentImports
  }

${
    process.env.NODE_ENV === 'production'
      ? productionTemplates
      : developmentTemplates
  }

export const template404ID = ${id404}

// Template Map
export default [
  ${templates.map((template, index) => `t_${index}`).join(',\n')}
]
`

  const dynamicRoutesPath = path.join(paths.DIST, 'react-static-templates.js')
  await fs.remove(dynamicRoutesPath)
  await fs.outputFile(dynamicRoutesPath, file)
}
<commit_msg>Replace Windows-style path separators in generated template file (#880)<commit_after>import path from 'path'
import slash from 'slash'
import fs from 'fs-extra'
import { chunkNameFromFile } from '../utils/chunkBuilder'

export default async ({ config }) => {
  const { templates, routes, paths } = config

  const route404 = routes.find(route => route.path === '404')
  const id404 = route404.templateIndex

  // convert Windows-style path separators to the Unix style to ensure sure the
  // string literal is valid and doesn't contain escaped characters
  const reactStaticUniversalPath = process.env.REACT_STATIC_UNIVERSAL_PATH.split(
    '\\'
  ).join('/')

  const productionImports = `import universal, { setHasBabelPlugin } from '${reactStaticUniversalPath}'`
  const developmentImports = ''

  const productionTemplates = `
setHasBabelPlugin()

const universalOptions = {
  loading: () => null,
  error: props => {
    console.error(props.error);
    return
An error occurred loading this page's template. More information is available in the console.
;
  },
}

${templates
    .map((template, index) => {
      let templatePath = path.relative(
        paths.DIST,
        path.resolve(paths.ROOT, template)
      )

      let chunkName = ''

      // relative resolving produces the wrong path, a "../" is missing
      // as the files looks equal, we simple use an absolute path then
      if (!paths.DIST.startsWith(paths.ROOT)) {
        templatePath = path.resolve(paths.ROOT, template)

        chunkName = `/* webpackChunkName: "${chunkNameFromFile(template)}" */`
      }

      return `const t_${index} = universal(import('${slash(
        templatePath
      )}'${chunkName}), universalOptions)`
    })
    .join('\n')}
`

  const developmentTemplates = templates
    .map((template, index) => {
      const templatePath = path.relative(
        paths.DIST,
        path.resolve(paths.ROOT, template)
      )
      return `import t_${index} from '${slash(templatePath)}'`
    })
    .join('\n')

  const file = `
${
    process.env.NODE_ENV === 'production'
      ? productionImports
      : developmentImports
  }

${
    process.env.NODE_ENV === 'production'
      ? productionTemplates
      : developmentTemplates
  }

export const template404ID = ${id404}

// Template Map
export default [
  ${templates.map((template, index) => `t_${index}`).join(',\n')}
]
`

  const dynamicRoutesPath = path.join(paths.DIST, 'react-static-templates.js')
  await fs.remove(dynamicRoutesPath)
  await fs.outputFile(dynamicRoutesPath, file)
}
<|endoftext|>


<commit_before>define([], function(helpers) {

	return ["$http", "ApiServer", function($http, api) {

		return function(searchText) {
			return new Promise(function(resolve, reject) {
				$http.get(api + "/content/search/" + searchText + "?types=isaacConceptPage,isaacQuestionPage").then(function(r) {
					var results = r.data;
					console.log("Received content search results:", results);

					var ids = [];

					for (var i in results.results) {
						ids.push({id: results.results[i].id, title: results.results[i].title, type: results.results[i].type});
					}

					return resolve(ids);
				}).catch(function (e) {
					console.error("Error searching for content ids:", e);
					return reject(e);
				})
			});
		}

	}];

});<commit_msg>Correctly load content IDs.<commit_after>define([], function(helpers) {

	return ["$http", "ApiServer", function($http, api) {

		return function(searchText) {
			return new Promise(function(resolve, reject) {
				$http.get(api + "/search/" + searchText + "?types=isaacConceptPage,isaacQuestionPage").then(function(r) {
					var results = r.data;
					console.log("Received content search results:", results);

					var ids = [];

					for (var i in results.results) {
						ids.push({id: results.results[i].id, title: results.results[i].title, type: results.results[i].type});
					}

					return resolve(ids);
				}).catch(function (e) {
					console.error("Error searching for content ids:", e);
					return reject(e);
				})
			});
		}

	}];

});<|endoftext|>


<commit_before>(function(global) {

  var globalModules = {
    set: function setModule (moduleName, dependencies) {
      var parentModulePath = modulePath(moduleName).slice(0, -1);

      for (var i = 0; i < parentModulePath.length; i++) {
        var p = parentModulePath[i];
        if (!globalModules[p]) {
          globalModules.set(p, []);
          globalModules.get(p).created = true;
        }
        globalModules.get(p).contains[moduleName] = true;
      }

      globalModules[moduleName] = {
        dependencies: dependencies,
        contains: {}
      };
    },
    get: function getModule (moduleName) {
      return globalModules[moduleName];
    },
    getInstance: function getInstance (moduleName) {
      var levels = moduleName.split('.');
      var ns = global;

      while (levels.length) {
        var name = levels.shift();
        if (!ns[name]) return null;
        ns = ns[name];
      }

      if (ns == global) return null;
      return ns;
    }
  };

  function modulePath (moduleName) {
    var levels = moduleName.split('.');
    var modules = [];
    for (var i = 0; i < levels.length; i++) {
      var m = levels[i];
      var last = modules[modules.length - 1];
      modules.push((last ? [last, m] : [m]).join('.'));
    }

    return modules;
  }

  function hash2array (hash) {
    var arr = [];
    for (var p in hash) {
      if (hash.hasOwnProperty(p) && hash[p]) {
        arr.push(p);
      }
    }
    return arr;
  }

  function checkReady (namespaces) {
    for (var i = 0, len = namespaces.length; i < len; i++) {
      var ns = globalModules.get(namespaces[i]), contains;
      if (!ns || !ns.created) {
        return false;
      } else if ((contains = hash2array(ns.contains)).length > 0){
        return checkReady(contains);
      }
    }
    return true;
  }

  global.use = function (namespaces, callback) {

    var interval = setTimeout(function checkModuleReady() {
      var namespaceObjs = [];
      if (!checkReady(namespaces)) {
        interval = setTimeout(checkModuleReady, 0);
      } else {
        clearInterval(interval);
        for (var i = 0; i < namespaces.length; i++) {
          namespaceObjs.push(globalModules.getInstance(namespaces[i]));
        }
        callback && callback.apply(global, namespaceObjs);
      }
    }, 0);
  };

  global.define = function (moduleName, dependencies, callback) {
    globalModules.set(moduleName, dependencies);

    var levels = moduleName.split('.');
    var ns = global, container, mname;

    while (levels.length) {
      mname = levels.shift();
      ns[mname] = ns[mname] || {};
      ns = ns[mname];

      if (levels.length == 1) {
        container = ns;
      }
    }

    global.use(dependencies, function() {
      var params = [].slice.call(arguments);
      var cb = function (module) {
        container[mname] = module;
        globalModules[moduleName].created = true;
      };
      params.unshift(ns);
      params.push(cb);
      var ret = callback.apply(ns, params);

      if (ret || hash2array(ns).length > 0) {
        if (ret) {
          container[mname] = ret;
        }
        globalModules[moduleName].created = true;
      }
    });

  };
})(this);
<commit_msg>fix bug when exports empty string<commit_after>(function(global) {

  var globalModules = {
    set: function setModule (moduleName, dependencies) {
      var parentModulePath = modulePath(moduleName).slice(0, -1);

      for (var i = 0; i < parentModulePath.length; i++) {
        var p = parentModulePath[i];
        if (!globalModules[p]) {
          globalModules.set(p, []);
          globalModules.get(p).created = true;
        }
        globalModules.get(p).contains[moduleName] = true;
      }

      globalModules[moduleName] = {
        dependencies: dependencies,
        contains: {}
      };
    },
    get: function getModule (moduleName) {
      return globalModules[moduleName];
    },
    getInstance: function getInstance (moduleName) {
      var levels = moduleName.split('.');
      var ns = global;

      while (levels.length) {
        var name = levels.shift();
        if (!ns[name]) return null;
        ns = ns[name];
      }

      if (ns == global) return null;
      return ns;
    }
  };

  function modulePath (moduleName) {
    var levels = moduleName.split('.');
    var modules = [];
    for (var i = 0; i < levels.length; i++) {
      var m = levels[i];
      var last = modules[modules.length - 1];
      modules.push((last ? [last, m] : [m]).join('.'));
    }

    return modules;
  }

  function hash2array (hash) {
    var arr = [];
    for (var p in hash) {
      if (hash.hasOwnProperty(p) && hash[p] != undefined) {
        arr.push(p);
      }
    }
    return arr;
  }

  function checkReady (namespaces) {
    for (var i = 0, len = namespaces.length; i < len; i++) {
      var ns = globalModules.get(namespaces[i]), contains;
      if (!ns || !ns.created) {
        return false;
      } else if ((contains = hash2array(ns.contains)).length > 0){
        return checkReady(contains);
      }
    }
    return true;
  }

  global.use = function (namespaces, callback) {

    var interval = setTimeout(function checkModuleReady() {
      var namespaceObjs = [];
      if (!checkReady(namespaces)) {
        interval = setTimeout(checkModuleReady, 0);
      } else {
        clearInterval(interval);
        for (var i = 0; i < namespaces.length; i++) {
          namespaceObjs.push(globalModules.getInstance(namespaces[i]));
        }
        callback && callback.apply(global, namespaceObjs);
      }
    }, 0);
  };

  global.define = function (moduleName, dependencies, callback) {
    globalModules.set(moduleName, dependencies);

    var levels = moduleName.split('.');
    var ns = global, container, mname;

    while (levels.length) {
      mname = levels.shift();
      ns[mname] = ns[mname] || {};
      ns = ns[mname];

      if (levels.length == 1) {
        container = ns;
      }
    }

    global.use(dependencies, function() {
      var params = [].slice.call(arguments);
      var cb = function (module) {
        container[mname] = module;
        globalModules[moduleName].created = true;
      };
      params.unshift(ns);
      params.push(cb);
      var ret = callback.apply(ns, params);

      if (ret || hash2array(ns).length > 0) {
        if (ret) {
          container[mname] = ret;
        }
        globalModules[moduleName].created = true;
      }
    });

  };
})(this);
<|endoftext|>


<commit_before>import React from 'react'
import {
  Provider,
  Banner,
  Heading,
  Lead,
  Container,
  Flex,
  Box,
  Text,
  Subhead,
  Absolute,
  Link as A
} from 'rebass'
import theme, { colors, mx } from '../theme'
import { Head } from 'react-static'
import { withFormik } from 'formik'
import yup from 'yup'
import axios from 'axios'
import Nav from '../components/Nav'
import { Field, Submit } from '../components/Forms'
import Footer from '../components/Footer'

const Header = Box.extend.attrs({
  is: 'header',
  align: 'center',
  justify: 'center',
  direction: 'column',
  bg: 'primary',
  p: 3
})`text-align: center;`

const Base = Container.extend.attrs({
  is: 'form',
  py: 4,
  px: 3,
  maxWidth: 40 * 16
})`
  display: grid;
  grid-gap: 1rem;
  ${mx[1]} {
    grid-template-columns: repeat(2, 1fr);
    h2, .textarea { grid-column: 1 / -1; }
  }
`

const Subheading = Heading.extend.attrs({
  f: 4,
  mt: 2,
  mb: 0,
  color: 'primary'
})``

const next12Months = () => {
  const monthNames = [
    'January',
    'February',
    'March',
    'April',
    'May',
    'June',
    'July',
    'August',
    'September',
    'October',
    'November',
    'December'
  ]
  const genMonth = date => {
    const month = monthNames[date.getMonth()]
    const label = `${month} ${date.getFullYear()}`
    const iso = date.toISOString()
    return { label, iso }
  }
  const months = []
  const today = new Date()
  const asap = genMonth(today)
  asap.label = 'ASAP'
  months.push(asap)
  for (let i = 0; i < 12; i++) {
    today.setMonth(today.getMonth() + 1)
    months.push(genMonth(today))
  }
  return months
}

const statusMessage = status =>
  status
    ? {
        success: 'Submitted—you’re all set! 🎈',
        error: 'Something went wrong 😰'
      }[status]
    : 'Submit application 📝'
const InnerForm = ({
  values,
  errors,
  touched,
  handleChange,
  handleBlur,
  handleSubmit,
  isSubmitting,
  status
}) => (
  <Base onSubmit={handleSubmit}>
    <Subheading>About you</Subheading>
    <Field
      label="First name"
      name="first_name"
      p="Cat"
      onChange={handleChange}
      onBlur={handleBlur}
      value={values.first_name}
      error={touched.first_name && errors.first_name}
    />
    <Field
      label="Last name"
      name="last_name"
      value={values.last_name}
      p="Hackworth"
      onChange={handleChange}
      onBlur={handleBlur}
      error={touched.last_name && errors.last_name}
    />
    <Field
      label="Email"
      name="email"
      type="email"
      p="cat@hackclub.com"
      value={values.email}
      onChange={handleChange}
      onBlur={handleBlur}
      error={touched.email && errors.email}
    />
    <Field
      label="Phone number"
      name="phone"
      type="phone"
      p="(555) 555-5555"
      value={values.phone}
      onChange={handleChange}
    />
    <Field
      label="GitHub"
      name="github"
      p="cathackworth"
      value={values.github}
      onChange={handleChange}
      onBlur={handleBlur}
    />
    <Field
      label="Twitter"
      name="twitter"
      p="cathackworth"
      value={values.twitter}
      onChange={handleChange}
      onBlur={handleBlur}
    />
    <Field
      label="High school name"
      name="high_school"
      p="Hacking High School"
      value={values.high_school}
      onChange={handleChange}
      onBlur={handleBlur}
      error={touched.high_school && errors.high_school}
    />
    <Field
      label="When do you graduate?"
      name="graduate"
      type="select"
      value={values.graduate}
      onChange={handleChange}
      onBlur={handleBlur}
      error={touched.graduate && errors.graduate}
    >
      <option value="9010">Other</option>
      <option value="9001">2022</option>
      <option value="9002">2021</option>
      <option value="9003">2020</option>
      <option value="9004">2019</option>
      <option value="9005">2018</option>
      <option value="9006">2017</option>
      <option value="9007">2016</option>
      <option value="9009">Teacher</option>
      <option value="9008">Graduated</option>
    </Field>
    <Subheading>Your club</Subheading>
    <Field
      label="When do you want to start?"
      name="start"
      type="select"
      children={next12Months().map(({ iso, label }) => (
        <option value={iso} key={iso} children={label} />
      ))}
      value={values.start}
      onChange={handleChange}
      onBlur={handleBlur}
      error={touched.start && errors.start}
    />
    <Field
      label="How did you hear about us?"
      name="referer"
      type="text"
      value={values.referer}
      onChange={handleChange}
      onBlur={handleBlur}
      error={touched.referer && errors.referer}
    />
    <Field
      label="Please tell us about an interesting project, preferably outside of class, that you created or worked on."
      name="interesting_project"
      type="textarea"
      value={values.interesting_project}
      onChange={handleChange}
      onBlur={handleBlur}
      error={touched.interesting_project && errors.interesting_project}
    />
    <Field
      label={

          Please tell us about the time you most successfully hacked some
          (non-computer) system to your advantage. (
            See some kinds of responses we’re looking for.
          )

      }
      name="systems_hacked"
      type="textarea"
      value={values.systems_hacked}
      onChange={handleChange}
      onBlur={handleBlur}
      error={touched.systems_hacked && errors.systems_hacked}
    />
    <Field
      label="What steps have you taken so far in starting your club?"
      name="steps_taken"
      type="textarea"
      value={values.steps_taken}
      onChange={handleChange}
      onBlur={handleBlur}
      error={touched.steps_taken && errors.steps_taken}
    />
    <Submit
      disabled={isSubmitting}
      onClick={handleSubmit}
      value={statusMessage(status)}
    />
  </Base>
)

const r = 'required'
const ApplicationForm = withFormik({
  mapPropsToValues: ({ params }) => ({ ...params }),
  validationSchema: yup.object().shape({
    first_name: yup.string().required(r),
    last_name: yup.string().required(r),
    email: yup.string().email('invalid email address').required(r),
    high_school: yup.string().required(r),
    graduate: yup.string().required(r),
    referer: yup.string().required(r),
    interesting_project: yup.string().required(r),
    systems_hacked: yup.string().required(r),
    steps_taken: yup.string().required(r)
  }),
  handleSubmit: (data, { setSubmitting, setStatus }) => {
    console.log(data)
    axios
      .post('https://hackclub.com/v1/club_applications', data)
      .then(res => {
        console.log(res)
        setSubmitting(false)
        setStatus('success')
      })
      .catch(e => {
        console.error(e)
        setSubmitting(false)
        setStatus('error')
      })
  },
  displayName: 'ApplicationForm'
})(InnerForm)

const systems_hacked =
  'https://www.quora.com/When-have-you-most-successfully-hacked-a-non-computer-system-to-your-advantage'
export default () => (
  <Provider theme={theme}>

      <title>Sign up – Hack Club</title>

      <Heading is="h1" color="white" f={[5, 6]} mt={4}>
        Submit your application
      </Heading>

    <ApplicationForm />

  </Provider>
)
<commit_msg>Fix start select menu<commit_after>import React from 'react'
import {
  Provider,
  Banner,
  Heading,
  Lead,
  Container,
  Flex,
  Box,
  Text,
  Subhead,
  Absolute,
  Link as A
} from 'rebass'
import theme, { colors, mx } from '../theme'
import { Head } from 'react-static'
import { withFormik } from 'formik'
import yup from 'yup'
import axios from 'axios'
import Nav from '../components/Nav'
import { Field, Submit } from '../components/Forms'
import Footer from '../components/Footer'

const Header = Box.extend.attrs({
  is: 'header',
  align: 'center',
  justify: 'center',
  direction: 'column',
  bg: 'primary',
  p: 3
})`text-align: center;`

const Base = Container.extend.attrs({
  is: 'form',
  py: 4,
  px: 3,
  maxWidth: 40 * 16
})`
  display: grid;
  grid-gap: 1rem;
  ${mx[1]} {
    grid-template-columns: repeat(2, 1fr);
    h2, .textarea { grid-column: 1 / -1; }
  }
`

const Subheading = Heading.extend.attrs({
  f: 4,
  mt: 2,
  mb: 0,
  color: 'primary'
})``

const next12Months = () => {
  const monthNames = [
    'January',
    'February',
    'March',
    'April',
    'May',
    'June',
    'July',
    'August',
    'September',
    'October',
    'November',
    'December'
  ]
  const genMonth = date => {
    const month = monthNames[date.getMonth()]
    const label = `${month} ${date.getFullYear()}`
    const iso = date.toISOString()
    return { label, iso }
  }
  const months = []
  const today = new Date()
  const asap = genMonth(today)
  asap.label = 'ASAP'
  months.push(asap)
  for (let i = 0; i < 12; i++) {
    today.setMonth(today.getMonth() + 1)
    months.push(genMonth(today))
  }
  return months
}

const statusMessage = status =>
  status
    ? {
        success: 'Submitted—you’re all set! 🎈',
        error: 'Something went wrong 😰'
      }[status]
    : 'Submit application 📝'
const InnerForm = ({
  values,
  errors,
  touched,
  handleChange,
  handleBlur,
  handleSubmit,
  isSubmitting,
  status,
  months
}) => (
  <Base onSubmit={handleSubmit}>
    <Subheading>About you</Subheading>
    <Field
      label="First name"
      name="first_name"
      p="Cat"
      onChange={handleChange}
      onBlur={handleBlur}
      value={values.first_name}
      error={touched.first_name && errors.first_name}
    />
    <Field
      label="Last name"
      name="last_name"
      value={values.last_name}
      p="Hackworth"
      onChange={handleChange}
      onBlur={handleBlur}
      error={touched.last_name && errors.last_name}
    />
    <Field
      label="Email"
      name="email"
      type="email"
      p="cat@hackclub.com"
      value={values.email}
      onChange={handleChange}
      onBlur={handleBlur}
      error={touched.email && errors.email}
    />
    <Field
      label="Phone number"
      name="phone"
      type="phone"
      p="(555) 555-5555"
      value={values.phone}
      onChange={handleChange}
    />
    <Field
      label="GitHub"
      name="github"
      p="cathackworth"
      value={values.github}
      onChange={handleChange}
      onBlur={handleBlur}
    />
    <Field
      label="Twitter"
      name="twitter"
      p="cathackworth"
      value={values.twitter}
      onChange={handleChange}
      onBlur={handleBlur}
    />
    <Field
      label="High school name"
      name="high_school"
      p="Hacking High School"
      value={values.high_school}
      onChange={handleChange}
      onBlur={handleBlur}
      error={touched.high_school && errors.high_school}
    />
    <Field
      label="When do you graduate?"
      name="graduate"
      type="select"
      value={values.graduate}
      onChange={handleChange}
      onBlur={handleBlur}
      error={touched.graduate && errors.graduate}
    >
      <option value="9010">Other</option>
      <option value="9001">2022</option>
      <option value="9002">2021</option>
      <option value="9003">2020</option>
      <option value="9004">2019</option>
      <option value="9005">2018</option>
      <option value="9006">2017</option>
      <option value="9007">2016</option>
      <option value="9009">Teacher</option>
      <option value="9008">Graduated</option>
    </Field>
    <Subheading>Your club</Subheading>
    <Field
      label="When do you want to start?"
      name="start"
      type="select"
      value={values.start}
      onChange={handleChange}
      onBlur={handleBlur}
      error={touched.start && errors.start}
    >
      {months.map(({ iso, label }, i) => (
        <option value={iso} key={`start-${i}`} children={label} />
      ))}
    </Field>
    <Field
      label="How did you hear about us?"
      name="referer"
      type="text"
      value={values.referer}
      onChange={handleChange}
      onBlur={handleBlur}
      error={touched.referer && errors.referer}
    />
    <Field
      label="Please tell us about an interesting project, preferably outside of class, that you created or worked on."
      name="interesting_project"
      type="textarea"
      value={values.interesting_project}
      onChange={handleChange}
      onBlur={handleBlur}
      error={touched.interesting_project && errors.interesting_project}
    />
    <Field
      label={

          Please tell us about the time you most successfully hacked some
          (non-computer) system to your advantage. (
            See some kinds of responses we’re looking for.
          )

      }
      name="systems_hacked"
      type="textarea"
      value={values.systems_hacked}
      onChange={handleChange}
      onBlur={handleBlur}
      error={touched.systems_hacked && errors.systems_hacked}
    />
    <Field
      label="What steps have you taken so far in starting your club?"
      name="steps_taken"
      type="textarea"
      value={values.steps_taken}
      onChange={handleChange}
      onBlur={handleBlur}
      error={touched.steps_taken && errors.steps_taken}
    />
    <Submit
      disabled={isSubmitting}
      onClick={handleSubmit}
      value={statusMessage(status)}
    />
  </Base>
)

const r = 'required'
const ApplicationForm = withFormik({
  mapPropsToValues: ({ params }) => ({ ...params }),
  validationSchema: yup.object().shape({
    first_name: yup.string().required(r),
    last_name: yup.string().required(r),
    email: yup.string().email('invalid email address').required(r),
    high_school: yup.string().required(r),
    graduate: yup.string().required(r),
    referer: yup.string().required(r),
    interesting_project: yup.string().required(r),
    systems_hacked: yup.string().required(r),
    steps_taken: yup.string().required(r)
  }),
  handleSubmit: (data, { setSubmitting, setStatus }) => {
    console.log(data)
    axios
      .post('https://hackclub.com/v1/club_applications', data)
      .then(res => {
        console.log(res)
        setSubmitting(false)
        setStatus('success')
      })
      .catch(e => {
        console.error(e)
        setSubmitting(false)
        setStatus('error')
      })
  },
  displayName: 'ApplicationForm'
})(InnerForm)

const systems_hacked =
  'https://www.quora.com/When-have-you-most-successfully-hacked-a-non-computer-system-to-your-advantage'
export default () => (
  <Provider theme={theme}>

      <title>Sign up – Hack Club</title>

      <Heading is="h1" color="white" f={[5, 6]} mt={4}>
        Submit your application
      </Heading>

    <ApplicationForm months={next12Months()} />

  </Provider>
)
<|endoftext|>


<commit_before><commit_msg>update tests<commit_after>'use strict';

const test = require('tape');
const sinon = require('sinon');

const Connection = require('../lib/connection');

const NOOP = () => { };

test('Connection has DEFAULTS exposed', (t) => {
    t.ok(Connection.DEFAULTS);
    t.end();
});
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import PropTypes from 'prop-types'

export default class LayerInteractions extends Component {
  static propTypes = {
    defaultMarkerId: PropTypes.string,
    activeMarkerId: PropTypes.string,
    children: PropTypes.node
  }

  static contextTypes = {
    map: PropTypes.object
  }

  componentDidMount() {
    const { map } = this.context
    const { defaultMarkerId, activeMarkerId } = this.props

    map.on('click', defaultMarkerId, (e) => {
      map.flyTo({
        center: [
          e.lngLat.lng,
          e.lngLat.lat
        ]
      })

      map.setFilter(activeMarkerId, ['==', 'title', e.features[0].properties.title])
    })
  }

  render() {
    return null;
  }
}
<commit_msg>implement move to and filter function<commit_after>import React, { Component } from 'react'
import PropTypes from 'prop-types'

export default class LayerInteractions extends Component {
  constructor(props, context) {
    super(props, context)

    this.moveToAndFilterMarker = this.moveToAndFilterMarker.bind(this)
  }

  static propTypes = {
    defaultMarkerId: PropTypes.string,
    activeMarkerId: PropTypes.string,
    children: PropTypes.node
  }

  static contextTypes = {
    map: PropTypes.object
  }

  componentDidMount() {
    const { map } = this.context
    const { defaultMarkerId } = this.props

    map.on('click', defaultMarkerId, this.moveToAndFilterMarker)
  }

  moveToAndFilterMarker(event) {
    const { map } = this.context
    const { activeMarkerId } = this.props

    map.flyTo({
      center: [
        event.lngLat.lng,
        event.lngLat.lat
      ]
    })

    map.setFilter(activeMarkerId, ['==', 'title', event.features[0].properties.title])
  }

  render() {
    return null;
  }
}
<|endoftext|>


<commit_before>'use strict';
var n = require('numeric');
module.exports = {
    defaultLambda: 0.7,

    /**
     * Compute local paricipant set ROI error (objective)
     * @note See [Eqn 6]
     * @param  {array}  w      ?iterative regressor?
     * @param  {array}  X      2D array where rows ~subjects, cols ~ROIs, cells ~ subject-ROI volumes
     * @param  {array}  y      response
     * @param  {number} lambda
     * @return {number}
     */
    objective: function(w, X, y, lambda) {
        lambda = lambda || this.defaultLambda;
        return n.sum(n.pow(n.sub(y, n.dot(X, w)), 2)) + (lambda * n.dot(w, w) / 2);
    },

    /**
     * Compute the local gradient of the object function
     * @note See [Eqn 9]
     * @param  {array}  w      ?iterative regressor?
     * @param  {array}  X      2D array where rows ~subjects, cols ~ROIs, cells ~ subject-ROI volumes
     * @param  {array}  y      response
     * @param  {number} lambda
     * @return {array}
     */
    gradient: function(w, X, y, lambda) {
        lambda = lambda || this.defaultLambda;
        return n.add(
            n.mul(
                -2,
                n.dot(
                    n.rep([X.length], 1),
                    n.mul(n.transpose(n.rep([X[0].length], n.sub(y, n.dot(X, w)))), X)
                )
            ),
            n.mul(lambda, w)
        );
    },

    /**
     * Simple multi-client response aggregator
     * @param  {array} W set of minimized regressors
     * @return {array}
     */
    aggregrateAvg: function(W) {
        var result = n.dot(
            n.rep([W.length], 1),
            W
        );
        return n.div(result, W.length);
    }

};
<commit_msg>aggregrate => aggregate<commit_after>'use strict';
var n = require('numeric');
module.exports = {
    defaultLambda: 0.7,

    /**
     * Compute local paricipant set ROI error (objective)
     * @note See [Eqn 6]
     * @param  {array}  w      ?iterative regressor?
     * @param  {array}  X      2D array where rows ~subjects, cols ~ROIs, cells ~ subject-ROI volumes
     * @param  {array}  y      response
     * @param  {number} lambda
     * @return {number}
     */
    objective: function(w, X, y, lambda) {
        lambda = lambda || this.defaultLambda;
        return n.sum(n.pow(n.sub(y, n.dot(X, w)), 2)) + (lambda * n.dot(w, w) / 2);
    },

    /**
     * Compute the local gradient of the object function
     * @note See [Eqn 9]
     * @param  {array}  w      ?iterative regressor?
     * @param  {array}  X      2D array where rows ~subjects, cols ~ROIs, cells ~ subject-ROI volumes
     * @param  {array}  y      response
     * @param  {number} lambda
     * @return {array}
     */
    gradient: function(w, X, y, lambda) {
        lambda = lambda || this.defaultLambda;
        return n.add(
            n.mul(
                -2,
                n.dot(
                    n.rep([X.length], 1),
                    n.mul(n.transpose(n.rep([X[0].length], n.sub(y, n.dot(X, w)))), X)
                )
            ),
            n.mul(lambda, w)
        );
    },

    /**
     * Simple multi-client response aggregator
     * @param  {array} W set of minimized regressors
     * @return {array}
     */
    aggregateAvg: function(W) {
        var result = n.dot(
            n.rep([W.length], 1),
            W
        );
        return n.div(result, W.length);
    }

};
<|endoftext|>


<commit_before>"use strict";

angular.module('arethusa.core').constant('LOCALES', [
  'en',
  'de',
  'fr'
]);
<commit_msg>Add comment about future locales<commit_after>"use strict";

// This constant is used to grant access to different localizations
// of the Arethusa interface.
//
// We plan to at least support the following in the future:
//
//    de
//    en
//    es
//    fa
//    fr
//    hr
//    it
//    pt
//
angular.module('arethusa.core').constant('LOCALES', [
  'en',
  'de',
  'fr'
]);
<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict';

// 3rd party deps
const argv = require('yargs').argv;
const diff = require('jiff').diff;
const fs = require('fs-extra');
const ncu = require('npm-check-updates');
const path = require('path');

const semverDiff = require('semver-diff');

// Static config
const pkgJson = path.join(process.cwd(), 'package.json');

// Default ncu config
var ncuConfig = {
    packageFile: pkgJson,
    jsonAll: true
};

// CLI params
if (argv.b || argv.bower) {
    ncuConfig.packageManager = "bower"
}

function compare(oldJson, newJson) {
    var pkgPatch = diff(oldJson, newJson);

    var pkgReport = {};

    for (var i = 0; i < pkgPatch.length; i++) {
        var from = pkgPatch[i];
        var to = pkgPatch[++i];

        pkgReport[from.path] = {
            from: from.value,
            to: to.value,
            status: semverDiff(from.value, to.value)
        }
    }

    return pkgReport;
}

function report(oldJson, newJson) {
    return new Promise(function (resolve) {
        if (oldJson && newJson) {
            resolve(compare(oldJson, newJson))
        }

        ncu
            .run(ncuConfig)
            .then(function (upgraded) {

                var currentPackage = fs.readJsonSync(pkgJson);

                resolve(compare(currentPackage, upgraded));
            });
    });

}

module.exports = {
    report: report
}<commit_msg>Code grooming<commit_after>#!/usr/bin/env node
'use strict';

// 3rd party deps
const argv = require('yargs').argv;
const diff = require('jiff').diff;
const fs = require('fs-extra');
const ncu = require('npm-check-updates');
const path = require('path');

const semverDiff = require('semver-diff');

// Static config
const pkgJson = path.join(process.cwd(), 'package.json');

// Default ncu config
var ncuConfig = {
    packageFile: pkgJson,
    jsonAll: true
};

// CLI params
if (argv.b || argv.bower) {
    ncuConfig.packageManager = "bower"
}

function compare(oldJson, newJson) {
    var pkgPatch = diff(oldJson, newJson);

    var pkgReport = {};

    for (var i = 0; i < pkgPatch.length; i++) {
        var from = pkgPatch[i];
        var to = pkgPatch[++i];

        pkgReport[from.path] = {
            from: from.value,
            to: to.value,
            status: semverDiff(from.value, to.value)
        }
    }

    return pkgReport;
}

function report(oldJson, newJson) {
    return new Promise(function (resolve) {
        if (oldJson && newJson) {
            resolve(compare(oldJson, newJson))
        }

        ncu
            .run(ncuConfig)
            .then(function (upgraded) {

                var currentPackage = fs.readJsonSync(pkgJson);

                resolve(compare(currentPackage, upgraded));
            });
    });
}

module.exports = {
    report: report
};
<|endoftext|>


<commit_before>
import getWindow from 'get-window'
import isBackward from 'selection-is-backward'
import { IS_SAFARI } from '../constants/environment'

/**
 * CSS overflow values that would cause scrolling.
 *
 * @type {Array}
 */

const OVERFLOWS = [
  'auto',
  'overlay',
  'scroll',
]

/**
 * Find the nearest parent with scrolling, or window.
 *
 * @param {el} Element
 */

function findScrollContainer(el, window) {
  let parent = el.parentNode
  let scroller

  while (!scroller) {
    if (!parent.parentNode) break

    const style = window.getComputedStyle(parent)
    const { overflowY } = style

    if (OVERFLOWS.includes(overflowY)) {
      scroller = parent
      break
    }

    parent = parent.parentNode
  }

  // COMPAT: Because Chrome does not allow doucment.body.scrollTop, we're
  // assuming that window.scrollTo() should be used if the scrollable element
  // turns out to be document.body or document.documentElement. This will work
  // unless body is intentionally set to scrollable by restricting its height
  // (e.g. height: 100vh).
  if (!scroller) {
    return window.document.body
  }

  return scroller
}

/**
 * Scroll the current selection's focus point into view if needed.
 *
 * @param {Selection} selection
 */

function scrollToSelection(selection) {
  if (!selection.anchorNode) return

  const window = getWindow(selection.anchorNode)
  const scroller = findScrollContainer(selection.anchorNode, window)
  const isWindow = scroller == window.document.body || scroller == window.document.documentElement
  const backward = isBackward(selection)

  const range = selection.getRangeAt(0)
  let selectionRect = range.getBoundingClientRect()

  // COMPAT: range.getBoundingClientRect() returns 0s in Safari when range is
  // collapsed. Expanding the range by 1 is a relatively effective workaround
  // for vertical scroll, although horizontal may be off by 1 character.
  // https://bugs.webkit.org/show_bug.cgi?id=138949
  // https://bugs.chromium.org/p/chromium/issues/detail?id=435438
  if (IS_SAFARI) {
    if (range.collapsed && selectionRect.top == 0 && selectionRect.height == 0) {
      if (range.startOffset == 0) {
        range.setEnd(range.endContainer, 1)
      } else {
        range.setStart(range.startContainer, range.startOffset - 1)
      }

      selectionRect = range.getBoundingClientRect()

      if (selectionRect.top == 0 && selectionRect.height == 0) {
        if (range.getClientRects().length) {
          selectionRect = range.getClientRects()[0]
        }
      }
    }
  }

  let width
  let height
  let yOffset
  let xOffset
  let scrollerTop = 0
  let scrollerLeft = 0
  let scrollerBordersY = 0
  let scrollerBordersX = 0

  if (isWindow) {
    const { innerWidth, innerHeight, pageYOffset, pageXOffset } = window
    width = innerWidth
    height = innerHeight
    yOffset = pageYOffset
    xOffset = pageXOffset
  } else {
    const { offsetWidth, offsetHeight, scrollTop, scrollLeft } = scroller
    const {
      borderTopWidth,
      borderBottomWidth,
      borderLeftWidth,
      borderRightWidth,
    } = window.getComputedStyle(scroller)

    const scrollerRect = scroller.getBoundingClientRect()
    width = offsetWidth
    height = offsetHeight
    scrollerTop = scrollerRect.top + parseInt(borderTopWidth, 10)
    scrollerLeft = scrollerRect.left + parseInt(borderLeftWidth, 10)
    scrollerBordersY = parseInt(borderTopWidth, 10) + parseInt(borderBottomWidth, 10)
    scrollerBordersX = parseInt(borderLeftWidth, 10) + parseInt(borderRightWidth, 10)
    yOffset = scrollTop
    xOffset = scrollLeft
  }

  const selectionFocusTop = backward ? selectionRect.top : selectionRect.bottom
  const selectionTop = selectionFocusTop + yOffset - scrollerTop

  const selectionFocusLeft = backward ? selectionRect.left : selectionRect.right
  const selectionLeft = selectionFocusLeft + xOffset - scrollerLeft

  let x = xOffset
  let y = yOffset

  if (selectionLeft < xOffset) {
    // selection to the left of viewport
    x = selectionLeft
  } else if (selectionLeft + selectionRect.width + scrollerBordersX > xOffset + width) {
    // selection to the right of viewport
    x = selectionLeft + scrollerBordersX - width
  }

  if (selectionTop < yOffset) {
    // selection above viewport
    y = selectionTop
  } else if (selectionTop + selectionRect.height + scrollerBordersY > yOffset + height) {
    // selection below viewport
    y = selectionTop + scrollerBordersY + selectionRect.height - height
  }

  if (isWindow) {
    window.scrollTo(x, y)
  } else {
    scroller.scrollTop = y
    scroller.scrollLeft = x
  }
}

/**
 * Export.
 *
 * @type {Function}
 */

export default scrollToSelection
<commit_msg>fix: account for container padding in scrollToSelection (#1462)<commit_after>
import getWindow from 'get-window'
import isBackward from 'selection-is-backward'
import { IS_SAFARI } from '../constants/environment'

/**
 * CSS overflow values that would cause scrolling.
 *
 * @type {Array}
 */

const OVERFLOWS = [
  'auto',
  'overlay',
  'scroll',
]

/**
 * Find the nearest parent with scrolling, or window.
 *
 * @param {el} Element
 */

function findScrollContainer(el, window) {
  let parent = el.parentNode
  let scroller

  while (!scroller) {
    if (!parent.parentNode) break

    const style = window.getComputedStyle(parent)
    const { overflowY } = style

    if (OVERFLOWS.includes(overflowY)) {
      scroller = parent
      break
    }

    parent = parent.parentNode
  }

  // COMPAT: Because Chrome does not allow doucment.body.scrollTop, we're
  // assuming that window.scrollTo() should be used if the scrollable element
  // turns out to be document.body or document.documentElement. This will work
  // unless body is intentionally set to scrollable by restricting its height
  // (e.g. height: 100vh).
  if (!scroller) {
    return window.document.body
  }

  return scroller
}

/**
 * Scroll the current selection's focus point into view if needed.
 *
 * @param {Selection} selection
 */

function scrollToSelection(selection) {
  if (!selection.anchorNode) return

  const window = getWindow(selection.anchorNode)
  const scroller = findScrollContainer(selection.anchorNode, window)
  const isWindow = scroller == window.document.body || scroller == window.document.documentElement
  const backward = isBackward(selection)

  const range = selection.getRangeAt(0).cloneRange()
  range.collapse(backward)
  let cursorRect = range.getBoundingClientRect()

  // COMPAT: range.getBoundingClientRect() returns 0s in Safari when range is
  // collapsed. Expanding the range by 1 is a relatively effective workaround
  // for vertical scroll, although horizontal may be off by 1 character.
  // https://bugs.webkit.org/show_bug.cgi?id=138949
  // https://bugs.chromium.org/p/chromium/issues/detail?id=435438
  if (IS_SAFARI) {
    if (range.collapsed && cursorRect.top == 0 && cursorRect.height == 0) {
      if (range.startOffset == 0) {
        range.setEnd(range.endContainer, 1)
      } else {
        range.setStart(range.startContainer, range.startOffset - 1)
      }

      cursorRect = range.getBoundingClientRect()

      if (cursorRect.top == 0 && cursorRect.height == 0) {
        if (range.getClientRects().length) {
          cursorRect = range.getClientRects()[0]
        }
      }
    }
  }

  let width
  let height
  let yOffset
  let xOffset
  let scrollerTop = 0
  let scrollerLeft = 0
  let scrollerBordersY = 0
  let scrollerBordersX = 0
  let scrollerPaddingTop = 0
  let scrollerPaddingBottom = 0
  let scrollerPaddingLeft = 0
  let scrollerPaddingRight = 0

  if (isWindow) {
    const { innerWidth, innerHeight, pageYOffset, pageXOffset } = window
    width = innerWidth
    height = innerHeight
    yOffset = pageYOffset
    xOffset = pageXOffset
  } else {
    const { offsetWidth, offsetHeight, scrollTop, scrollLeft } = scroller
    const {
      borderTopWidth,
      borderBottomWidth,
      borderLeftWidth,
      borderRightWidth,
      paddingTop,
      paddingBottom,
      paddingLeft,
      paddingRight,
    } = window.getComputedStyle(scroller)

    const scrollerRect = scroller.getBoundingClientRect()
    width = offsetWidth
    height = offsetHeight
    scrollerTop = scrollerRect.top + parseInt(borderTopWidth, 10)
    scrollerLeft = scrollerRect.left + parseInt(borderLeftWidth, 10)
    scrollerBordersY = parseInt(borderTopWidth, 10) + parseInt(borderBottomWidth, 10)
    scrollerBordersX = parseInt(borderLeftWidth, 10) + parseInt(borderRightWidth, 10)
    scrollerPaddingTop = parseInt(paddingTop, 10)
    scrollerPaddingBottom = parseInt(paddingBottom, 10)
    scrollerPaddingLeft = parseInt(paddingLeft, 10)
    scrollerPaddingRight = parseInt(paddingRight, 10)
    yOffset = scrollTop
    xOffset = scrollLeft
  }

  const cursorTop = cursorRect.top + yOffset - scrollerTop
  const cursorLeft = cursorRect.left + xOffset - scrollerLeft

  let x = xOffset
  let y = yOffset

  if (cursorLeft < xOffset) {
    // selection to the left of viewport
    x = cursorLeft - scrollerPaddingLeft
  } else if (cursorLeft + cursorRect.width + scrollerBordersX > xOffset + width) {
    // selection to the right of viewport
    x = cursorLeft + scrollerBordersX + scrollerPaddingRight - width
  }

  if (cursorTop < yOffset) {
    // selection above viewport
    y = cursorTop - scrollerPaddingTop
  } else if (cursorTop + cursorRect.height + scrollerBordersY > yOffset + height) {
    // selection below viewport
    y = cursorTop + scrollerBordersY + scrollerPaddingBottom + cursorRect.height - height
  }

  if (isWindow) {
    window.scrollTo(x, y)
  } else {
    scroller.scrollTop = y
    scroller.scrollLeft = x
  }
}

/**
 * Export.
 *
 * @type {Function}
 */

export default scrollToSelection
<|endoftext|>