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

    var ModulationController = function(params) {

        if (!params)
            params = new Object();

        this.canvas = params.canvas || undefined;
        this.endCallback = params.endCallback || undefined;

        /* Are these needed? */
        this.saveState = false;

        this.isSending = false;
        this.playing = false;
        this.done = false;
        this.stoppedAt = 0;
        this.modData = null;
        this.byteArray = null;
        this.playCount = 0;

        this.PROT_VERSION = 0x01;   // Protocol v1.0

        this.CONTROL_PACKET = 0x01;
        this.DATA_PACKET = 0x02;

        this.modData = new modulator(this); // the modulator object contains our window's audio context

        /* Preamble sent before every audio packet */
        this.preamble = [0x00, 0x00, 0x00, 0x00, 0xaa, 0x55, 0x42];
    }

    ModulationController.prototype = {

        makeControlHeader: function() {
            return [this.PROT_VERSION, this.CONTROL_PACKET, 0x00, 0x00];
        },

        makeDataHeader: function(blockNum) {
            return [this.PROT_VERSION, this.DATA_PACKET, blockNum & 0xff, (blockNum >> 8) & 0xff];
        },

        sendData: function(data) {
            if (data) {
                var dataLength = data.length;
                var array = new Uint8Array(new ArrayBuffer(dataLength));
                for (i = 0; i < dataLength; i++)
                    array[i] = data.charCodeAt(i);

                this.byteArray = array;
                this.playCount = 0;
                this.transcodeFile(0);
                this.isSending = true;
            }
        },

        // this is the core function for transcoding
        // two object variables must be set:
        // byteArray, and playCount.
        // byteArray is the binary file to transmit
        // playCount keeps track of how many times the entire file has been replayed

        // the parameter to this, "index", is a packet counter. We have to recursively call
        // transcodeFile using callbacks triggered by the completion of audio playback. I couldn't
        // think of any other way to do it.
        transcodeFile: function(index) {
            var fileLen = this.byteArray.length;
            var blocks = Math.ceil(fileLen / 256);

            // index 0 & 1 create identical control packets. We transmit the control packet
            // twice in the beginning because (a) it's tiny and almost free and (b) if we
            // happen to miss it, we waste an entire playback cycle before we start committing
            // data to memory
            if (index == 0  || index == 1) {
                var ctlPacket = this.makeCtlPacket(this.byteArray.subarray(0, fileLen));

                this.modData.modulate(ctlPacket);
                this.modData.playLoop(this, index + 1);
                this.modData.drawWaveform(this.canvas);
            }
            else {
                // data index starts at 2, due to two sends of the control packet up front
                var i = index - 2;
                // handle whole blocks
                if (i < blocks - 1) {
                    var dataPacket = this.makeDataPacket(this.byteArray.subarray(i * 256, i * 256 + 256), i);
                    this.modData.modulate(dataPacket);
                    this.modData.playLoop(this, index + 1);
                    this.modData.drawWaveform(this.canvas);
                }
                else {
                    // handle last block of data, which may not be 256 bytes long
                    var dataPacket = this.makeDataPacket(this.byteArray.subarray(i * 256, fileLen), i);
                    this.modData.modulate(dataPacket);
                    this.modData.playLoop(this, index + 1);
                    this.modData.drawWaveform(this.canvas);
                }
            }
        },

        makeUint32: function(num) {
            return [num & 0xff,
                   (num >> 8) & 0xff,
                   (num >> 16) & 0xff,
                   (num >> 24) & 0xff];
        },

        makeUint16: function(num) {
            return [num & 0xff,
                   (num >> 8) & 0xff];
        },

        makePacket: function() {
            var len = 0;
            var i;
            for (i = 0; i < arguments.length; i++)
                len += arguments[i].length;

            var pkt = new Uint8Array(len);
            var offset = 0;

            for (i = 0; i < arguments.length; i++)
                offset += this.appendData(pkt, arguments[i], offset);

            return pkt;
        },

        makeCtlPacket: function(data) {
            // parameters from microcontroller spec. Probably a better way
            // to do this in javascript, but I don't know how (seems like "const" could be used, but not universal)
            var preamble = this.preamble;
            var header = this.makeControlHeader();
            var program_length = this.makeUint32(data.length);
            var program_hash = this.makeHash(data, 0x32d0babe);  // 0x32d0babe by convention
            var program_guid_str = SparkMD5.hash(String.fromCharCode.apply(null,data), false);
            var program_guid = [];
            var i;
            for (i = 0; i < program_guid_str.length-1; i += 2)
                program_guid.push(parseInt(program_guid_str.substr(i,2),16));

            var footer = this.makeFooter(header, program_length, program_hash, program_guid);
            var stop = [0xff];

            return this.makePacket(preamble, header, program_length, program_hash, program_guid, footer, stop);
        },

        /* Appends "src" to "dst", beginning at offset "offset".
         * Handy for populating data buffers.
         */
        appendData: function(dst, src, offset) {
            var i;
            for (i = 0; i < src.length; i++)
                dst[offset + i] = src[i];
            return i;
        },

        makeHash: function(data, hash) {
            return this.makeUint32(murmurhash3_32_gc(data, hash));
        },

        makeFooter: function(packet) {
            var hash = 0xdeadbeef;
            var data = new Array();
            var i;
            var j;

            // Join all argument arrays together into "data"
            for (i = 0; i < arguments.length; i++)
                for (j = 0; j < arguments[i].length; j++)
                    data.push(arguments[i][j]);

            return this.makeHash(data, hash);
        },

        makeDataPacket: function(dataIn, blocknum) {
            var data;
            var i;

            // now assemble the packet
            var preamble = this.preamble;
            var header = this.makeDataHeader(blocknum);

            // Ensure the "data" payload is 256 bytes long.
            var data = new Uint8Array(256);
            data.fill(0xff);    // Pad extra data with 0xff
            this.appendData(data, dataIn, 0);

            var footer = this.makeFooter(header, data);
            var stop = [0xff];

            // 256 byte payload, preamble, sector offset + 4 bytes hash + 1 byte stop
            var packetlen = preamble.length + header.length + data.length + footer.length + stop.length;

            // now stripe the buffer to ensure transitions for baud sync
            // don't stripe the premable or the hash
            for (i = 0; i < data.length; i++) {
                if ((i % 16) == 3)
                    data[i] ^= 0x55;
                else if ((i % 16) == 11)
                    data[i] ^= 0xaa;
            }

            return this.makePacket(preamble, header, data, footer, stop);
        },

        // once all audio is done playing, call this to reset UI elements to idle state
        audioEndCB: function() {
            this.isSending = false;
            if (this.endCallback)
                this.endCallback();
        },

        stop: function() {
            ;
        },

        isRunning: function() {
            return this.isSending;
        }
    }

    /* Set up the constructor, so we can do "new ModulationController()" */
    window.ModulationController = function(params) {
        return new ModulationController(params);
    };
}(this));

<commit_msg>modulate-controller: simplify packet gen driver<commit_after>(function (window) {
    'use strict';

    var ModulationController = function(params) {

        if (!params)
            params = new Object();

        this.canvas = params.canvas || undefined;
        this.endCallback = params.endCallback || undefined;

        /* Are these needed? */
        this.saveState = false;

        this.isSending = false;
        this.playing = false;
        this.done = false;
        this.stoppedAt = 0;
        this.modData = null;
        this.byteArray = null;
        this.playCount = 0;

        this.PROT_VERSION = 0x01;   // Protocol v1.0

        this.CONTROL_PACKET = 0x01;
        this.DATA_PACKET = 0x02;

        this.modData = new modulator(this); // the modulator object contains our window's audio context

        /* Preamble sent before every audio packet */
        this.preamble = [0x00, 0x00, 0x00, 0x00, 0xaa, 0x55, 0x42];
    }

    ModulationController.prototype = {

        makeControlHeader: function() {
            return [this.PROT_VERSION, this.CONTROL_PACKET, 0x00, 0x00];
        },

        makeDataHeader: function(blockNum) {
            return [this.PROT_VERSION, this.DATA_PACKET, blockNum & 0xff, (blockNum >> 8) & 0xff];
        },

        sendData: function(data) {
            if (data) {
                var dataLength = data.length;
                var array = new Uint8Array(new ArrayBuffer(dataLength));
                for (i = 0; i < dataLength; i++)
                    array[i] = data.charCodeAt(i);

                this.byteArray = array;
                this.playCount = 0;
                this.transcodeFile(0);
                this.isSending = true;
            }
        },

        // this is the core function for transcoding
        // two object variables must be set:
        // byteArray, and playCount.
        // byteArray is the binary file to transmit
        // playCount keeps track of how many times the entire file has been replayed

        // the parameter to this, "index", is a packet counter. We have to recursively call
        // transcodeFile using callbacks triggered by the completion of audio playback. I couldn't
        // think of any other way to do it.
        transcodeFile: function(index) {
            var fileLen = this.byteArray.length;
            var blocks = Math.ceil(fileLen / 256);
            var packet;

            // index 0 & 1 create identical control packets. We transmit the control packet
            // twice in the beginning because (a) it's tiny and almost free and (b) if we
            // happen to miss it, we waste an entire playback cycle before we start committing
            // data to memory
            if (index == 0  || index == 1) {
                packet = this.makeCtlPacket(this.byteArray.subarray(0, fileLen));
            }
            else {
                // data index starts at 2, due to two sends of the control packet up front
                var block = index - 2;
                var start = block * 256;
                var end = start + 256;
                if (end > fileLen)
                    end = fileLen;
                packet = this.makeDataPacket(this.byteArray.subarray(start, end), block);
            }

            this.modData.modulate(packet);
            this.modData.playLoop(this, index + 1);
            this.modData.drawWaveform(this.canvas);
        },

        makeUint32: function(num) {
            return [num & 0xff,
                   (num >> 8) & 0xff,
                   (num >> 16) & 0xff,
                   (num >> 24) & 0xff];
        },

        makeUint16: function(num) {
            return [num & 0xff,
                   (num >> 8) & 0xff];
        },

        makePacket: function() {
            var len = 0;
            var i;
            for (i = 0; i < arguments.length; i++)
                len += arguments[i].length;

            var pkt = new Uint8Array(len);
            var offset = 0;

            for (i = 0; i < arguments.length; i++)
                offset += this.appendData(pkt, arguments[i], offset);

            return pkt;
        },

        makeCtlPacket: function(data) {
            // parameters from microcontroller spec. Probably a better way
            // to do this in javascript, but I don't know how (seems like "const" could be used, but not universal)
            var preamble = this.preamble;
            var header = this.makeControlHeader();
            var program_length = this.makeUint32(data.length);
            var program_hash = this.makeHash(data, 0x32d0babe);  // 0x32d0babe by convention
            var program_guid_str = SparkMD5.hash(String.fromCharCode.apply(null,data), false);
            var program_guid = [];
            var i;
            for (i = 0; i < program_guid_str.length-1; i += 2)
                program_guid.push(parseInt(program_guid_str.substr(i,2),16));

            var footer = this.makeFooter(header, program_length, program_hash, program_guid);
            var stop = [0xff];

            return this.makePacket(preamble, header, program_length, program_hash, program_guid, footer, stop);
        },

        /* Appends "src" to "dst", beginning at offset "offset".
         * Handy for populating data buffers.
         */
        appendData: function(dst, src, offset) {
            var i;
            for (i = 0; i < src.length; i++)
                dst[offset + i] = src[i];
            return i;
        },

        makeHash: function(data, hash) {
            return this.makeUint32(murmurhash3_32_gc(data, hash));
        },

        makeFooter: function(packet) {
            var hash = 0xdeadbeef;
            var data = new Array();
            var i;
            var j;

            // Join all argument arrays together into "data"
            for (i = 0; i < arguments.length; i++)
                for (j = 0; j < arguments[i].length; j++)
                    data.push(arguments[i][j]);

            return this.makeHash(data, hash);
        },

        makeDataPacket: function(dataIn, blocknum) {
            var data;
            var i;

            // now assemble the packet
            var preamble = this.preamble;
            var header = this.makeDataHeader(blocknum);

            // Ensure the "data" payload is 256 bytes long.
            var data = new Uint8Array(256);
            data.fill(0xff);    // Pad extra data with 0xff
            this.appendData(data, dataIn, 0);

            var footer = this.makeFooter(header, data);
            var stop = [0xff];

            // 256 byte payload, preamble, sector offset + 4 bytes hash + 1 byte stop
            var packetlen = preamble.length + header.length + data.length + footer.length + stop.length;

            // now stripe the buffer to ensure transitions for baud sync
            // don't stripe the premable or the hash
            for (i = 0; i < data.length; i++) {
                if ((i % 16) == 3)
                    data[i] ^= 0x55;
                else if ((i % 16) == 11)
                    data[i] ^= 0xaa;
            }

            return this.makePacket(preamble, header, data, footer, stop);
        },

        // once all audio is done playing, call this to reset UI elements to idle state
        audioEndCB: function() {
            this.isSending = false;
            if (this.endCallback)
                this.endCallback();
        },

        stop: function() {
            ;
        },

        isRunning: function() {
            return this.isSending;
        }
    }

    /* Set up the constructor, so we can do "new ModulationController()" */
    window.ModulationController = function(params) {
        return new ModulationController(params);
    };
}(this));

<|endoftext|>


<commit_before>window.appHelpers = function () {

  function getEnv(domain) {

    let env;
    let lastDotSplit = this.splitByLastDot(domain);

    if (lastDotSplit.indexOf('/') > -1) {
      lastDotSplit = lastDotSplit.split('/')[0];
    }

    if (lastDotSplit === 'com' || lastDotSplit === 'org') {
      env = 'live';
    } else {
      env = 'test';
    }
    return env;
  }

  function splitByLastDot(text) {
    var index = text.lastIndexOf('.');
    return text.slice(index + 1);
  }

  return {
    getEnv,
    splitByLastDot
  };
}();
class SiteHeader extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      baseUrl: window.json_baseurl,
      cat_title: window.json_cat_title,
      hasIdentity: window.json_hasIdentity,
      is_show_title: window.json_is_show_title,
      redirectString: window.json_redirectString,
      serverUrl: window.json_serverUrl,
      serverUri: window.json_serverUri,
      store: {
        sName: window.json_sname,
        name: window.json_store_name,
        order: window.json_store_order,
        last_char_store_order: window.last_char_store_order
      },
      user: window.json_member,
      logo: window.json_logoWidth,
      cat_title_left: window.json_cat_title_left,
      tabs_left: window.tabs_left,
      template: window.json_template,
      status: ""
    };
    this.updateDimensions = this.updateDimensions.bind(this);
  }

  componentWillMount() {
    this.updateDimensions();
  }

  componentDidMount() {
    window.addEventListener("resize", this.updateDimensions);
    window.addEventListener("orientationchange", this.updateDimensions);
  }

  updateDimensions() {
    const width = window.innerWidth;
    let device;
    if (width >= 910) {
      device = "large";
    } else if (width < 910 && width >= 610) {
      device = "mid";
    } else if (width < 610) {
      device = "tablet";
    }
    this.setState({ device: device });
  }

  render() {

    let userMenuDisplay, loginMenuDisplay, siteHeaderTopRightCssClass;
    if (this.state.user) {
      userMenuDisplay = React.createElement(SiteHeaderUserMenu, {
        serverUrl: this.state.serverUrl,
        baseUrl: this.state.baseUrl,
        user: this.state.user
      });
      siteHeaderTopRightCssClass = "w-user";
    } else {
      loginMenuDisplay = React.createElement(SiteHeaderLoginMenu, {
        baseUrl: this.state.baseUrl,
        redirectString: this.state.redirectString,
        template: this.state.template
      });
    }

    let logoLink = this.state.serverUrl;
    if (this.state.serverUri.indexOf('/s/') > -1) {
      logoLink += "/s/" + this.state.store.name;
    }

    let siteHeaderStoreNameDisplay;
    if (this.state.is_show_title === "1") {
      siteHeaderStoreNameDisplay = React.createElement(
        "div",
        { id: "site-header-store-name-container" },
        React.createElement(
          "a",
          { href: logoLink },
          this.state.store.name
        )
      );
    }

    let HeaderDisplay;
    if (this.state.device !== "tablet") {
      HeaderDisplay = React.createElement(
        "section",
        { id: "site-header-wrapper", style: { "paddingLeft": this.state.template['header-logo']['width'] } },
        React.createElement(
          "div",
          { id: "siter-header-left" },
          React.createElement(
            "div",
            { id: "site-header-logo-container", style: this.state.template['header-logo'] },
            React.createElement(
              "a",
              { href: logoLink },
              React.createElement("img", { src: this.state.template['header-logo']['image-src'] })
            )
          ),
          siteHeaderStoreNameDisplay
        ),
        React.createElement(
          "div",
          { id: "site-header-right" },
          React.createElement(
            "div",
            { id: "site-header-right-top", className: siteHeaderTopRightCssClass },
            React.createElement(SiteHeaderSearchForm, {
              baseUrl: this.state.baseUrl
            }),
            userMenuDisplay
          ),
          React.createElement(
            "div",
            { id: "site-header-right-bottom" },
            loginMenuDisplay
          )
        )
      );
    } else {
      HeaderDisplay = React.createElement(MobileSiteHeader, {
        logoLink: logoLink,
        template: this.state.template,
        user: this.state.user,
        baseUrl: this.state.baseUrl,
        store: this.state.store,
        redirectString: this.state.redirectString
      });
    }

    return React.createElement(
      "section",
      { id: "site-header", style: this.state.template.header },
      HeaderDisplay
    );
  }
}

class SiteHeaderSearchForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      searchText: ''
    };
    this.onSearchTextChange = this.onSearchTextChange.bind(this);
    this.onSearchFormSubmit = this.onSearchFormSubmit.bind(this);
  }

  onSearchTextChange(e) {
    this.setState({ searchText: e.target.value });
  }

  onSearchFormSubmit(e) {
    e.preventDefault();
    window.location.href = this.props.baseUrl + "/search?projectSearchText=" + this.state.searchText;
  }

  render() {
    return React.createElement(
      "div",
      { id: "site-header-search-form" },
      React.createElement(
        "form",
        { id: "search-form", onSubmit: this.onSearchFormSubmit },
        React.createElement("input", { onChange: this.onSearchTextChange, value: this.state.searchText, type: "text", name: "projectSearchText" }),
        React.createElement("a", { onClick: this.onSearchFormSubmit })
      )
    );
  }
}

class SiteHeaderLoginMenu extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
  render() {

    let registerButtonCssClass, loginButtonCssClass;

    if (window.location.href.indexOf('/register') > -1) {
      registerButtonCssClass = "active";
    }

    if (window.location.href.indexOf('/login') > -1) {
      loginButtonCssClass = "active";
    }

    const menuItemCssClass = {
      "borderColor": this.props.template['header-nav-tabs']['border-color'],
      "backgroundColor": this.props.template['header-nav-tabs']['background-color']
    };

    return React.createElement(
      "div",
      { id: "site-header-login-menu" },
      React.createElement(
        "ul",
        null,
        React.createElement(
          "li",
          { style: menuItemCssClass, className: registerButtonCssClass },
          React.createElement(
            "a",
            { href: this.props.baseUrl + "/register" },
            "Register"
          )
        ),
        React.createElement(
          "li",
          { style: menuItemCssClass, className: loginButtonCssClass },
          React.createElement(
            "a",
            { href: this.props.baseUrl + "/login" + this.props.redirectString },
            "Login"
          )
        )
      )
    );
  }
}

class SiteHeaderUserMenu extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
    this.handleClick = this.handleClick.bind(this);
  }

  componentWillMount() {
    document.addEventListener('mousedown', this.handleClick, false);
  }

  componentWillUnmount() {
    document.removeEventListener('mousedown', this.handleClick, false);
  }

  handleClick(e) {
    let dropdownClass = "";
    if (this.node.contains(e.target)) {
      if (this.state.dropdownClass === "open") {
        if (e.target.className === "profile-menu-toggle" || e.target.className === "profile-menu-image" || e.target.className === "profile-menu-username") {
          dropdownClass = "";
        } else {
          dropdownClass = "open";
        }
      } else {
        dropdownClass = "open";
      }
    }
    this.setState({ dropdownClass: dropdownClass });
  }

  render() {

    return React.createElement(
      "ul",
      { id: "site-header-user-menu-container" },
      React.createElement(
        "li",
        { ref: node => this.node = node, id: "user-menu-toggle", className: this.state.dropdownClass },
        React.createElement(
          "a",
          { className: "profile-menu-toggle" },
          React.createElement("img", { className: "profile-menu-image", src: window.json_member_avatar }),
          React.createElement(
            "span",
            { className: "profile-menu-username" },
            this.props.user.username
          )
        ),
        React.createElement(
          "ul",
          { id: "user-profile-menu" },
          React.createElement("div", { className: "dropdown-header" }),
          React.createElement(
            "li",
            null,
            React.createElement(
              "a",
              { href: "/product/add" },
              "Add Product"
            )
          ),
          React.createElement(
            "li",
            null,
            React.createElement(
              "a",
              { href: this.props.baseUrl + "/u/" + this.props.user.username + "/products" },
              "Products"
            )
          ),
          React.createElement(
            "li",
            null,
            React.createElement(
              "a",
              { href: this.props.baseUrl + "/u/" + this.props.user.username + "/plings" },
              "Plings"
            )
          ),
          React.createElement(
            "li",
            null,
            React.createElement(
              "a",
              { href: "/settings" },
              "Settings"
            )
          ),
          React.createElement(
            "li",
            null,
            React.createElement(
              "a",
              { href: "/logout" },
              "Logout"
            )
          )
        )
      )
    );
  }
}

class MobileSiteHeader extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      status: "switch"
    };
    this.showMobileUserMenu = this.showMobileUserMenu.bind(this);
    this.showMobileSearchForm = this.showMobileSearchForm.bind(this);
    this.showMobileSwitchMenu = this.showMobileSwitchMenu.bind(this);
  }

  showMobileUserMenu() {
    this.setState({ status: "user" });
  }

  showMobileSearchForm() {
    this.setState({ status: "search" });
  }

  showMobileSwitchMenu() {
    this.setState({ status: "switch" });
  }

  render() {

    const menuItemCssClass = {
      "borderColor": this.props.template['header-nav-tabs']['border-color'],
      "backgroundColor": this.props.template['header-nav-tabs']['background-color']
    };

    const closeMenuElementDisplay = React.createElement(
      "a",
      { className: "menu-item", onClick: this.showMobileSwitchMenu },
      React.createElement("span", { className: "glyphicon glyphicon-remove" })
    );

    let mobileMenuDisplay;
    if (this.state.status === "switch") {
      mobileMenuDisplay = React.createElement(
        "div",
        { id: "switch-menu" },
        React.createElement(
          "a",
          { className: "menu-item", onClick: this.showMobileSearchForm, id: "user-menu-switch" },
          React.createElement("span", { className: "glyphicon glyphicon-search" })
        ),
        React.createElement(
          "a",
          { className: "menu-item", onClick: this.showMobileUserMenu, id: "search-menu-switch" },
          React.createElement("span", { className: "glyphicon glyphicon-option-horizontal" })
        )
      );
    } else if (this.state.status === "user") {
      mobileMenuDisplay = React.createElement(
        "div",
        { id: "mobile-user-menu" },
        React.createElement(
          "div",
          { className: "menu-content-wrapper" },
          React.createElement(MobileUserContainer, {
            user: this.props.user,
            baseUrl: this.props.baseUrl,
            template: this.props.template,
            redirectString: this.props.redirectString
          })
        ),
        closeMenuElementDisplay
      );
    } else if (this.state.status === "search") {
      mobileMenuDisplay = React.createElement(
        "div",
        { id: "mobile-search-menu" },
        React.createElement(
          "div",
          { className: "menu-content-wrapper" },
          React.createElement(SiteHeaderSearchForm, {
            baseUrl: this.props.baseUrl
          })
        ),
        closeMenuElementDisplay
      );
    }

    let logoElementCssClass = this.props.store.name;
    if (this.state.status !== "switch") {
      logoElementCssClass += " mini-version";
    }

    return React.createElement(
      "section",
      { id: "mobile-site-header" },
      React.createElement(
        "div",
        { id: "mobile-site-header-logo", className: logoElementCssClass },
        React.createElement(
          "a",
          { href: this.props.logoLink },
          React.createElement("img", { src: this.props.template['header-logo']['image-src'] })
        )
      ),
      React.createElement(
        "div",
        { id: "mobile-site-header-menus-container" },
        mobileMenuDisplay
      )
    );
  }
}

class MobileUserContainer extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  render() {

    let userDisplay;
    if (this.props.user) {
      userDisplay = React.createElement(SiteHeaderUserMenu, {
        user: this.props.user
      });
    } else {
      userDisplay = React.createElement(SiteHeaderLoginMenu, {
        baseUrl: this.props.baseUrl,
        template: this.props.template,
        redirectString: this.props.redirectString
      });
    }

    return React.createElement(
      "div",
      { id: "mobile-user-container" },
      userDisplay
    );
  }
}

ReactDOM.render(React.createElement(SiteHeader, null), document.getElementById('site-header-container'));
<commit_msg>login<commit_after>window.appHelpers = function () {

  function getEnv(domain) {

    let env;
    let lastDotSplit = this.splitByLastDot(domain);

    if (lastDotSplit.indexOf('/') > -1) {
      lastDotSplit = lastDotSplit.split('/')[0];
    }

    if (lastDotSplit === 'com' || lastDotSplit === 'org') {
      env = 'live';
    } else {
      env = 'test';
    }
    return env;
  }

  function splitByLastDot(text) {
    var index = text.lastIndexOf('.');
    return text.slice(index + 1);
  }

  return {
    getEnv,
    splitByLastDot
  };
}();
class SiteHeader extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      baseUrl: window.json_baseurl,
      cat_title: window.json_cat_title,
      hasIdentity: window.json_hasIdentity,
      is_show_title: window.json_is_show_title,
      redirectString: window.json_redirectString,
      serverUrl: window.json_serverUrl,
      serverUri: window.json_serverUri,
      store: {
        sName: window.json_sname,
        name: window.json_store_name,
        order: window.json_store_order,
        last_char_store_order: window.last_char_store_order
      },
      user: window.json_member,
      logo: window.json_logoWidth,
      cat_title_left: window.json_cat_title_left,
      tabs_left: window.tabs_left,
      template: window.json_template,
      status: ""
    };
    this.updateDimensions = this.updateDimensions.bind(this);
  }

  componentWillMount() {
    this.updateDimensions();
  }

  componentDidMount() {
    window.addEventListener("resize", this.updateDimensions);
    window.addEventListener("orientationchange", this.updateDimensions);
  }

  updateDimensions() {
    const width = window.innerWidth;
    let device;
    if (width >= 910) {
      device = "large";
    } else if (width < 910 && width >= 610) {
      device = "mid";
    } else if (width < 610) {
      device = "tablet";
    }
    this.setState({ device: device });
  }

  render() {

    let userMenuDisplay, loginMenuDisplay, siteHeaderTopRightCssClass;
    if (this.state.user) {
      userMenuDisplay = React.createElement(SiteHeaderUserMenu, {
        serverUrl: this.state.serverUrl,
        baseUrl: this.state.baseUrl,
        user: this.state.user
      });
      siteHeaderTopRightCssClass = "w-user";
    } else {
      loginMenuDisplay = React.createElement(SiteHeaderLoginMenu, {
        baseUrl: this.state.baseUrl,
        redirectString: this.state.redirectString,
        template: this.state.template
      });
    }

    let logoLink = this.state.serverUrl;
    if (this.state.serverUri.indexOf('/s/') > -1) {
      logoLink += "/s/" + this.state.store.name;
    }

    let siteHeaderStoreNameDisplay;
    if (this.state.is_show_title === "1") {
      siteHeaderStoreNameDisplay = React.createElement(
        "div",
        { id: "site-header-store-name-container" },
        React.createElement(
          "a",
          { href: logoLink },
          this.state.store.name
        )
      );
    }

    let HeaderDisplay;
    if (this.state.device !== "tablet") {
      HeaderDisplay = React.createElement(
        "section",
        { id: "site-header-wrapper", style: { "paddingLeft": this.state.template['header-logo']['width'] } },
        React.createElement(
          "div",
          { id: "siter-header-left" },
          React.createElement(
            "div",
            { id: "site-header-logo-container", style: this.state.template['header-logo'] },
            React.createElement(
              "a",
              { href: logoLink },
              React.createElement("img", { src: this.state.template['header-logo']['image-src'] })
            )
          ),
          siteHeaderStoreNameDisplay
        ),
        React.createElement(
          "div",
          { id: "site-header-right" },
          React.createElement(
            "div",
            { id: "site-header-right-top", className: siteHeaderTopRightCssClass },
            React.createElement(SiteHeaderSearchForm, {
              baseUrl: this.state.baseUrl
            }),
            userMenuDisplay
          ),
          React.createElement(
            "div",
            { id: "site-header-right-bottom" },
            loginMenuDisplay
          )
        )
      );
    } else {
      HeaderDisplay = React.createElement(MobileSiteHeader, {
        logoLink: logoLink,
        template: this.state.template,
        user: this.state.user,
        baseUrl: this.state.baseUrl,
        store: this.state.store,
        redirectString: this.state.redirectString
      });
    }

    return React.createElement(
      "section",
      { id: "site-header", style: this.state.template.header },
      HeaderDisplay
    );
  }
}

class SiteHeaderSearchForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      searchText: ''
    };
    this.onSearchTextChange = this.onSearchTextChange.bind(this);
    this.onSearchFormSubmit = this.onSearchFormSubmit.bind(this);
  }

  onSearchTextChange(e) {
    this.setState({ searchText: e.target.value });
  }

  onSearchFormSubmit(e) {
    e.preventDefault();
    window.location.href = this.props.baseUrl + "/search?projectSearchText=" + this.state.searchText;
  }

  render() {
    return React.createElement(
      "div",
      { id: "site-header-search-form" },
      React.createElement(
        "form",
        { id: "search-form", onSubmit: this.onSearchFormSubmit },
        React.createElement("input", { onChange: this.onSearchTextChange, value: this.state.searchText, type: "text", name: "projectSearchText" }),
        React.createElement("a", { onClick: this.onSearchFormSubmit })
      )
    );
  }
}

class SiteHeaderLoginMenu extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
  render() {

    let registerButtonCssClass, loginButtonCssClass;

    if (window.location.href.indexOf('/register') > -1) {
      registerButtonCssClass = "active";
    }

    if (window.location.href.indexOf('/login') > -1) {
      loginButtonCssClass = "active";
    }

    const menuItemCssClass = {
      "borderColor": this.props.template['header-nav-tabs']['border-color'],
      "backgroundColor": this.props.template['header-nav-tabs']['background-color']
    };

    return React.createElement(
      "div",
      { id: "site-header-login-menu" },
      React.createElement(
        "ul",
        null,
        React.createElement(
          "li",
          { style: menuItemCssClass, className: registerButtonCssClass },
          React.createElement(
            "a",
            { href: "/register" },
            "Register"
          )
        ),
        React.createElement(
          "li",
          { style: menuItemCssClass, className: loginButtonCssClass },
          React.createElement(
            "a",
            { href: "/login" + this.props.redirectString },
            "Login"
          )
        )
      )
    );
  }
}

class SiteHeaderUserMenu extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
    this.handleClick = this.handleClick.bind(this);
  }

  componentWillMount() {
    document.addEventListener('mousedown', this.handleClick, false);
  }

  componentWillUnmount() {
    document.removeEventListener('mousedown', this.handleClick, false);
  }

  handleClick(e) {
    let dropdownClass = "";
    if (this.node.contains(e.target)) {
      if (this.state.dropdownClass === "open") {
        if (e.target.className === "profile-menu-toggle" || e.target.className === "profile-menu-image" || e.target.className === "profile-menu-username") {
          dropdownClass = "";
        } else {
          dropdownClass = "open";
        }
      } else {
        dropdownClass = "open";
      }
    }
    this.setState({ dropdownClass: dropdownClass });
  }

  render() {

    return React.createElement(
      "ul",
      { id: "site-header-user-menu-container" },
      React.createElement(
        "li",
        { ref: node => this.node = node, id: "user-menu-toggle", className: this.state.dropdownClass },
        React.createElement(
          "a",
          { className: "profile-menu-toggle" },
          React.createElement("img", { className: "profile-menu-image", src: window.json_member_avatar }),
          React.createElement(
            "span",
            { className: "profile-menu-username" },
            this.props.user.username
          )
        ),
        React.createElement(
          "ul",
          { id: "user-profile-menu" },
          React.createElement("div", { className: "dropdown-header" }),
          React.createElement(
            "li",
            null,
            React.createElement(
              "a",
              { href: "/product/add" },
              "Add Product"
            )
          ),
          React.createElement(
            "li",
            null,
            React.createElement(
              "a",
              { href: this.props.baseUrl + "/u/" + this.props.user.username + "/products" },
              "Products"
            )
          ),
          React.createElement(
            "li",
            null,
            React.createElement(
              "a",
              { href: this.props.baseUrl + "/u/" + this.props.user.username + "/plings" },
              "Plings"
            )
          ),
          React.createElement(
            "li",
            null,
            React.createElement(
              "a",
              { href: "/settings" },
              "Settings"
            )
          ),
          React.createElement(
            "li",
            null,
            React.createElement(
              "a",
              { href: "/logout" },
              "Logout"
            )
          )
        )
      )
    );
  }
}

class MobileSiteHeader extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      status: "switch"
    };
    this.showMobileUserMenu = this.showMobileUserMenu.bind(this);
    this.showMobileSearchForm = this.showMobileSearchForm.bind(this);
    this.showMobileSwitchMenu = this.showMobileSwitchMenu.bind(this);
  }

  showMobileUserMenu() {
    this.setState({ status: "user" });
  }

  showMobileSearchForm() {
    this.setState({ status: "search" });
  }

  showMobileSwitchMenu() {
    this.setState({ status: "switch" });
  }

  render() {

    const menuItemCssClass = {
      "borderColor": this.props.template['header-nav-tabs']['border-color'],
      "backgroundColor": this.props.template['header-nav-tabs']['background-color']
    };

    const closeMenuElementDisplay = React.createElement(
      "a",
      { className: "menu-item", onClick: this.showMobileSwitchMenu },
      React.createElement("span", { className: "glyphicon glyphicon-remove" })
    );

    let mobileMenuDisplay;
    if (this.state.status === "switch") {
      mobileMenuDisplay = React.createElement(
        "div",
        { id: "switch-menu" },
        React.createElement(
          "a",
          { className: "menu-item", onClick: this.showMobileSearchForm, id: "user-menu-switch" },
          React.createElement("span", { className: "glyphicon glyphicon-search" })
        ),
        React.createElement(
          "a",
          { className: "menu-item", onClick: this.showMobileUserMenu, id: "search-menu-switch" },
          React.createElement("span", { className: "glyphicon glyphicon-option-horizontal" })
        )
      );
    } else if (this.state.status === "user") {
      mobileMenuDisplay = React.createElement(
        "div",
        { id: "mobile-user-menu" },
        React.createElement(
          "div",
          { className: "menu-content-wrapper" },
          React.createElement(MobileUserContainer, {
            user: this.props.user,
            baseUrl: this.props.baseUrl,
            template: this.props.template,
            redirectString: this.props.redirectString
          })
        ),
        closeMenuElementDisplay
      );
    } else if (this.state.status === "search") {
      mobileMenuDisplay = React.createElement(
        "div",
        { id: "mobile-search-menu" },
        React.createElement(
          "div",
          { className: "menu-content-wrapper" },
          React.createElement(SiteHeaderSearchForm, {
            baseUrl: this.props.baseUrl
          })
        ),
        closeMenuElementDisplay
      );
    }

    let logoElementCssClass = this.props.store.name;
    if (this.state.status !== "switch") {
      logoElementCssClass += " mini-version";
    }

    return React.createElement(
      "section",
      { id: "mobile-site-header" },
      React.createElement(
        "div",
        { id: "mobile-site-header-logo", className: logoElementCssClass },
        React.createElement(
          "a",
          { href: this.props.logoLink },
          React.createElement("img", { src: this.props.template['header-logo']['image-src'] })
        )
      ),
      React.createElement(
        "div",
        { id: "mobile-site-header-menus-container" },
        mobileMenuDisplay
      )
    );
  }
}

class MobileUserContainer extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  render() {

    let userDisplay;
    if (this.props.user) {
      userDisplay = React.createElement(SiteHeaderUserMenu, {
        user: this.props.user
      });
    } else {
      userDisplay = React.createElement(SiteHeaderLoginMenu, {
        baseUrl: this.props.baseUrl,
        template: this.props.template,
        redirectString: this.props.redirectString
      });
    }

    return React.createElement(
      "div",
      { id: "mobile-user-container" },
      userDisplay
    );
  }
}

ReactDOM.render(React.createElement(SiteHeader, null), document.getElementById('site-header-container'));
<|endoftext|>


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

var cp = require('child_process')
// var fs = require('fs')
// var path = require('path')

var result = process.argv.slice(2).map(function (arg) {
  console.log(arg)
  try {
    var describe = cp.execSync('git describe', {
      cwd: arg,
      encoding: 'utf-8'
    })
      // If the release-tag is not the latest commit, the pattern does not match
    if (describe.match(/-\d+-\w*/)) {
        return { "dir": arg, "describe": describe }
    }
  } catch (e) {
  }
}).filter(function(a) {
    return a
})

console.log(result)
<commit_msg>Output some data of to-be-released repos<commit_after>#!/usr/bin/env node

var cp = require('child_process')
// var fs = require('fs')
// var path = require('path')

var result = process.argv.slice(2).map(function (arg) {
  try {
    var describe = cp.execSync('git describe', {
      cwd: arg,
      encoding: 'utf-8'
    })
      // If the release-tag is not the latest commit, the pattern does not match
      var match = describe.match(/(.*)-(\d+)-g(\w*)/);
      if (match) {
        return { "dir": arg, "describeMatch": match }
    }
  } catch (e) {
  }
}).filter(function(a) {
    return a
}).map(function(repo) {
    return {
        dir: repo.dir,
        tag: repo.describeMatch,
        log: cp.execSync('git log --boundary --oneline '+repo.describeMatch[1] + '..',{
            cwd: repo.dir,
            encoding: "utf-8"
        })
    }
}).forEach(function(repo) {
    console.log(repo.dir + ": "+repo.tag[1]+"\n\n"+repo.log+"\n\n-------------------------\n")
})

<|endoftext|>


<commit_before>export const USER_LOGGED_IN = 'USER_LOGGED_IN'
<commit_msg>add log out const<commit_after>export const USER_LOGGED_IN = 'USER_LOGGED_IN'
export const USER_LOGGED_OUT = 'USER_LOGGED_OUT'
<|endoftext|>


<commit_before>/**
* The `Matter.Constraint` module contains methods for creating and manipulating constraints.
* Constraints are used for specifying that a fixed distance must be maintained between two bodies (or a body and a fixed world-space position).
* The stiffness of constraints can be modified to create springs or elastic.
*
* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
*
* @class Constraint
*/

var Constraint = {};

module.exports = Constraint;

var Vertices = require('../geometry/Vertices');
var Vector = require('../geometry/Vector');
var Sleeping = require('../core/Sleeping');
var Bounds = require('../geometry/Bounds');
var Axes = require('../geometry/Axes');
var Common = require('../core/Common');

(function() {

    Constraint._warming = 0.4;
    Constraint._torqueDampen = 1;
    Constraint._minLength = 0.000001;

    /**
     * Creates a new constraint.
     * All properties have default values, and many are pre-calculated automatically based on other properties.
     * To simulate a revolute constraint (or pin joint) set `length: 0` and a high `stiffness` value (e.g. `0.7` or above).
     * If the constraint is unstable, try lowering the `stiffness` value and / or increasing `engine.constraintIterations`.
     * For compound bodies, constraints must be applied to the parent body (not one of its parts).
     * See the properties section below for detailed information on what you can pass via the `options` object.
     * @method create
     * @param {} options
     * @return {constraint} constraint
     */
    Constraint.create = function(options) {
        var constraint = options;

        // if bodies defined but no points, use body centre
        if (constraint.bodyA && !constraint.pointA)
            constraint.pointA = { x: 0, y: 0 };
        if (constraint.bodyB && !constraint.pointB)
            constraint.pointB = { x: 0, y: 0 };

        // calculate static length using initial world space points
        var initialPointA = constraint.bodyA ? Vector.add(constraint.bodyA.position, constraint.pointA) : constraint.pointA,
            initialPointB = constraint.bodyB ? Vector.add(constraint.bodyB.position, constraint.pointB) : constraint.pointB,
            length = Vector.magnitude(Vector.sub(initialPointA, initialPointB));

        constraint.length = typeof constraint.length !== 'undefined' ? constraint.length : length;

        // option defaults
        constraint.id = constraint.id || Common.nextId();
        constraint.label = constraint.label || 'Constraint';
        constraint.type = 'constraint';
        constraint.stiffness = constraint.stiffness || (constraint.length > 0 ? 1 : 0.7);
        constraint.damping = constraint.damping || 0;
        constraint.angularStiffness = constraint.angularStiffness || 0;
        constraint.angleA = constraint.bodyA ? constraint.bodyA.angle : constraint.angleA;
        constraint.angleB = constraint.bodyB ? constraint.bodyB.angle : constraint.angleB;
        constraint.plugin = {};

        // render
        var render = {
            visible: true,
            lineWidth: 2,
            strokeStyle: '#ffffff',
            type: 'line',
            anchors: true
        };

        if (constraint.length === 0 && constraint.stiffness > 0.1) {
            render.type = 'pin';
            render.anchors = false;
        } else if (constraint.stiffness < 0.9) {
            render.type = 'spring';
        }

        constraint.render = Common.extend(render, constraint.render);

        return constraint;
    };

    /**
     * Prepares for solving by constraint warming.
     * @private
     * @method preSolveAll
     * @param {body[]} bodies
     */
    Constraint.preSolveAll = function(bodies) {
        for (var i = 0; i < bodies.length; i += 1) {
            var body = bodies[i],
                impulse = body.constraintImpulse;

            if (body.isStatic || (impulse.x === 0 && impulse.y === 0 && impulse.angle === 0)) {
                continue;
            }

            body.position.x += impulse.x;
            body.position.y += impulse.y;
            body.angle += impulse.angle;
        }
    };

    /**
     * Solves all constraints in a list of collisions.
     * @private
     * @method solveAll
     * @param {constraint[]} constraints
     * @param {number} timeScale
     */
    Constraint.solveAll = function(constraints, timeScale) {
        // Solve fixed constraints first.
        for (var i = 0; i < constraints.length; i += 1) {
            var constraint = constraints[i],
                fixedA = !constraint.bodyA || (constraint.bodyA && constraint.bodyA.isStatic),
                fixedB = !constraint.bodyB || (constraint.bodyB && constraint.bodyB.isStatic);

            if (fixedA || fixedB) {
                Constraint.solve(constraints[i], timeScale);
            }
        }

        // Solve free constraints last.
        for (i = 0; i < constraints.length; i += 1) {
            constraint = constraints[i];
            fixedA = !constraint.bodyA || (constraint.bodyA && constraint.bodyA.isStatic);
            fixedB = !constraint.bodyB || (constraint.bodyB && constraint.bodyB.isStatic);

            if (!fixedA && !fixedB) {
                Constraint.solve(constraints[i], timeScale);
            }
        }
    };

    /**
     * Solves a distance constraint with Gauss-Siedel method.
     * @private
     * @method solve
     * @param {constraint} constraint
     * @param {number} timeScale
     */
    Constraint.solve = function(constraint, timeScale) {
        var bodyA = constraint.bodyA,
            bodyB = constraint.bodyB,
            pointA = constraint.pointA,
            pointB = constraint.pointB;

        if (!bodyA && !bodyB)
            return;

        // update reference angle
        if (bodyA && !bodyA.isStatic) {
            Vector.rotate(pointA, bodyA.angle - constraint.angleA, pointA);
            constraint.angleA = bodyA.angle;
        }

        // update reference angle
        if (bodyB && !bodyB.isStatic) {
            Vector.rotate(pointB, bodyB.angle - constraint.angleB, pointB);
            constraint.angleB = bodyB.angle;
        }

        var pointAWorld = pointA,
            pointBWorld = pointB;

        if (bodyA) pointAWorld = Vector.add(bodyA.position, pointA);
        if (bodyB) pointBWorld = Vector.add(bodyB.position, pointB);

        if (!pointAWorld || !pointBWorld)
            return;

        var delta = Vector.sub(pointAWorld, pointBWorld),
            currentLength = Vector.magnitude(delta);

        // prevent singularity
        if (currentLength < Constraint._minLength) {
            currentLength = Constraint._minLength;
        }

        // solve distance constraint with Gauss-Siedel method
        var difference = (currentLength - constraint.length) / currentLength,
            stiffness = constraint.stiffness < 1 ? constraint.stiffness * timeScale : constraint.stiffness,
            force = Vector.mult(delta, difference * stiffness),
            massTotal = (bodyA ? bodyA.inverseMass : 0) + (bodyB ? bodyB.inverseMass : 0),
            inertiaTotal = (bodyA ? bodyA.inverseInertia : 0) + (bodyB ? bodyB.inverseInertia : 0),
            resistanceTotal = massTotal + inertiaTotal,
            torque,
            share,
            normal,
            normalVelocity,
            relativeVelocity;

        if (constraint.damping) {
            var zero = Vector.create();
            normal = Vector.div(delta, currentLength);

            relativeVelocity = Vector.sub(
                bodyB && Vector.sub(bodyB.position, bodyB.positionPrev) || zero,
                bodyA && Vector.sub(bodyA.position, bodyA.positionPrev) || zero
            );

            normalVelocity = Vector.dot(normal, relativeVelocity);
        }

        if (bodyA && !bodyA.isStatic) {
            share = bodyA.inverseMass / massTotal;

            // keep track of applied impulses for post solving
            bodyA.constraintImpulse.x -= force.x * share;
            bodyA.constraintImpulse.y -= force.y * share;

            // apply forces
            bodyA.position.x -= force.x * share;
            bodyA.position.y -= force.y * share;

            // apply damping
            if (constraint.damping) {
                bodyA.positionPrev.x -= constraint.damping * normal.x * normalVelocity * share;
                bodyA.positionPrev.y -= constraint.damping * normal.y * normalVelocity * share;
            }

            // apply torque
            torque = (Vector.cross(pointA, force) / resistanceTotal) * Constraint._torqueDampen * bodyA.inverseInertia * (1 - constraint.angularStiffness);
            bodyA.constraintImpulse.angle -= torque;
            bodyA.angle -= torque;
        }

        if (bodyB && !bodyB.isStatic) {
            share = bodyB.inverseMass / massTotal;

            // keep track of applied impulses for post solving
            bodyB.constraintImpulse.x += force.x * share;
            bodyB.constraintImpulse.y += force.y * share;

            // apply forces
            bodyB.position.x += force.x * share;
            bodyB.position.y += force.y * share;

            // apply damping
            if (constraint.damping) {
                bodyB.positionPrev.x += constraint.damping * normal.x * normalVelocity * share;
                bodyB.positionPrev.y += constraint.damping * normal.y * normalVelocity * share;
            }

            // apply torque
            torque = (Vector.cross(pointB, force) / resistanceTotal) * Constraint._torqueDampen * bodyB.inverseInertia * (1 - constraint.angularStiffness);
            bodyB.constraintImpulse.angle += torque;
            bodyB.angle += torque;
        }

    };

    /**
     * Performs body updates required after solving constraints.
     * @private
     * @method postSolveAll
     * @param {body[]} bodies
     */
    Constraint.postSolveAll = function(bodies) {
        for (var i = 0; i < bodies.length; i++) {
            var body = bodies[i],
                impulse = body.constraintImpulse;

            if (body.isStatic || (impulse.x === 0 && impulse.y === 0 && impulse.angle === 0)) {
                continue;
            }

            Sleeping.set(body, false);

            // update geometry and reset
            for (var j = 0; j < body.parts.length; j++) {
                var part = body.parts[j];

                Vertices.translate(part.vertices, impulse);

                if (j > 0) {
                    part.position.x += impulse.x;
                    part.position.y += impulse.y;
                }

                if (impulse.angle !== 0) {
                    Vertices.rotate(part.vertices, impulse.angle, body.position);
                    Axes.rotate(part.axes, impulse.angle);
                    if (j > 0) {
                        Vector.rotateAbout(part.position, impulse.angle, body.position, part.position);
                    }
                }

                Bounds.update(part.bounds, part.vertices, body.velocity);
            }

            // dampen the cached impulse for warming next step
            impulse.angle *= Constraint._warming;
            impulse.x *= Constraint._warming;
            impulse.y *= Constraint._warming;
        }
    };

    /*
    *
    *  Properties Documentation
    *
    */

    /**
     * An integer `Number` uniquely identifying number generated in `Composite.create` by `Common.nextId`.
     *
     * @property id
     * @type number
     */

    /**
     * A `String` denoting the type of object.
     *
     * @property type
     * @type string
     * @default "constraint"
     * @readOnly
     */

    /**
     * An arbitrary `String` name to help the user identify and manage bodies.
     *
     * @property label
     * @type string
     * @default "Constraint"
     */

    /**
     * An `Object` that defines the rendering properties to be consumed by the module `Matter.Render`.
     *
     * @property render
     * @type object
     */

    /**
     * A flag that indicates if the constraint should be rendered.
     *
     * @property render.visible
     * @type boolean
     * @default true
     */

    /**
     * A `Number` that defines the line width to use when rendering the constraint outline.
     * A value of `0` means no outline will be rendered.
     *
     * @property render.lineWidth
     * @type number
     * @default 2
     */

    /**
     * A `String` that defines the stroke style to use when rendering the constraint outline.
     * It is the same as when using a canvas, so it accepts CSS style property values.
     *
     * @property render.strokeStyle
     * @type string
     * @default a random colour
     */

    /**
     * A `String` that defines the constraint rendering type.
     * The possible values are 'line', 'pin', 'spring'.
     * An appropriate render type will be automatically chosen unless one is given in options.
     *
     * @property render.type
     * @type string
     * @default 'line'
     */

    /**
     * A `Boolean` that defines if the constraint's anchor points should be rendered.
     *
     * @property render.anchors
     * @type boolean
     * @default true
     */

    /**
     * The first possible `Body` that this constraint is attached to.
     *
     * @property bodyA
     * @type body
     * @default null
     */

    /**
     * The second possible `Body` that this constraint is attached to.
     *
     * @property bodyB
     * @type body
     * @default null
     */

    /**
     * A `Vector` that specifies the offset of the constraint from center of the `constraint.bodyA` if defined, otherwise a world-space position.
     *
     * @property pointA
     * @type vector
     * @default { x: 0, y: 0 }
     */

    /**
     * A `Vector` that specifies the offset of the constraint from center of the `constraint.bodyA` if defined, otherwise a world-space position.
     *
     * @property pointB
     * @type vector
     * @default { x: 0, y: 0 }
     */

    /**
     * A `Number` that specifies the stiffness of the constraint, i.e. the rate at which it returns to its resting `constraint.length`.
     * A value of `1` means the constraint should be very stiff.
     * A value of `0.2` means the constraint acts like a soft spring.
     *
     * @property stiffness
     * @type number
     * @default 1
     */

    /**
     * A `Number` that specifies the damping of the constraint,
     * i.e. the amount of resistance applied to each body based on their velocities to limit the amount of oscillation.
     * Damping will only be apparent when the constraint also has a very low `stiffness`.
     * A value of `0.1` means the constraint will apply heavy damping, resulting in little to no oscillation.
     * A value of `0` means the constraint will apply no damping.
     *
     * @property damping
     * @type number
     * @default 0
     */

    /**
     * A `Number` that specifies the target resting length of the constraint.
     * It is calculated automatically in `Constraint.create` from initial positions of the `constraint.bodyA` and `constraint.bodyB`.
     *
     * @property length
     * @type number
     */

    /**
     * An object reserved for storing plugin-specific properties.
     *
     * @property plugin
     * @type {}
     */

})();
<commit_msg>Fixed constraint pointB documentation<commit_after>/**
* The `Matter.Constraint` module contains methods for creating and manipulating constraints.
* Constraints are used for specifying that a fixed distance must be maintained between two bodies (or a body and a fixed world-space position).
* The stiffness of constraints can be modified to create springs or elastic.
*
* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
*
* @class Constraint
*/

var Constraint = {};

module.exports = Constraint;

var Vertices = require('../geometry/Vertices');
var Vector = require('../geometry/Vector');
var Sleeping = require('../core/Sleeping');
var Bounds = require('../geometry/Bounds');
var Axes = require('../geometry/Axes');
var Common = require('../core/Common');

(function() {

    Constraint._warming = 0.4;
    Constraint._torqueDampen = 1;
    Constraint._minLength = 0.000001;

    /**
     * Creates a new constraint.
     * All properties have default values, and many are pre-calculated automatically based on other properties.
     * To simulate a revolute constraint (or pin joint) set `length: 0` and a high `stiffness` value (e.g. `0.7` or above).
     * If the constraint is unstable, try lowering the `stiffness` value and / or increasing `engine.constraintIterations`.
     * For compound bodies, constraints must be applied to the parent body (not one of its parts).
     * See the properties section below for detailed information on what you can pass via the `options` object.
     * @method create
     * @param {} options
     * @return {constraint} constraint
     */
    Constraint.create = function(options) {
        var constraint = options;

        // if bodies defined but no points, use body centre
        if (constraint.bodyA && !constraint.pointA)
            constraint.pointA = { x: 0, y: 0 };
        if (constraint.bodyB && !constraint.pointB)
            constraint.pointB = { x: 0, y: 0 };

        // calculate static length using initial world space points
        var initialPointA = constraint.bodyA ? Vector.add(constraint.bodyA.position, constraint.pointA) : constraint.pointA,
            initialPointB = constraint.bodyB ? Vector.add(constraint.bodyB.position, constraint.pointB) : constraint.pointB,
            length = Vector.magnitude(Vector.sub(initialPointA, initialPointB));

        constraint.length = typeof constraint.length !== 'undefined' ? constraint.length : length;

        // option defaults
        constraint.id = constraint.id || Common.nextId();
        constraint.label = constraint.label || 'Constraint';
        constraint.type = 'constraint';
        constraint.stiffness = constraint.stiffness || (constraint.length > 0 ? 1 : 0.7);
        constraint.damping = constraint.damping || 0;
        constraint.angularStiffness = constraint.angularStiffness || 0;
        constraint.angleA = constraint.bodyA ? constraint.bodyA.angle : constraint.angleA;
        constraint.angleB = constraint.bodyB ? constraint.bodyB.angle : constraint.angleB;
        constraint.plugin = {};

        // render
        var render = {
            visible: true,
            lineWidth: 2,
            strokeStyle: '#ffffff',
            type: 'line',
            anchors: true
        };

        if (constraint.length === 0 && constraint.stiffness > 0.1) {
            render.type = 'pin';
            render.anchors = false;
        } else if (constraint.stiffness < 0.9) {
            render.type = 'spring';
        }

        constraint.render = Common.extend(render, constraint.render);

        return constraint;
    };

    /**
     * Prepares for solving by constraint warming.
     * @private
     * @method preSolveAll
     * @param {body[]} bodies
     */
    Constraint.preSolveAll = function(bodies) {
        for (var i = 0; i < bodies.length; i += 1) {
            var body = bodies[i],
                impulse = body.constraintImpulse;

            if (body.isStatic || (impulse.x === 0 && impulse.y === 0 && impulse.angle === 0)) {
                continue;
            }

            body.position.x += impulse.x;
            body.position.y += impulse.y;
            body.angle += impulse.angle;
        }
    };

    /**
     * Solves all constraints in a list of collisions.
     * @private
     * @method solveAll
     * @param {constraint[]} constraints
     * @param {number} timeScale
     */
    Constraint.solveAll = function(constraints, timeScale) {
        // Solve fixed constraints first.
        for (var i = 0; i < constraints.length; i += 1) {
            var constraint = constraints[i],
                fixedA = !constraint.bodyA || (constraint.bodyA && constraint.bodyA.isStatic),
                fixedB = !constraint.bodyB || (constraint.bodyB && constraint.bodyB.isStatic);

            if (fixedA || fixedB) {
                Constraint.solve(constraints[i], timeScale);
            }
        }

        // Solve free constraints last.
        for (i = 0; i < constraints.length; i += 1) {
            constraint = constraints[i];
            fixedA = !constraint.bodyA || (constraint.bodyA && constraint.bodyA.isStatic);
            fixedB = !constraint.bodyB || (constraint.bodyB && constraint.bodyB.isStatic);

            if (!fixedA && !fixedB) {
                Constraint.solve(constraints[i], timeScale);
            }
        }
    };

    /**
     * Solves a distance constraint with Gauss-Siedel method.
     * @private
     * @method solve
     * @param {constraint} constraint
     * @param {number} timeScale
     */
    Constraint.solve = function(constraint, timeScale) {
        var bodyA = constraint.bodyA,
            bodyB = constraint.bodyB,
            pointA = constraint.pointA,
            pointB = constraint.pointB;

        if (!bodyA && !bodyB)
            return;

        // update reference angle
        if (bodyA && !bodyA.isStatic) {
            Vector.rotate(pointA, bodyA.angle - constraint.angleA, pointA);
            constraint.angleA = bodyA.angle;
        }

        // update reference angle
        if (bodyB && !bodyB.isStatic) {
            Vector.rotate(pointB, bodyB.angle - constraint.angleB, pointB);
            constraint.angleB = bodyB.angle;
        }

        var pointAWorld = pointA,
            pointBWorld = pointB;

        if (bodyA) pointAWorld = Vector.add(bodyA.position, pointA);
        if (bodyB) pointBWorld = Vector.add(bodyB.position, pointB);

        if (!pointAWorld || !pointBWorld)
            return;

        var delta = Vector.sub(pointAWorld, pointBWorld),
            currentLength = Vector.magnitude(delta);

        // prevent singularity
        if (currentLength < Constraint._minLength) {
            currentLength = Constraint._minLength;
        }

        // solve distance constraint with Gauss-Siedel method
        var difference = (currentLength - constraint.length) / currentLength,
            stiffness = constraint.stiffness < 1 ? constraint.stiffness * timeScale : constraint.stiffness,
            force = Vector.mult(delta, difference * stiffness),
            massTotal = (bodyA ? bodyA.inverseMass : 0) + (bodyB ? bodyB.inverseMass : 0),
            inertiaTotal = (bodyA ? bodyA.inverseInertia : 0) + (bodyB ? bodyB.inverseInertia : 0),
            resistanceTotal = massTotal + inertiaTotal,
            torque,
            share,
            normal,
            normalVelocity,
            relativeVelocity;

        if (constraint.damping) {
            var zero = Vector.create();
            normal = Vector.div(delta, currentLength);

            relativeVelocity = Vector.sub(
                bodyB && Vector.sub(bodyB.position, bodyB.positionPrev) || zero,
                bodyA && Vector.sub(bodyA.position, bodyA.positionPrev) || zero
            );

            normalVelocity = Vector.dot(normal, relativeVelocity);
        }

        if (bodyA && !bodyA.isStatic) {
            share = bodyA.inverseMass / massTotal;

            // keep track of applied impulses for post solving
            bodyA.constraintImpulse.x -= force.x * share;
            bodyA.constraintImpulse.y -= force.y * share;

            // apply forces
            bodyA.position.x -= force.x * share;
            bodyA.position.y -= force.y * share;

            // apply damping
            if (constraint.damping) {
                bodyA.positionPrev.x -= constraint.damping * normal.x * normalVelocity * share;
                bodyA.positionPrev.y -= constraint.damping * normal.y * normalVelocity * share;
            }

            // apply torque
            torque = (Vector.cross(pointA, force) / resistanceTotal) * Constraint._torqueDampen * bodyA.inverseInertia * (1 - constraint.angularStiffness);
            bodyA.constraintImpulse.angle -= torque;
            bodyA.angle -= torque;
        }

        if (bodyB && !bodyB.isStatic) {
            share = bodyB.inverseMass / massTotal;

            // keep track of applied impulses for post solving
            bodyB.constraintImpulse.x += force.x * share;
            bodyB.constraintImpulse.y += force.y * share;

            // apply forces
            bodyB.position.x += force.x * share;
            bodyB.position.y += force.y * share;

            // apply damping
            if (constraint.damping) {
                bodyB.positionPrev.x += constraint.damping * normal.x * normalVelocity * share;
                bodyB.positionPrev.y += constraint.damping * normal.y * normalVelocity * share;
            }

            // apply torque
            torque = (Vector.cross(pointB, force) / resistanceTotal) * Constraint._torqueDampen * bodyB.inverseInertia * (1 - constraint.angularStiffness);
            bodyB.constraintImpulse.angle += torque;
            bodyB.angle += torque;
        }

    };

    /**
     * Performs body updates required after solving constraints.
     * @private
     * @method postSolveAll
     * @param {body[]} bodies
     */
    Constraint.postSolveAll = function(bodies) {
        for (var i = 0; i < bodies.length; i++) {
            var body = bodies[i],
                impulse = body.constraintImpulse;

            if (body.isStatic || (impulse.x === 0 && impulse.y === 0 && impulse.angle === 0)) {
                continue;
            }

            Sleeping.set(body, false);

            // update geometry and reset
            for (var j = 0; j < body.parts.length; j++) {
                var part = body.parts[j];

                Vertices.translate(part.vertices, impulse);

                if (j > 0) {
                    part.position.x += impulse.x;
                    part.position.y += impulse.y;
                }

                if (impulse.angle !== 0) {
                    Vertices.rotate(part.vertices, impulse.angle, body.position);
                    Axes.rotate(part.axes, impulse.angle);
                    if (j > 0) {
                        Vector.rotateAbout(part.position, impulse.angle, body.position, part.position);
                    }
                }

                Bounds.update(part.bounds, part.vertices, body.velocity);
            }

            // dampen the cached impulse for warming next step
            impulse.angle *= Constraint._warming;
            impulse.x *= Constraint._warming;
            impulse.y *= Constraint._warming;
        }
    };

    /*
    *
    *  Properties Documentation
    *
    */

    /**
     * An integer `Number` uniquely identifying number generated in `Composite.create` by `Common.nextId`.
     *
     * @property id
     * @type number
     */

    /**
     * A `String` denoting the type of object.
     *
     * @property type
     * @type string
     * @default "constraint"
     * @readOnly
     */

    /**
     * An arbitrary `String` name to help the user identify and manage bodies.
     *
     * @property label
     * @type string
     * @default "Constraint"
     */

    /**
     * An `Object` that defines the rendering properties to be consumed by the module `Matter.Render`.
     *
     * @property render
     * @type object
     */

    /**
     * A flag that indicates if the constraint should be rendered.
     *
     * @property render.visible
     * @type boolean
     * @default true
     */

    /**
     * A `Number` that defines the line width to use when rendering the constraint outline.
     * A value of `0` means no outline will be rendered.
     *
     * @property render.lineWidth
     * @type number
     * @default 2
     */

    /**
     * A `String` that defines the stroke style to use when rendering the constraint outline.
     * It is the same as when using a canvas, so it accepts CSS style property values.
     *
     * @property render.strokeStyle
     * @type string
     * @default a random colour
     */

    /**
     * A `String` that defines the constraint rendering type.
     * The possible values are 'line', 'pin', 'spring'.
     * An appropriate render type will be automatically chosen unless one is given in options.
     *
     * @property render.type
     * @type string
     * @default 'line'
     */

    /**
     * A `Boolean` that defines if the constraint's anchor points should be rendered.
     *
     * @property render.anchors
     * @type boolean
     * @default true
     */

    /**
     * The first possible `Body` that this constraint is attached to.
     *
     * @property bodyA
     * @type body
     * @default null
     */

    /**
     * The second possible `Body` that this constraint is attached to.
     *
     * @property bodyB
     * @type body
     * @default null
     */

    /**
     * A `Vector` that specifies the offset of the constraint from center of the `constraint.bodyA` if defined, otherwise a world-space position.
     *
     * @property pointA
     * @type vector
     * @default { x: 0, y: 0 }
     */

    /**
     * A `Vector` that specifies the offset of the constraint from center of the `constraint.bodyB` if defined, otherwise a world-space position.
     *
     * @property pointB
     * @type vector
     * @default { x: 0, y: 0 }
     */

    /**
     * A `Number` that specifies the stiffness of the constraint, i.e. the rate at which it returns to its resting `constraint.length`.
     * A value of `1` means the constraint should be very stiff.
     * A value of `0.2` means the constraint acts like a soft spring.
     *
     * @property stiffness
     * @type number
     * @default 1
     */

    /**
     * A `Number` that specifies the damping of the constraint,
     * i.e. the amount of resistance applied to each body based on their velocities to limit the amount of oscillation.
     * Damping will only be apparent when the constraint also has a very low `stiffness`.
     * A value of `0.1` means the constraint will apply heavy damping, resulting in little to no oscillation.
     * A value of `0` means the constraint will apply no damping.
     *
     * @property damping
     * @type number
     * @default 0
     */

    /**
     * A `Number` that specifies the target resting length of the constraint.
     * It is calculated automatically in `Constraint.create` from initial positions of the `constraint.bodyA` and `constraint.bodyB`.
     *
     * @property length
     * @type number
     */

    /**
     * An object reserved for storing plugin-specific properties.
     *
     * @property plugin
     * @type {}
     */

})();
<|endoftext|>


<commit_before>import React from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux'
import {fetchWeather} from '../actions/index'
function mapStateToProps(state) {
  return {};
}

class SearchBar extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      term: ''
    };

    this.onInputChange = this.onInputChange.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
  }

  onInputChange(event) {

    event.preventDefault();
    this.setState({term: event.target.value})
  }

  onSubmit(e) {
    console.log('need to look for', this.state.term)
    e.preventDefault();
    this.props.fetchWeather(this.state.term)
    this.setState({term: ''});

  }

  componentDidMount() {
    var input = document.getElementById('pac-input');
    var autocomplete = new google.maps.places.Autocomplete(input,{ types: ['geocode'] });
  }

  render() {
    return (
      <form onSubmit={this.onSubmit} className="input-group">

          <input id="pac-input" placeholder="Select location" className="form-control" value={this.state.term} onChange={this.onInputChange}/>

          <button className="btn btn-secondary" type="submit">Submit</button>

      </form>
    );
  }
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({
    fetchWeather
  }, dispatch)
} //adding the fetchWeather to the props and binding it so when it changes, it will re-render my component

export default connect(null, mapDispatchToProps)(SearchBar)
// set first arg to null because i dont care about states for this component but only it's props
<commit_msg>make it better<commit_after>import React from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux'
import {fetchWeather} from '../actions/index'
function mapStateToProps(state) {
  return {};
}

class SearchBar extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      term: ''
    };

    this.onInputChange = this.onInputChange.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
  }

  onInputChange(event) {

    event.preventDefault();
    this.setState({term: event.target.value})
  }

  onSubmit(e) {
    console.log('need to look for', this.state.term)
    e.preventDefault();
    this.props.fetchWeather(this.state.term)
    this.setState({term: ''});

  }

  componentDidMount() {
    var input = document.getElementById('pac-input');
    var autocomplete = new google.maps.places.Autocomplete(input,{ types: ['geocode'] });

google.maps.event.addListener(autocomplete,'place_changed', ()=>{   this.props.fetchWeather(autocomplete.getPlace().formatted_address); this.setState({term: ''}) });
  }

  render() {
    return (
      <form onSubmit={this.onSubmit} className="input-group">

          <input id="pac-input" placeholder="Select location" className="form-control" value={this.state.term} onChange={this.onInputChange}/>

          <button className="btn btn-secondary" type="submit">Submit</button>

      </form>
    );
  }
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({
    fetchWeather
  }, dispatch)
} //adding the fetchWeather to the props and binding it so when it changes, it will re-render my component

export default connect(null, mapDispatchToProps)(SearchBar)
// set first arg to null because i dont care about states for this component but only it's props
<|endoftext|>