<commit_before>/**
 * @license
 * Copyright 2019 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.u2',
  name: 'ExportModal',
  extends: 'foam.u2.View',

  documentation: 'Export Modal',

  imports: [
    'exportDriverRegistryDAO',
    'filteredTableColumns'
  ],

  requires: [
    'foam.u2.ModalHeader',
    'foam.u2.layout.Cols'
  ],

  properties: [
    {
      name: 'dataType',
      view: function(_, X) {
        return foam.u2.view.ChoiceView.create({
          dao: X.exportDriverRegistryDAO.where(X.data.predicate),
          objToChoice: function(a) {
            return [a.id, a.id];
          }
        });
      }
    },
    {
      name: 'note',
      view: 'foam.u2.tag.TextArea',
      value: ''
    },
    {
      class: 'FObjectProperty',
      of: 'foam.mlang.predicate.Predicate',
      name: 'predicate',
      factory: function() { return foam.mlang.predicate.True.create(); }
    },
    'exportData',
    'exportObj',
    {
      name: 'exportAllColumns',
      view: { class: 'foam.u2.CheckBox' },
      class: 'Boolean'
    }
  ],

  css: `
    ^{
      width: 448px;
      margin: auto;
    }
    ^ .foam-u2-tag-Select {
      width: 125px;
      height: 40px;
      border-radius: 0;
      margin-left: 25px;
      padding: 12px 20px;
      border: solid 1px rgba(164, 179, 184, 0.5);
      background-color: white;
      outline: none;
    }
    ^ .foam-u2-tag-Select:hover {
      cursor: pointer;
    }
    ^ .foam-u2-tag-Select:focus {
      border: solid 1px #59A5D5;
    }
    ^ .label{
      margin: 10px 0px 0px 25px;
    }
    ^ .note {
      height: 150px;
      width: 398px;
      margin-left: 25px;
    }
    ^buttons {
      padding: 12px;
    }

    ^ .foam-u2-ActionView-primary {
      margin: 12px;
    }
  `,

  methods: [
    function initE() {
      var self = this;
      this.SUPER();

      this
      .tag(this.ModalHeader.create({
        title: 'Export'
      }))
      .addClass(this.myClass())
      .startContext({ data: this })
        .start()
          .start().addClass('label').add('Data Type').end()
          .start(this.DATA_TYPE).end()
          .start().addClass('label').add('Response').end()
          .start(this.NOTE).addClass('input-box').addClass('note').end()
          .add(
            self.slot(function(dataType) {
              if ( dataType == 'CSV' ) {
                return self.E().start().addClass('label').add('Export all columns ').startContext({ data: self }).add(self.EXPORT_ALL_COLUMNS).endContext().end();
              }
            })
          )
          .start(this.Cols).style({ 'justify-content': 'flex-start' }).addClass(this.myClass('buttons'))
            .start(this.DOWNLOAD).end()
            .start(this.CONVERT).end()
          .end()
        .end()
      .endContext();
    }
  ],

  actions: [
    async function convert() {
      if ( ! this.exportData && ! this.exportObj ) {
        console.log('Neither exportData nor exportObj exist');
        return;
      }

      var filteredColumnsCopy = this.filteredTableColumns;
      if ( this.exportAllColumns )
        this.filteredTableColumns = null;

      var exportDriver = await this.exportDriverRegistryDAO.find(this.dataType);
      exportDriver = foam.lookup(exportDriver.driverName).create();

      this.note = this.exportData ?
        await exportDriver.exportDAO(this.__context__, this.exportData) :
        await exportDriver.exportFObject(this.__context__, this.exportObj);

        if ( this.exportAllColumns )
          this.filteredTableColumns = filteredColumnsCopy;
    },

    async function download() {
      var self = this;
      if ( ! this.exportData && ! this.exportObj ) {
        console.log('Neither exportData nor exportObj exist');
        return;
      }

      var filteredColumnsCopy = this.filteredTableColumns;
      if ( this.exportAllColumns )
        this.filteredTableColumns = null;

      var exportDriverReg = await this.exportDriverRegistryDAO.find(this.dataType);
      var exportDriver    = foam.lookup(exportDriverReg.driverName).create();

      var p = this.exportData ?
        exportDriver.exportDAO(this.__context__, this.exportData) :
        Promise.resolve(exportDriver.exportFObject(this.__context__, this.exportObj));

      p.then(result => {
        var prefix = 'data:' + exportDriverReg.mimeType + ',';
        var link = document.createElement('a');
        var href = encodeURI(prefix + result);
        if ( href.length > 524288 ) {
          self.note = result;
          alert('Results exceed maximum download size.\nPlease cut and paste response data.');
        } else {
          link.setAttribute('href', href);
          link.setAttribute('download', 'data.' + exportDriverReg.extension);
          document.body.appendChild(link);
          link.click();
        }
      });

      if ( this.exportAllColumns )
        this.filteredTableColumns = filteredColumnsCopy;
    }
  ]

});
<commit_msg>Fixing errors<commit_after>/**
 * @license
 * Copyright 2019 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.u2',
  name: 'ExportModal',
  extends: 'foam.u2.View',

  documentation: 'Export Modal',

  imports: [
    'exportDriverRegistryDAO',
    'filteredTableColumns'
  ],

  requires: [
    'foam.u2.ModalHeader',
    'foam.u2.layout.Cols'
  ],

  properties: [
    {
      name: 'dataType',
      view: function(_, X) {
        return foam.u2.view.ChoiceView.create({
          dao: X.exportDriverRegistryDAO.where(X.data.predicate),
          objToChoice: function(a) {
            return [a.id, a.id];
          }
        });
      }
    },
    {
      name: 'note',
      view: 'foam.u2.tag.TextArea',
      value: ''
    },
    {
      class: 'FObjectProperty',
      of: 'foam.mlang.predicate.Predicate',
      name: 'predicate',
      factory: function() { return foam.mlang.predicate.True.create(); }
    },
    'exportData',
    'exportObj',
    {
      name: 'exportAllColumns',
      view: { class: 'foam.u2.CheckBox',  label: 'Export all columns '},
      class: 'Boolean',
    }
  ],

  css: `
    ^{
      width: 448px;
      margin: auto;
    }
    ^ .foam-u2-tag-Select {
      width: 125px;
      height: 40px;
      border-radius: 0;
      margin-left: 25px;
      padding: 12px 20px;
      border: solid 1px rgba(164, 179, 184, 0.5);
      background-color: white;
      outline: none;
    }
    ^ .foam-u2-tag-Select:hover {
      cursor: pointer;
    }
    ^ .foam-u2-tag-Select:focus {
      border: solid 1px #59A5D5;
    }
    ^ .label{
      margin: 10px 0px 0px 25px;
    }
    ^ .note {
      height: 150px;
      width: 398px;
      margin-left: 25px;
    }
    ^buttons {
      padding: 12px;
    }

    ^ .foam-u2-ActionView-primary {
      margin: 12px;
    }
  `,

  methods: [
    function initE() {
      var self = this;
      this.SUPER();

      this
      .tag(this.ModalHeader.create({
        title: 'Export'
      }))
      .addClass(this.myClass())
      .startContext({ data: this })
        .start()
          .start().addClass('label').add('Data Type').end()
          .start(this.DATA_TYPE).end()
          .start().addClass('label').add('Response').end()
          .start(this.NOTE).addClass('input-box').addClass('note').end()
          .add(
            self.slot(function(dataType) {
              if ( dataType == 'CSV' ) {
                return self.E().start().addClass('label').startContext({ data: self }).add(self.EXPORT_ALL_COLUMNS).endContext().end();
              }
            })
          )
          .start(this.Cols).style({ 'justify-content': 'flex-start' }).addClass(this.myClass('buttons'))
            .start(this.DOWNLOAD).end()
            .start(this.CONVERT).end()
          .end()
        .end()
      .endContext();
    }
  ],

  actions: [
    async function convert() {
      if ( ! this.exportData && ! this.exportObj ) {
        console.log('Neither exportData nor exportObj exist');
        return;
      }

      var filteredColumnsCopy = this.filteredTableColumns;
      if ( this.exportAllColumns )
        this.filteredTableColumns = null;

      var exportDriver = await this.exportDriverRegistryDAO.find(this.dataType);
      exportDriver = foam.lookup(exportDriver.driverName).create();

      this.note = this.exportData ?
        await exportDriver.exportDAO(this.__context__, this.exportData) :
        await exportDriver.exportFObject(this.__context__, this.exportObj);

        if ( this.exportAllColumns )
          this.filteredTableColumns = filteredColumnsCopy;
    },

    async function download() {
      var self = this;
      if ( ! this.exportData && ! this.exportObj ) {
        console.log('Neither exportData nor exportObj exist');
        return;
      }

      var filteredColumnsCopy = this.filteredTableColumns;
      if ( this.exportAllColumns )
        this.filteredTableColumns = null;

      var exportDriverReg = await this.exportDriverRegistryDAO.find(this.dataType);
      var exportDriver    = foam.lookup(exportDriverReg.driverName).create();

      var p = this.exportData ?
        exportDriver.exportDAO(this.__context__, this.exportData) :
        Promise.resolve(exportDriver.exportFObject(this.__context__, this.exportObj));

      p.then(result => {
        var prefix = 'data:' + exportDriverReg.mimeType + ',';
        var link = document.createElement('a');
        var href = encodeURI(prefix + result);
        if ( href.length > 524288 ) {
          self.note = result;
          alert('Results exceed maximum download size.\nPlease cut and paste response data.');
        } else {
          link.setAttribute('href', href);
          link.setAttribute('download', 'data.' + exportDriverReg.extension);
          document.body.appendChild(link);
          link.click();
        }

        if ( this.exportAllColumns )
          this.filteredTableColumns = filteredColumnsCopy;
      });
    }
  ]

});
<|endoftext|>


<commit_before>/**
 * @typedef {object} ModmailConfig
 * @property {string} [token]
 * @property {array} [mainGuildId]
 * @property {string} [mailGuildId]
 * @property {string} [logChannelId]
 * @property {string} [prefix="!"]
 * @property {string} [snippetPrefix="!!"]
 * @property {string} [snippetPrefixAnon="!!!"]
 * @property {string} [status="Message me for help!"]
 * @property {string} [responseMessage="Thank you for your message! Our mod team will reply to you here as soon as possible."]
 * @property {string} [closeMessage]
 * @property {boolean} [allowUserClose=false]
 * @property {string} [newThreadCategoryId]
 * @property {string} [mentionRole="here"]
 * @property {boolean} [pingOnBotMention=true]
 * @property {string} [botMentionResponse]
 * @property {array} [inboxServerPermission=[]]
 * @property {boolean} [alwaysReply=false]
 * @property {boolean} [alwaysReplyAnon=false]
 * @property {boolean} [useNicknames=false]
 * @property {boolean} [ignoreAccidentalThreads=false]
 * @property {boolean} [threadTimestamps=false]
 * @property {boolean} [allowMove=false]
 * @property {boolean} [syncPermissionsOnMove=true]
 * @property {boolean} [typingProxy=false]
 * @property {boolean} [typingProxyReverse=false]
 * @property {boolean} [mentionUserInThreadHeader=false]
 * @property {boolean} [rolesInThreadHeader=false]
 * @property {boolean} [allowStaffEdit=false]
 * @property {boolean} [allowStaffDelete=false]
 * @property {boolean} [enableGreeting=false]
 * @property {string} [greetingMessage]
 * @property {string} [greetingAttachment]
 * @property {*} [guildGreetings={}]
 * @property {number} [requiredAccountAge] Required account age to message Modmail, in hours
 * @property {string} [accountAgeDeniedMessage="Your Discord account is not old enough to contact modmail."]
 * @property {number} [requiredTimeOnServer] Required time on server to message Modmail, in minutes
 * @property {string} [timeOnServerDeniedMessage="You haven't been a member of the server for long enough to contact modmail."]
 * @property {boolean} [relaySmallAttachmentsAsAttachments=false]
 * @property {number} [smallAttachmentLimit=2097152] Max size of attachment to relay directly. Default is 2MB.
 * @property {string} [attachmentStorage="original"]
 * @property {string} [attachmentStorageChannelId]
 * @property {*} [categoryAutomation={}]
 * @property {boolean} [updateNotifications=true]
 * @property {array} [plugins=[]]
 * @property {*} [commandAliases]
 * @property {number} [port=8890]
 * @property {string} [url]
 * @property {array} [extraIntents=[]]
 * @property {*} [dbType="sqlite"]
 * @property {object} [sqliteOptions]
 * @property {string} sqliteOptions.filename
 * @property {object} [mysqlOptions]
 * @property {string} mysqlOptions.host
 * @property {number} mysqlOptions.port
 * @property {string} mysqlOptions.user
 * @property {string} mysqlOptions.password
 * @property {string} mysqlOptions.database
 * @property {string} [mysqlOptions.timezone]
 */
<commit_msg>Update config JSDoc<commit_after>/**
 * @typedef {object} ModmailConfig
 * @property {string} [token]
 * @property {array} [mainGuildId]
 * @property {string} [mailGuildId]
 * @property {string} [logChannelId]
 * @property {string} [prefix="!"]
 * @property {string} [snippetPrefix="!!"]
 * @property {string} [snippetPrefixAnon="!!!"]
 * @property {string} [status="Message me for help!"]
 * @property {string} [responseMessage="Thank you for your message! Our mod team will reply to you here as soon as possible."]
 * @property {string} [closeMessage]
 * @property {boolean} [allowUserClose=false]
 * @property {string} [newThreadCategoryId]
 * @property {string} [mentionRole="here"]
 * @property {boolean} [pingOnBotMention=true]
 * @property {string} [botMentionResponse]
 * @property {array} [inboxServerPermission=[]]
 * @property {boolean} [alwaysReply=false]
 * @property {boolean} [alwaysReplyAnon=false]
 * @property {boolean} [useNicknames=false]
 * @property {boolean} [ignoreAccidentalThreads=false]
 * @property {boolean} [threadTimestamps=false]
 * @property {boolean} [allowMove=false]
 * @property {boolean} [syncPermissionsOnMove=true]
 * @property {boolean} [typingProxy=false]
 * @property {boolean} [typingProxyReverse=false]
 * @property {boolean} [mentionUserInThreadHeader=false]
 * @property {boolean} [rolesInThreadHeader=false]
 * @property {boolean} [allowStaffEdit=false]
 * @property {boolean} [allowStaffDelete=false]
 * @property {boolean} [enableGreeting=false]
 * @property {string} [greetingMessage]
 * @property {string} [greetingAttachment]
 * @property {*} [guildGreetings={}]
 * @property {number} [requiredAccountAge] Required account age to message Modmail, in hours
 * @property {string} [accountAgeDeniedMessage="Your Discord account is not old enough to contact modmail."]
 * @property {number} [requiredTimeOnServer] Required time on server to message Modmail, in minutes
 * @property {string} [timeOnServerDeniedMessage="You haven't been a member of the server for long enough to contact modmail."]
 * @property {boolean} [relaySmallAttachmentsAsAttachments=false]
 * @property {number} [smallAttachmentLimit=2097152] Max size of attachment to relay directly. Default is 2MB.
 * @property {string} [attachmentStorage="original"]
 * @property {string} [attachmentStorageChannelId]
 * @property {*} [categoryAutomation={}]
 * @property {boolean} [updateNotifications=true]
 * @property {array} [plugins=[]]
 * @property {*} [commandAliases]
 * @property {boolean} [reactOnSeen=false]
 * @property {string} [reactOnSeenEmoji="📨"]
 * @property {boolean} [createThreadOnMention=false]
 * @property {number} [port=8890]
 * @property {string} [url]
 * @property {array} [extraIntents=[]]
 * @property {*} [dbType="sqlite"]
 * @property {object} [sqliteOptions]
 * @property {string} sqliteOptions.filename
 * @property {object} [mysqlOptions]
 * @property {string} mysqlOptions.host
 * @property {number} mysqlOptions.port
 * @property {string} mysqlOptions.user
 * @property {string} mysqlOptions.password
 * @property {string} mysqlOptions.database
 * @property {string} [mysqlOptions.timezone]
 */
<|endoftext|>


<commit_before>/**
 * @classDestription - Placeholder for Projects application variables and functions.
 * @class - Projects
 */
var Projects = (function ($) {
    var constructor = function (infoboxoptions) {
        this.AddressMarker = null;

        this.Events = [];

        // Can we geolocate?
        this.geolocate = navigator.geolocation;

        this.getEvents = function (rows, Map, Default) {

            for (var i in rows) {
                rows[i]['name'] = rows[i]['1. Project Title/Name'];
            }
            rows.sort(function (a, b) {
                if (a.name > b.name) {
                    return 1;
                }
                if (a.name < b.name) {
                    return -1;
                }
                // a must be equal to b
                return 0;
            });
            console.dir(rows);

            // Copy the Project data to the Event object
            for (var i in rows) {
                this.Events[i] = new Event();
                for (var colname in rows[i]) {
                    this.Events[i].data[colname] = rows[i][colname];
                }

                var ll = this.Events[i].data['Location'];
                var lla = ll.split(',');

                if (lla.length != 2) {} else {

                    var Lat = null;
                    var Lng = null;

                    // Create the Google LatLng object

                    Lat = lla[0];
                    Lng = lla[1];

                    this.Events[i].latlng = new google.maps.LatLng(Lat, Lng);

                    var project_type = $.trim(this.Events[i].data['3. Project type']);

                    // Create the markers for each event

                    var icon = '';
                    var panel_class = '';

                    if (!(project_type in project_type_info)) {
                        project_type = 'Other';
                    }

                    icon = project_type_info[project_type].pin_url;

                    project_type_info[project_type].count++;
                    project_type_info['All'].count++;

                    panel_class = project_type_info[project_type].id + '-panel';

                    this.Events[i].marker = new google.maps.Marker({
                        position: this.Events[i].latlng,
                        map: Map.Map,
                        icon: icon,
                        shadow: 'img/shadow.png',
                        clickable: true
                    });

                    this.Events[i].panel = {
                        Lat: Lat,
                        Lng: Lng,
                        map: Map.Map
                    };

                    // Make the info box
                    this.Events[i].infobox = new InfoBox(infoboxoptions);

                    var data = this.Events[i].data;
                    var project_name = data['1. Project Title/Name'];

                    //
                    ptype = data['3. Project type'];
                    if ((typeof project_type_info[(ptype)] === 'undefined')) {
                        ptype = 'Other';
                    }

                    var title_class = 'panel-title-' + project_type_info[ptype].id;

                    var accordion = '';
                    accordion += '
' + "\n";
                    accordion += '
' + "\n";
                    accordion += '
' + "\n";
                    accordion += '                  ' + "\n";
                    accordion += '                    ' + project_name + "\n";
                    accordion += '                  ' + "\n";
                    accordion += '
' + "\n";
                    accordion += '
' + "\n";
                    accordion += '
' + "\n";
                    accordion += '
' + "\n";
                    accordion += this.displayIt('Organization Type:', data['21. Which best describes your type of organization?']);
                    accordion += this.displayIt('Organization website or Facebook page:', data['17. Organization website or Facebook page']);
                    accordion += this.displayIt('Contact:', data['18. Name of lead contact person for project']);
                    accordion += this.displayIt('Phone:', data['19. Phone number of the project\'s contact person']);
                    accordion += this.displayIt('Email:', data['20. Email address of the project\'s contact person']);

                    accordion += '
Project Type: ' + data['3. Project type'] + '
' + "\n";
                    accordion += '
' + data['2. Project description'] + "\n";
                    accordion += '
' + data['How often does this project occur?'] + "\n";
                    accordion += '
' + data['5. What is the start date of your project?'] + ' through ' + data['6. What is the finish date (or anticipated finish date)?'] + "\n";
                    accordion += this.displayIt('Website:', data['Project website']);
                    accordion += this.displayIt('Partners:', data['7. Who are your project partners?']);
                    accordion += this.displayIt('Focus:', data['8. Is the project area-wide or located at one site?']);
                    accordion += this.displayIt('Neighborhoods/Cities:', data['9. For area-wide projects, list the neighborhoods/cities this project occurs.']);
                    accordion += this.displayIt('Project Boundaries:', data['10. For area-wide projects, does this project have more specific boundaries?']);
                    accordion += this.displayIt('Neighborhood Assoc. Support:', data['11. Does the project have the support of the neighborhood association?']);
                    accordion += this.displayIt('Needs:', data['22. The project is in need of:']);
                    accordion += this.displayIt('Will Help:', data['23. We are happy to talk to others about our project and experience!']);

                    accordion += this.displayIt('Website:', data['Project']);

                    accordion += '' + "\n";
                    accordion += '
' + "\n";
                    accordion += '
Show on map
' + "\n";
                    accordion += '
' + "\n";
                    accordion += '
' + "\n";
                    accordion += '
' + "\n";

                    $('#accordion').append(accordion);
                }
            }
            for (var i in this.Events) {
                // Listen for marker clicks
                google.maps.event.addListener(this.Events[i].marker, 'click', this.Events[i].toggleInfoBox(Map.Map, this.Events[i]));
                $('#show-on-map-' + i).on("click", null, {
                    map: Map.Map,
                    default: Default,
                    panel: this.Events[i].panel
                }, this.centerPin);

            }

        };

        this.displayIt = function (label, value) {
            if (value) {
                return '
' + label + ' ' + value + '
' + "\n";
            } else {
                return '';
            }
        }

        /**
         * PROJECT FILTER functions
         */
        this.displayProjectTypeFilters = function () {
            for (var project_type in project_type_info) {
                var project = project_type_info[project_type];
                var li = '
' + project_type + '' + project.count + '
';
                $("#project-type-filter-buttons").append(li);
            }
        }

        this.displayProjectTypeCounts = function () {
            for (var project_type in project_type_info) {
                var project = project_type_info[project_type];
                $('#cnt-' + project.id).html(project.count);
            }
        }

        /**
         * MAP functions
         */
        this.centerPin = function (e) {
            var Latlng = new google.maps.LatLng(
                e.data.panel.Lat,
                e.data.panel.Lng
            );
            e.data.map.setCenter(Latlng);
            e.data.map.setZoom(e.data.default.zoomaddress);
        }

        /**
         * Set the address for a latlng
         */
        this.codeLatLng = function (Latlng) {
            var Geocoder = new google.maps.Geocoder();
            Geocoder.geocode({
                    'latLng': Latlng
                },
                function (Results, Status) {
                    if (Status == google.maps.GeocoderStatus.OK) {
                        if (Results[0]) {
                            var formattedAddress = Results[0].formatted_address.split(',');
                            $('#nav-address').val(formattedAddress[0]);

                            // Mask the exact address before recording
                            // Example: '1456 W Greenleaf Ave' becomes '1400 W Greenleaf Ave'
                            var addarray = $.trim($('#nav-address').val()).split(' ');
                            // Chicago addresses start with numbers. So look for them and mask them.
                            if (addarray[0].match(/^[0-9]+$/) !== null) {
                                var replacement = addarray[0].substr(0, addarray[0].length - 2) + '00';
                                if (replacement !== '00') {
                                    addarray[0] = replacement;
                                } else {
                                    addarray[0] = '0';
                                }
                            }
                            var maskedAddress = addarray.join(' ');
                            //_gaq.push(['_trackEvent', 'Find Me', 'Address', maskedAddress]);
                        } else {
                            alert('We\'re sorry. We could not find an address for this location.');
                        }
                    } else {
                        alert('We\'re sorry. We could not find an address for this location.');
                    }
                }
            );
        };

        // Put a Pan/Zoom control on the map
        this.setFindMeControl = function (controlDiv, Map, Project, Default) {
            // Set CSS styles for the DIV containing the control
            // Setting padding to 5 px will offset the control
            // from the edge of the map.
            controlDiv.style.padding = '1em';
            // Set CSS for the control border.
            var controlUI = document.createElement('div');
            controlUI.style.backgroundColor = '#333';
            //controlUI.style.color = 'white';
            controlUI.style.borderStyle = 'solid';
            controlUI.style.borderWidth = '0px';
            controlUI.style.cursor = 'pointer';
            controlUI.style.textAlign = 'center';
            controlUI.style.borderRadius = '6px';
            controlUI.title = 'Click to find your location.';
            controlDiv.appendChild(controlUI);
            // Set CSS for the control interior.
            var controlText = document.createElement('div');
            controlText.style.fontFamily = '"Helvetica Neue",Helvetica,Arial,sans-serif';
            controlText.style.fontSize = '12px';
            controlText.style.color = '#fff';
            controlText.style.paddingLeft = '.5em';
            controlText.style.paddingRight = '.5em';
            controlText.style.paddingTop = '.3em';
            controlText.style.paddingBottom = '.3em';
            controlText.innerHTML = 'Find Me';
            controlUI.appendChild(controlText);
            // Setup the click event listeners.
            google.maps.event.addDomListener(controlUI, 'click', function () {
                if (navigator.geolocation) {
                    navigator.geolocation.getCurrentPosition(
                        // Success
                        function (position) {
                            //_gaq.push(['_trackEvent', 'GPS', 'Success']);
                            var Latlng = new google.maps.LatLng(
                                position.coords.latitude,
                                position.coords.longitude
                            );
                            Map.Map.setCenter(Latlng);
                            Map.Map.setZoom(Default.zoomaddress);
                            // Make a map marker if none exists yet
                            if (Project.AddressMarker === null) {
                                Project.AddressMarker = new google.maps.Marker({
                                    position: Latlng,
                                    map: Map.Map,
                                    icon: Default.iconlocation,
                                    clickable: false
                                });
                            } else {
                                // Move the marker to the new location
                                Project.AddressMarker.setPosition(Latlng);
                                // If the marker is hidden, unhide it
                                if (Project.AddressMarker.getMap() === null) {
                                    Project.AddressMarker.setMap(Map.Map);
                                }
                            }
                            Project.codeLatLng(Latlng);
                        },
                        // Failure
                        function () {
                            alert('We\'re sorry. We could not find you. Please type in an address.');
                        }, {
                            timeout: 5000,
                            enableHighAccuracy: true
                        }
                    );
                }
            });
        };

        this.setMapLegend = function (controlDiv, Map, Project, Default) {
            // Set CSS styles for the DIV containing the control
            // Setting padding to 5 px will offset the control
            // from the edge of the map.
            controlDiv.style.padding = '1em';
            // Set CSS for the control border.
            var controlUI = document.createElement('div');
            controlUI.style.backgroundColor = 'rgba(255,255,255,0.7)';
            //controlUI.style.color = 'white';
            controlUI.style.borderStyle = 'solid';
            controlUI.style.borderWidth = '0px';
            controlUI.style.cursor = 'pointer';
            controlUI.style.textAlign = 'center';
            controlUI.style.borderRadius = '6px';
            controlUI.title = 'Click to hide.';
            controlDiv.appendChild(controlUI);
            // Set CSS for the control interior.
            var controlText = document.createElement('div');
            controlText.style.fontFamily = '"Helvetica Neue",Helvetica,Arial,sans-serif';
            controlText.style.fontSize = '12px';
            controlText.style.color = '#333';
            controlText.style.paddingLeft = '.5em';
            controlText.style.paddingRight = '.5em';
            controlText.style.paddingTop = '.3em';
            controlText.style.paddingBottom = '.3em';
            controlText.innerHTML = '
Free
';
            controlUI.appendChild(controlText);
            // Setup the click event listeners.
            google.maps.event.addDomListener(controlUI, 'click', function () {
                Map.Map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].clear();
            });
        };

        this.setMarkersByProjectType = function (project_type_to_display) {
            if (project_type_to_display == 'all') {
                $('.panel-default').css("display", "block");
            } else {
                $('.panel-default').css("display", "none");
                $('.' + project_type_to_display + '-panel').css("display", "block");
            }

            for (var i in this.Events) {

                var ptype = this.Events[i].data['3. Project type'];

                if (project_type_to_display == 'all' || ((typeof project_type_info[(ptype)] !== 'undefined') && (project_type_info[(ptype)].id == project_type_to_display))) {
                    if ((typeof project_type_info[(ptype)] === 'undefined')) {
                        ptype = 'Other';
                    }
                    this.Events[i].marker.setIcon(project_type_info[(ptype)].pin_url);
                } else {
                    this.Events[i].marker.setIcon('img/grey-transparent.png');
                }

            }
        };
    };
    return constructor;
})(jQuery);
<commit_msg>Fixed field names since they changed in the form<commit_after>/**
 * @classDestription - Placeholder for Projects application variables and functions.
 * @class - Projects
 */
var Projects = (function ($) {
    var constructor = function (infoboxoptions) {
        this.AddressMarker = null;

        this.Events = [];

        // Can we geolocate?
        this.geolocate = navigator.geolocation;

        this.getEvents = function (rows, Map, Default) {

            for (var i in rows) {
                rows[i]['name'] = rows[i]['1. Project Title/Name'];
            }
            rows.sort(function (a, b) {
                if (a.name > b.name) {
                    return 1;
                }
                if (a.name < b.name) {
                    return -1;
                }
                // a must be equal to b
                return 0;
            });
            console.dir(rows);

            // Copy the Project data to the Event object
            for (var i in rows) {
                this.Events[i] = new Event();
                for (var colname in rows[i]) {
                    this.Events[i].data[colname] = rows[i][colname];
                }

                var ll = this.Events[i].data['Location'];
                var lla = ll.split(',');

                if (lla.length != 2) {} else {

                    var Lat = null;
                    var Lng = null;

                    // Create the Google LatLng object

                    Lat = lla[0];
                    Lng = lla[1];

                    this.Events[i].latlng = new google.maps.LatLng(Lat, Lng);

                    var project_type = $.trim(this.Events[i].data['3. Project type']);

                    // Create the markers for each event

                    var icon = '';
                    var panel_class = '';

                    if (!(project_type in project_type_info)) {
                        project_type = 'Other';
                    }

                    icon = project_type_info[project_type].pin_url;

                    project_type_info[project_type].count++;
                    project_type_info['All'].count++;

                    panel_class = project_type_info[project_type].id + '-panel';

                    this.Events[i].marker = new google.maps.Marker({
                        position: this.Events[i].latlng,
                        map: Map.Map,
                        icon: icon,
                        shadow: 'img/shadow.png',
                        clickable: true
                    });

                    this.Events[i].panel = {
                        Lat: Lat,
                        Lng: Lng,
                        map: Map.Map
                    };

                    // Make the info box
                    this.Events[i].infobox = new InfoBox(infoboxoptions);

                    var data = this.Events[i].data;
                    var project_name = data['1. Project Title/Name'];

                    //
                    ptype = data['3. Project type'];
                    if ((typeof project_type_info[(ptype)] === 'undefined')) {
                        ptype = 'Other';
                    }

                    var title_class = 'panel-title-' + project_type_info[ptype].id;

                    var accordion = '';
                    accordion += '
' + "\n";
                    accordion += '
' + "\n";
                    accordion += '
' + "\n";
                    accordion += '                  ' + "\n";
                    accordion += '                    ' + project_name + "\n";
                    accordion += '                  ' + "\n";
                    accordion += '
' + "\n";
                    accordion += '
' + "\n";
                    accordion += '
' + "\n";
                    accordion += '
' + "\n";
                    accordion += this.displayIt('Organization Type:', data['21. Which best describes your organization?']);
                    accordion += this.displayIt('Organization website or Facebook page:', data['4. Project website or Facebook page']);
                    accordion += this.displayIt('Contact:', data['19. Name of lead contact person for project']);
                    accordion += this.displayIt('Phone:', data['20. Phone number of the project\'s contact person']);
                    accordion += this.displayIt('Email:', data['20. Email address of the project\'s contact person']);

                    accordion += '
Project Type: ' + data['3. Project type'] + '
' + "\n";
                    accordion += '
' + data['2. Project description'] + "\n";
                    accordion += '
' + data['How often does this project occur?'] + "\n";
                    accordion += '
' + data['5. What is the start date of your project?'] + ' through ' + data['6. What is the finish date (or anticipated finish date)?'] + "\n";
                    accordion += this.displayIt('Website:', data['4. Project website or Facebook page']);
                    accordion += this.displayIt('Partners:', data['8. Who are your project partners?']);
                    accordion += this.displayIt('Focus:', data['9. Is the project area-wide or located at one site?']);
                    accordion += this.displayIt('Neighborhoods/Cities:', data['10. For area-wide projects, list the neighborhood(s) in which this project occurs.']);
                    accordion += this.displayIt('Project Boundaries:', data['11. For area-wide projects, does this project have more specific boundaries?']);
                    accordion += this.displayIt('Neighborhood Assoc. Support:', data['12. Does the project have the support of the neighborhood association?']);
                    accordion += this.displayIt('Needs:', data['22. The project is in need of:']);
                    accordion += this.displayIt('Will Help:', data['23. We are happy to talk to others about our project and experience!']);

                    accordion += '' + "\n";
                    accordion += '
' + "\n";
                    accordion += '
Show on map
' + "\n";
                    accordion += '
' + "\n";
                    accordion += '
' + "\n";
                    accordion += '
' + "\n";

                    $('#accordion').append(accordion);
                }
            }
            for (var i in this.Events) {
                // Listen for marker clicks
                google.maps.event.addListener(this.Events[i].marker, 'click', this.Events[i].toggleInfoBox(Map.Map, this.Events[i]));
                $('#show-on-map-' + i).on("click", null, {
                    map: Map.Map,
                    default: Default,
                    panel: this.Events[i].panel
                }, this.centerPin);

            }

        };

        this.displayIt = function (label, value) {
            if (value) {
                return '
' + label + ' ' + value + '
' + "\n";
            } else {
                return '';
            }
        }

        /**
         * PROJECT FILTER functions
         */
        this.displayProjectTypeFilters = function () {
            for (var project_type in project_type_info) {
                var project = project_type_info[project_type];
                var li = '
' + project_type + '' + project.count + '
';
                $("#project-type-filter-buttons").append(li);
            }
        }

        this.displayProjectTypeCounts = function () {
            for (var project_type in project_type_info) {
                var project = project_type_info[project_type];
                $('#cnt-' + project.id).html(project.count);
            }
        }

        /**
         * MAP functions
         */
        this.centerPin = function (e) {
            var Latlng = new google.maps.LatLng(
                e.data.panel.Lat,
                e.data.panel.Lng
            );
            e.data.map.setCenter(Latlng);
            e.data.map.setZoom(e.data.default.zoomaddress);
        }

        /**
         * Set the address for a latlng
         */
        this.codeLatLng = function (Latlng) {
            var Geocoder = new google.maps.Geocoder();
            Geocoder.geocode({
                    'latLng': Latlng
                },
                function (Results, Status) {
                    if (Status == google.maps.GeocoderStatus.OK) {
                        if (Results[0]) {
                            var formattedAddress = Results[0].formatted_address.split(',');
                            $('#nav-address').val(formattedAddress[0]);

                            // Mask the exact address before recording
                            // Example: '1456 W Greenleaf Ave' becomes '1400 W Greenleaf Ave'
                            var addarray = $.trim($('#nav-address').val()).split(' ');
                            // Chicago addresses start with numbers. So look for them and mask them.
                            if (addarray[0].match(/^[0-9]+$/) !== null) {
                                var replacement = addarray[0].substr(0, addarray[0].length - 2) + '00';
                                if (replacement !== '00') {
                                    addarray[0] = replacement;
                                } else {
                                    addarray[0] = '0';
                                }
                            }
                            var maskedAddress = addarray.join(' ');
                            //_gaq.push(['_trackEvent', 'Find Me', 'Address', maskedAddress]);
                        } else {
                            alert('We\'re sorry. We could not find an address for this location.');
                        }
                    } else {
                        alert('We\'re sorry. We could not find an address for this location.');
                    }
                }
            );
        };

        // Put a Pan/Zoom control on the map
        this.setFindMeControl = function (controlDiv, Map, Project, Default) {
            // Set CSS styles for the DIV containing the control
            // Setting padding to 5 px will offset the control
            // from the edge of the map.
            controlDiv.style.padding = '1em';
            // Set CSS for the control border.
            var controlUI = document.createElement('div');
            controlUI.style.backgroundColor = '#333';
            //controlUI.style.color = 'white';
            controlUI.style.borderStyle = 'solid';
            controlUI.style.borderWidth = '0px';
            controlUI.style.cursor = 'pointer';
            controlUI.style.textAlign = 'center';
            controlUI.style.borderRadius = '6px';
            controlUI.title = 'Click to find your location.';
            controlDiv.appendChild(controlUI);
            // Set CSS for the control interior.
            var controlText = document.createElement('div');
            controlText.style.fontFamily = '"Helvetica Neue",Helvetica,Arial,sans-serif';
            controlText.style.fontSize = '12px';
            controlText.style.color = '#fff';
            controlText.style.paddingLeft = '.5em';
            controlText.style.paddingRight = '.5em';
            controlText.style.paddingTop = '.3em';
            controlText.style.paddingBottom = '.3em';
            controlText.innerHTML = 'Find Me';
            controlUI.appendChild(controlText);
            // Setup the click event listeners.
            google.maps.event.addDomListener(controlUI, 'click', function () {
                if (navigator.geolocation) {
                    navigator.geolocation.getCurrentPosition(
                        // Success
                        function (position) {
                            //_gaq.push(['_trackEvent', 'GPS', 'Success']);
                            var Latlng = new google.maps.LatLng(
                                position.coords.latitude,
                                position.coords.longitude
                            );
                            Map.Map.setCenter(Latlng);
                            Map.Map.setZoom(Default.zoomaddress);
                            // Make a map marker if none exists yet
                            if (Project.AddressMarker === null) {
                                Project.AddressMarker = new google.maps.Marker({
                                    position: Latlng,
                                    map: Map.Map,
                                    icon: Default.iconlocation,
                                    clickable: false
                                });
                            } else {
                                // Move the marker to the new location
                                Project.AddressMarker.setPosition(Latlng);
                                // If the marker is hidden, unhide it
                                if (Project.AddressMarker.getMap() === null) {
                                    Project.AddressMarker.setMap(Map.Map);
                                }
                            }
                            Project.codeLatLng(Latlng);
                        },
                        // Failure
                        function () {
                            alert('We\'re sorry. We could not find you. Please type in an address.');
                        }, {
                            timeout: 5000,
                            enableHighAccuracy: true
                        }
                    );
                }
            });
        };

        this.setMapLegend = function (controlDiv, Map, Project, Default) {
            // Set CSS styles for the DIV containing the control
            // Setting padding to 5 px will offset the control
            // from the edge of the map.
            controlDiv.style.padding = '1em';
            // Set CSS for the control border.
            var controlUI = document.createElement('div');
            controlUI.style.backgroundColor = 'rgba(255,255,255,0.7)';
            //controlUI.style.color = 'white';
            controlUI.style.borderStyle = 'solid';
            controlUI.style.borderWidth = '0px';
            controlUI.style.cursor = 'pointer';
            controlUI.style.textAlign = 'center';
            controlUI.style.borderRadius = '6px';
            controlUI.title = 'Click to hide.';
            controlDiv.appendChild(controlUI);
            // Set CSS for the control interior.
            var controlText = document.createElement('div');
            controlText.style.fontFamily = '"Helvetica Neue",Helvetica,Arial,sans-serif';
            controlText.style.fontSize = '12px';
            controlText.style.color = '#333';
            controlText.style.paddingLeft = '.5em';
            controlText.style.paddingRight = '.5em';
            controlText.style.paddingTop = '.3em';
            controlText.style.paddingBottom = '.3em';
            controlText.innerHTML = '
Free
';
            controlUI.appendChild(controlText);
            // Setup the click event listeners.
            google.maps.event.addDomListener(controlUI, 'click', function () {
                Map.Map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].clear();
            });
        };

        this.setMarkersByProjectType = function (project_type_to_display) {
            if (project_type_to_display == 'all') {
                $('.panel-default').css("display", "block");
            } else {
                $('.panel-default').css("display", "none");
                $('.' + project_type_to_display + '-panel').css("display", "block");
            }

            for (var i in this.Events) {

                var ptype = this.Events[i].data['3. Project type'];

                if ( project_type_to_display == 'all' || ((typeof project_type_info[(ptype)] !== 'undefined') && (project_type_info[(ptype)].id == project_type_to_display))) {
                    if ((typeof project_type_info[(ptype)] === 'undefined')) {
                        ptype = 'Other';
                    }
                    this.Events[i].marker.setIcon(project_type_info[(ptype)].pin_url);
                } else {
                    this.Events[i].marker.setIcon('img/grey-transparent.png');
                }

            }
        };
    };
    return constructor;
})(jQuery);
<|endoftext|>


<commit_before>const settings = {  /* "name in local storage": "form input parameter" */
  "backgroundColor":     "background",
  "handColor":           "hands",
  "hourColor":           "hours",
  "innerColor":          "inner",
  "minuteColor":         "minutes",
  "lowBatteryLevel":     "battlvl",
  "batteryColor":        "battcol",
  "bluetoothColor":      "bluetooth",
  "bluetoothVibration":  "vibrate",
  "textColor":           "textcol",
  "textFormat":          "textfmt",
};

function encodeStored(names) {
  var first = true;
  var result = "";
  for (var key in names) {
    var value = localStorage.getItem(key);
    if (value != null) {
      result = result + (first ? "?" : "&") + names[key] + "=" + encodeURIComponent(value);
      first = false;
    }
  }
  return result;
}

Pebble.addEventListener("ready", function() {
  console.log("Classic-Lite PebbleKit JS ready!");
});

Pebble.addEventListener("showConfiguration", function() {
/* TODO: switch to release version:
  Pebble.openURL("https://cdn.rawgit.com/faelys/classic-lite/v1.0/config.html");
*/
  Pebble.openURL("https://rawgit.com/faelys/classic-lite/trunk/config.html" + encodeStored(settings));
});

Pebble.addEventListener("webviewclosed", function(e) {
  var configData = JSON.parse(decodeURIComponent(e.response));

  for (var key in settings) {
    localStorage.setItem(key, configData[key]);
  }

  var dict = {
    1: parseInt(configData["backgroundColor"]),
    2: parseInt(configData["batteryColor"]),
    3: parseInt(configData["bluetoothColor"]),
    4: parseInt(configData["handColor"]),
    5: parseInt(configData["hourColor"]),
    6: parseInt(configData["innerColor"]),
    7: parseInt(configData["minuteColor"]),
    8: parseInt(configData["textColor"]),
    11: configData["textFormat"],
    12: parseInt(configData["bluetoothVibration"]),
    13: parseInt(configData["lowBatteryLevel"]),
  };

  Pebble.sendAppMessage(dict, function() {
    console.log("Send successful: " + JSON.stringify(dict));
  }, function() {
    console.log("Send failed!");
  });
});
<commit_msg>Prepare `pebble-js-app.js` for release<commit_after>/*
 * Copyright (c) 2015, Natacha Porté
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

const settings = {  /* "name in local storage": "form input parameter" */
  "backgroundColor":     "background",
  "handColor":           "hands",
  "hourColor":           "hours",
  "innerColor":          "inner",
  "minuteColor":         "minutes",
  "lowBatteryLevel":     "battlvl",
  "batteryColor":        "battcol",
  "bluetoothColor":      "bluetooth",
  "bluetoothVibration":  "vibrate",
  "textColor":           "textcol",
  "textFormat":          "textfmt",
};

function encodeStored(names) {
  var first = true;
  var result = "";
  for (var key in names) {
    var value = localStorage.getItem(key);
    if (value != null) {
      result = result + (first ? "?" : "&") + names[key] + "=" + encodeURIComponent(value);
      first = false;
    }
  }
  return result;
}

Pebble.addEventListener("ready", function() {
  console.log("Classic-Lite PebbleKit JS ready!");
});

Pebble.addEventListener("showConfiguration", function() {
  Pebble.openURL("https://cdn.rawgit.com/faelys/classic-lite/v1.0/config.html" + encodeStored(settings));
});

Pebble.addEventListener("webviewclosed", function(e) {
  var configData = JSON.parse(decodeURIComponent(e.response));

  for (var key in settings) {
    localStorage.setItem(key, configData[key]);
  }

  var dict = {
    1: parseInt(configData["backgroundColor"]),
    2: parseInt(configData["batteryColor"]),
    3: parseInt(configData["bluetoothColor"]),
    4: parseInt(configData["handColor"]),
    5: parseInt(configData["hourColor"]),
    6: parseInt(configData["innerColor"]),
    7: parseInt(configData["minuteColor"]),
    8: parseInt(configData["textColor"]),
    11: configData["textFormat"],
    12: parseInt(configData["bluetoothVibration"]),
    13: parseInt(configData["lowBatteryLevel"]),
  };

  Pebble.sendAppMessage(dict, function() {
    console.log("Send successful: " + JSON.stringify(dict));
  }, function() {
    console.log("Send failed!");
  });
});
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import h from 'react-hyperscript'
import anime from 'animejs'

import Animate from 'reusableComponents/Animate'

import styles from './tooltip.css'

export default class ToolTip extends Component {
  state = {
    visible: false
  }

  animeSettings = {
    duration: 225
  }

  handleHoverIn = () => this.setState({ visible: true })

  handleHoverOut = () => this.setState({ visible: false })

  // to handle touch devices
  handleClick = () => this.setState({ visible: !this.state.visible })

  handleKeyDown = e => {
    const keycode = e.which || e.keyCode
    if (keycode === 13) this.setState({ visible: !this.state.visible })
  }

  onEnter = (el, cb) => {
    const { scrollWidth: elWidth, scrollHeight: elHeight } = el
    const {
      width: visibleTextWidth,
      top: visibleTextTop,
      left: visibleTextLeft,
      right: visibleTextRight,
      height: visibleTextHeight
    } = this.visibleText.getBoundingClientRect()
    const distanceFromBottom =
      window.innerHeight - (visibleTextTop + visibleTextHeight)
    const distanceFromRight =
      window.innerWidth - (visibleTextLeft + visibleTextWidth)

    const computeMarginLeft = () => {
      if (
        (elWidth - visibleTextWidth) / 2 > visibleTextLeft ||
        elWidth > distanceFromRight
      ) { return '0px' }
      return `${-(elWidth - visibleTextWidth) / 2}px`
    }

    const computeTop = () => {
      if (visibleTextTop > distanceFromBottom) { return `${visibleTextTop - elHeight}px` }
      return `${visibleTextTop + visibleTextHeight}px`
    }

    const computeLeft = () => {
      if (elWidth > distanceFromRight) return `${visibleTextRight - elWidth}px`
      return `${visibleTextLeft}px`
    }

    const computeTransformOrigin = () => {
      if (visibleTextTop > distanceFromBottom) {
        if (elWidth > distanceFromRight) return 'right bottom 0'
        if ((elWidth - visibleTextWidth) / 2 > visibleTextLeft) { return 'left bottom 0' }
        return 'center bottom 0'
      } else {
        if (elWidth > distanceFromRight) return 'right top 0'
        if ((elWidth - visibleTextWidth) / 2 > visibleTextLeft) { return 'left top 0' }
        return 'center top 0'
      }
    }

    el.style.top = computeTop()
    el.style.left = computeLeft()
    el.style.marginLeft = computeMarginLeft()
    el.style.transformOrigin = computeTransformOrigin()
    anime({
      targets: el,
      scale: {
        ...this.animeSettings,
        easing: [0.175, 0.885, 0.32, 1.275],
        value: 1
      },
      complete: cb
    })
  }

  onLeave = (el, cb) => {
    anime({
      targets: el,
      scale: { ...this.animeSettings, easing: 'easeInOutQuad', value: 0 },
      complete: () => {
        el.style.top = 0
        el.style.left = 0
        el.style.marginLeft = 0
        return cb()
      }
    })
  }

  renderToolTips() {
    const { onEnter, onLeave, state: { visible }, props } = this

    return h(
      Animate,
      {
        trigger: visible,
        onEnter,
        onLeave,
        customClassName: styles.hiddenText,
        customStyle: { transform: 'scale(0)' }
      },
      h('span', props.hiddenText)
    )
  }

  render() {
    return h(
      'span',
      {
        onClick: this.handleClick,
        onMouseEnter: this.handleHoverIn,
        onMouseLeave: this.handleHoverOut,
        onKeyDown: this.handleKeyDown,
        className: styles.root,
        tabIndex: '0'
      },
      [
        h(
          'span',
          {
            ref: visibleText => {
              this.visibleText = visibleText
            },
            className: styles.text
          },
          this.props.children
        ),
        this.renderToolTips()
      ]
    )
  }

  static propTypes = {
    hiddenText: React.PropTypes.string
  }

  static defaultProps = {
    hiddenText: 'add some text'
  }
}
<commit_msg>clean up code<commit_after>import React, { Component } from 'react'
import h from 'react-hyperscript'
import anime from 'animejs'

import Animate from 'reusableComponents/Animate'

import styles from './tooltip.css'

export default class ToolTip extends Component {
  state = {
    visible: false
  }

  animeSettings = {
    duration: 225
  }

  handleHoverIn = () => this.setState({ visible: true })

  handleHoverOut = () => this.setState({ visible: false })

  // to handle touch devices
  handleClick = () => this.setState({ visible: !this.state.visible })

  handleKeyDown = e => {
    const keycode = e.which || e.keyCode
    if (keycode === 13) this.setState({ visible: !this.state.visible })
  }

  onEnter = (el, cb) => {
    const { scrollWidth: elWidth, scrollHeight: elHeight } = el
    const {
      width: visibleTextWidth,
      top: visibleTextTop,
      left: visibleTextLeft,
      right: visibleTextRight,
      height: visibleTextHeight
    } = this.visibleText.getBoundingClientRect()
    const distanceFromBottom =
      window.innerHeight - (visibleTextTop + visibleTextHeight)
    const distanceFromRight =
      window.innerWidth - (visibleTextLeft + visibleTextWidth)

    const computeMarginLeft = () => {
      if (
        (elWidth - visibleTextWidth) / 2 > visibleTextLeft ||
        elWidth > distanceFromRight
      ) {
        return '0px'
      }
      return `${-(elWidth - visibleTextWidth) / 2}px`
    }

    const computeTop = () => {
      if (visibleTextTop > distanceFromBottom) {
        return `${visibleTextTop - elHeight}px`
      }
      return `${visibleTextTop + visibleTextHeight}px`
    }

    const computeLeft = () => {
      if (elWidth > distanceFromRight) return `${visibleTextRight - elWidth}px`
      return `${visibleTextLeft}px`
    }

    const computeTransformOrigin = () => {
      if (visibleTextTop > distanceFromBottom) {
        if (elWidth > distanceFromRight) return 'right bottom 0'
        if ((elWidth - visibleTextWidth) / 2 > visibleTextLeft) {
          return 'left bottom 0'
        }
        return 'center bottom 0'
      } else {
        if (elWidth > distanceFromRight) return 'right top 0'
        if ((elWidth - visibleTextWidth) / 2 > visibleTextLeft) {
          return 'left top 0'
        }
        return 'center top 0'
      }
    }

    el.style.top = computeTop()
    el.style.left = computeLeft()
    el.style.marginLeft = computeMarginLeft()
    el.style.transformOrigin = computeTransformOrigin()
    anime({
      targets: el,
      scale: {
        ...this.animeSettings,
        easing: [0.175, 0.885, 0.32, 1.275],
        value: 1
      },
      complete: cb
    })
  }

  onLeave = (el, cb) => {
    anime({
      targets: el,
      scale: { ...this.animeSettings, easing: 'easeInOutQuad', value: 0 },
      complete: () => {
        el.style.top = 0
        el.style.left = 0
        el.style.marginLeft = 0
        return cb()
      }
    })
  }

  renderToolTips() {
    const { onEnter, onLeave, state: { visible }, props } = this

    return h(
      Animate,
      {
        trigger: visible,
        onEnter,
        onLeave,
        customClassName: styles.hiddenText,
        customStyle: { transform: 'scale(0)' }
      },
      h('span', props.hiddenText)
    )
  }

  render() {
    return h(
      'span',
      {
        onClick: this.handleClick,
        onMouseEnter: this.handleHoverIn,
        onMouseLeave: this.handleHoverOut,
        onKeyDown: this.handleKeyDown,
        className: styles.root,
        tabIndex: '0'
      },
      [
        h(
          'span',
          {
            ref: visibleText => {
              this.visibleText = visibleText
            },
            className: styles.text
          },
          this.props.children
        ),
        this.renderToolTips()
      ]
    )
  }

  static propTypes = {
    hiddenText: React.PropTypes.string
  }

  static defaultProps = {
    hiddenText: 'add some text'
  }
}
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import { StyleSheet } from 'react-native';
import PopupDialog, { Dialog, DialogTitle, DialogButton } from 'react-native-popup-dialog';

const propTypes = {
  ...Dialog.propTypes,
  ...DialogTitle.propTypes,
};

const defaultProps = {
  animationDuration: 200,
  closeOnTouchOutside: true,
  minWidth: 0.8,
  maxWidth: 0.8,
  minHeight: 0.1,
  maxHeight: 0.4,
};

class DialogComponent extends Component {
  static propTypes = propTypes;
  static defaultProps = defaultProps;

  constructor(props) {
    super(props);

    this.openDialog = this.openDialog.bind(this);
    this.closeDialog = this.closeDialog.bind(this);
  }

  openDialog(onOpened) {
    this.popupDialog.openDialog(onOpened);
  }

  closeDialog(onClosed) {
    this.popupDialog.closeDialog(onClosed);
  }

  render() {
    let title;

    if (this.props.title) {
      title = (
        <DialogTitle
          title={this.props.title}
          titleStyle={this.props.titleStyle}
          titleTextStyle={this.props.titleTextStyle}
          titleAlign={this.props.titleAlign}
          haveTitleBar={false}
        />
      );
    }

    return (
      <PopupDialog
        dialogStyle={styles.dialog}
        ref={popupDialog => { this.popupDialog = popupDialog; }}
        {...this.props}
      >
        {title}
        {this.props.children}
      </PopupDialog>
    );
  }
}

const styles = StyleSheet.create({
  dialog: {
    elevation: 5,
    minHeight: 96,
    borderRadius: 0,
    opacity: 0,
    shadowColor: 'black',
    shadowOpacity: 0.2,
    shadowRadius: 5,
    shadowOffset: {
      width: 1,
      height: 2,
    },
  },
});

export default DialogComponent;
<commit_msg>update DialogComponent.js<commit_after>// @flow

import React, { Component, PropTypes } from 'react';
import { View, StyleSheet, Dimensions } from 'react-native';
import PopupDialog, { Dialog } from 'react-native-popup-dialog';

import DialogTitle from './components/DialogTitle';

const { width: screenWidth, height: screenHeight } = Dimensions.get('window');

const propTypes = {
  ...Dialog.propTypes,
  ...DialogTitle.propTypes,
  dialogContainerStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
};

const defaultProps = {
  animationDuration: 200,
  closeOnTouchOutside: true,
  width: screenWidth,
  height: null,
};

class DialogComponent extends Component {
  static propTypes = propTypes;
  static defaultProps = defaultProps;

  constructor(props) {
    super(props);

    this.openDialog = this.openDialog.bind(this);
    this.closeDialog = this.closeDialog.bind(this);
  }

  openDialog(onOpened) {
    this.popupDialog.openDialog(onOpened);
  }

  closeDialog(onClosed) {
    this.popupDialog.closeDialog(onClosed);
  }

  render() {
    let { title, children } = this.props;

    if (title && typeof title !== 'function') {
      title = (
        <DialogTitle {...this.props} />
      );
    }

    if (title && title.type && title.type.name === 'DialogTitle') {
      if (children && children.type.name === 'DialogContent') {
        const props = {
          ...children.props,
          contentStyle: [{ paddingTop: 0 }, children.props.contentStyle],
        };

        const content = children.props.children;

        children = React.cloneElement(
          children,
          props,
          content,
        );
      }
    }

    return (
      <PopupDialog
        ref={popupDialog => { this.popupDialog = popupDialog; }}
        width={this.props.width}
        height={this.props.height}
        dialogAnimation={this.props.dialogAnimation}
        dialogStyle={[styles.dialog, this.props.dialogStyle]}
        animationDuration={this.props.animationDuration}
        overlayPointerEvents={this.props.overlayPointerEvents}
        overlayBackgroundColor={this.props.overlayBackgroundColor}
        overlayOpacity={this.props.overlayOpacity}
        closeOnTouchOutside={this.props.closeOnTouchOutside}
        haveOverlay={this.props.haveOverlay}
        open={this.props.open}
        onOpened={this.props.onOpened}
        onClosed={this.props.onClosed}
        actions={this.props.actions}
      >
        {title}
        {children}
      </PopupDialog>
    );
  }
}

const styles = StyleSheet.create({
  dialog: {
    elevation: 5,
    minHeight: 96,
    borderRadius: 0,
    opacity: 0,
    shadowColor: 'black',
    shadowOpacity: 0.2,
    shadowRadius: 5,
    shadowOffset: {
      width: 1,
      height: 2,
    },
  },
  dialogContainer: {
    flex: 1,
  },
});

export default DialogComponent;
<|endoftext|>


<commit_before>// Define appearance of geometry shapes

var Color = {
  C1: [206, 53, 0],     // Aviation Orange
  C2: [9, 86, 141],     // Blue
  C3: [255, 187, 0],    // Lemon Yellow
  C4: [69, 119, 37],    // Oxygen Tank Green
  getClr: function(_idx) {
    return Color['C' + _idx];
  },
  length: function() {
    return Object.keys(Color).length - 2;
  },
}
<commit_msg>add more color<commit_after>// Define appearance of geometry shapes

var Color = {
  C1: [174, 218, 75],    // green
  C2: [12, 144, 209],    // Preface Isolation
  C3: [206, 53, 0],      // Aviation Orange
  C4: [198, 12, 209],    // Oxygen Tank Green
  C5: [106, 12, 209],    // ghostwriter, primary
  C6: [24, 208, 175],    // mintasia
  getClr: function(_idx) {
    return Color['C' + _idx];
  },
  length: function() {
    return Object.keys(Color).length - 2;
  },
}
<|endoftext|>


<commit_before>/*globals require*/

/**
 * node genprojectjson.js stat.json [projectNameInDataBase]
 *
 * With optional projectNameInDataBase argument the script will import the project into the database.
 *
 * This takes a report file of a desktop GME instance model and creates a webgme project file.
 * @author pmeijer / https://github.com/pmeijer
 */
var Chance = require('chance'),
    chance = new Chance(),
    fs = require('fs'),
    importProject = require('../../src/bin/import_project'),
    path = require('path');

function generateProject (stat, options) {
    var project = {
        bases: {},
        root: {
            path: '',
            guid: null
        },
        relids: {},
        containment: {},
        nodes: {},
        metaSheets: {}
    },
        META_ASPECT_SET = 'MetaAspectSet_' + chance.guid(),
        metaSheetCounter = 1,
        fcoNode,
        statModel = stat.Model,
        opts = options || {},
        nbrOfPointerTypes = opts.nbrOfPointerTypes || 10,
        pathToModelNode = {},
        guidToMetaNode = {},
        nbrOfPointers = statModel.NumberOfReferences + statModel.NumberOfConnections * 2,
        relIdCnt = 2;

    project.root.guid = chance.guid();
    project.containment = statModel.ContainmentTree;

    fcoNode = createRootNodeAndFCO(project.root.guid);
    addNode(stat.MetaModel.RootGUID, project.root.guid);
    guidToMetaNode[stat.MetaModel.RootGUID].attributes.name = 'META_' + stat.ParadigmName;
    traverseMetaTree(project.containment[stat.MetaModel.RootGUID], stat.MetaModel.RootGUID);
    traverseTree(project.containment, project.root.guid, '');
    project.containment[fcoNode._guid] = {};
    createPointers();

    function NodeObj(guid, baseGuid, parent) {
        var cnt = 0;
        this._guid = guid;
        this.attributes = {
            name: chance.last()
        }
        if (baseGuid) {
            this.base = baseGuid;
            this.meta = {};
            do {
                cnt += 1;
                if (guidToMetaNode[baseGuid]) {
                    this.meta.attributes = JSON.parse(JSON.stringify(guidToMetaNode[baseGuid].meta.attributes));
                    break;
                }
                baseGuid = stat.Model.InheritanceTree[baseGuid];
                if (cnt > 1000) {
                    console.error('Caught in a loop!');
                    break;
                }
            } while (true);
        } else {
            this.base = null;
            this.meta = {
                attributes: {
                    name: {
                        type: 'string'
                    }
                }
            };
        }
        this.parent = parent ? parent._guid : null;
        this.pointers = {
            base: this.base
        }
        this.registry = {
            position: {
                x: chance.integer({ min: 0, max: 1000 }),
                y: chance.integer({ min: 0, max: 1000 })
            }
        }
        this.sets = {};
    }

    function createRootNodeAndFCO(rootGuid) {
        var rootNode = new NodeObj(rootGuid),
            fcoGuid = chance.guid(),
            fcoNode = new NodeObj(fcoGuid, null, rootNode),
            metaAspectSet = {
                attributes: {},
                guid: fcoGuid,
                registry: {
                    position: {
                        x: 100,
                        y: 100
                    }
                }
            },
            metaChildren = {
                minItems: [
                    -1
                ],
                maxItems: [
                    -1
                ],
                items: [
                    fcoGuid
                ]
            };
        // Build the root node
        rootNode.attributes.name = 'ROOT';
        rootNode.meta.children = metaChildren;
        rootNode.registry = {
            MetaSheets: [{
                SetID: META_ASPECT_SET,
                order: 0,
                title: 'META'
            }],
            ProjectRegistry: {
                FCO_ID: '/1',
            },
            usedAddOns: 'ConstraintAddOn',
            validPlugins: '',
        };
        rootNode.sets = {
            MetaAspectSet: [metaAspectSet]
        }
        rootNode.sets[META_ASPECT_SET] = [metaAspectSet];
        // Build the fco node
        fcoNode.attributes.name = 'FCO';
        fcoNode.meta.children = metaChildren;
        fcoNode.registry.DisplayFormat = '$name';
        fcoNode.registry.PortSVGIcon = '';
        fcoNode.registry.SVGIcon = '';
        fcoNode.registry.decorator = '';
        fcoNode.registry.isAbstract = false;
        fcoNode.registry.isPort = false;

        // add to nodes and relids.
        project.nodes[rootGuid] = rootNode;
        project.nodes[fcoGuid] = fcoNode;
        project.relids[rootGuid] = null;
        project.relids[fcoGuid] = '1';
        guidToMetaNode[fcoGuid] = fcoNode;
        return fcoNode;
    };

    function traverseMetaTree(root, rootguid) {
        var id,
            path;
        for (id in root) {
            if (root.hasOwnProperty(id)) {
                path = addNode(id, rootguid);
                traverseMetaTree(root[id], id);
            }
        }
    }

    function traverseTree(root, rootguid, rootPath) {
        var id,
            path;
        for (id in root) {
            if (root.hasOwnProperty(id) && guidToMetaNode.hasOwnProperty(id) === false) {
                path = addNode(id, rootguid, rootPath);
                traverseTree(root[id], id, path);
            }
        }
    }

    function addNode(guid, parentGuid, parentPath) {
        var node,
            relId,
            path,
            isMeta,
            base;
        if (statModel.InheritanceTree[guid]) {
            isMeta = false;
            base = statModel.InheritanceTree[guid];
        } else {
            isMeta = true;
            base = fcoNode._guid;
        }

        node = new NodeObj(guid, base, project.nodes[parentGuid]);
        project.nodes[guid] = node;
        relId = relIdCnt.toString();
        project.relids[guid] = relId;
        if (isMeta) {
            guidToMetaNode[guid] = node;
            addToMetaAspectSet(guid);
        } else {
            path = parentPath + '/' + relId;
            pathToModelNode[path] = node;
        }
        relIdCnt += 1;
        return path;
    };

    function addToMetaAspectSet(guid) {
        var rootNode = project.nodes[project.root.guid],
            metaAspectSet = {
                attributes: {},
                guid: guid,
                registry: {
                    position: {
                        x: chance.integer({ min: 0, max: 1000 }),
                        y: chance.integer({ min: 0, max: 1000 })
                    }
                }
            };

        rootNode.sets.MetaAspectSet.push(metaAspectSet);
        rootNode.sets[META_ASPECT_SET].push(metaAspectSet);

        metaSheetCounter += 1;
        if (metaSheetCounter % 30 == 0) {
            META_ASPECT_SET = 'MetaAspectSet_' + chance.guid();
            rootNode.registry.MetaSheets.push({
                SetID: META_ASPECT_SET,
                order: metaSheetCounter/30,
                title: chance.first()
            });
            rootNode.sets[META_ASPECT_SET] = [];
        }
    }
    function createPointers() {
        var pointerTypes = [],
            paths = Object.keys(pathToModelNode),
            index,
            typeIndex,
            targetPath,
            collision,
            whileCnt,
            i;
        for (i = 0; i < nbrOfPointerTypes; i += 1) {
            pointerTypes.push(chance.first());
        }
        console.log('Generated pointerTypes ', pointerTypes);
        for (i = 0; i < nbrOfPointers; i += 1) {
            index = i % paths.length;
            targetPath = paths[chance.integer({min:0, max: paths.length-1})];
            whileCnt = 0;
            do {
                whileCnt += 1;
                typeIndex = chance.integer({min:0, max: nbrOfPointerTypes-1});
                collision = setPointer(pathToModelNode[paths[index]], pointerTypes[typeIndex], targetPath);
                if (collision && whileCnt > 2 * nbrOfPointerTypes) {
                    console.error('Too many collisions, skipping pointer..');
                }
            }
            while (collision)
        }
    };

    function setPointer(node, name, targetPath) {
        var targetNode = pathToModelNode[targetPath];

        if (node.pointers[name]) {
            console.log('Collision of pointer', node._guid, name, targetPath);
            return true;
        }
        node.pointers[name] = targetNode._guid;

        //targetNode.collection = targetNode.collection || {};
        //targetNode.collection[name] = targetNode.collection[name] || [];
        //targetNode.collection[name].push(node._guid);
        return false;
    }

    return project;
};

if (require.main === module) {
    var inputFile = process.argv[2],
        baseName = path.basename(inputFile, '.json'),
        outName = path.join(process.cwd(), baseName + '_out.json'),
        projectName = process.argv[3];

    var proj = generateProject(JSON.parse(fs.readFileSync(inputFile, 'utf8')));
    if (projectName) {
        importProject.importProject(projectName, proj, null, function (err) {
            if (err) {
                console.error('Could not import project to database!, err', err);
            } else {
                console.log('Project successfully imported to ' + projectName);
            }
        })
    } else {
        console.log('Will write to', outName);
        fs.writeFile(outName, JSON.stringify(proj, function (key, value) {
            if (key === '_guid') {
                return undefined;
            }
            return value;
        }));
    }
}

module.exports.generateProject = generateProject;

<commit_msg>#121 expose mongosettings, generate output file next to input.<commit_after>/*globals require*/

/**
 * node genprojectjson.js stat.json [projectNameInDataBase] [mongoip] [mongoport] [mongodb]
 *
 * With optional projectNameInDataBase argument the script will import the project into the database.
 *
 * This takes a report file of a desktop GME instance model and creates a webgme project file.
 * @author pmeijer / https://github.com/pmeijer
 */
var Chance = require('chance'),
    chance = new Chance(),
    fs = require('fs'),
    importProject = require('../../src/bin/import_project'),
    path = require('path');

function generateProject (stat, options) {
    var project = {
        bases: {},
        root: {
            path: '',
            guid: null
        },
        relids: {},
        containment: {},
        nodes: {},
        metaSheets: {}
    },
        META_ASPECT_SET = 'MetaAspectSet_' + chance.guid(),
        metaSheetCounter = 1,
        fcoNode,
        statModel = stat.Model,
        opts = options || {},
        nbrOfPointerTypes = opts.nbrOfPointerTypes || 10,
        pathToModelNode = {},
        guidToMetaNode = {},
        nbrOfPointers = statModel.NumberOfReferences + statModel.NumberOfConnections * 2,
        relIdCnt = 2;

    project.root.guid = chance.guid();
    project.containment = statModel.ContainmentTree;

    fcoNode = createRootNodeAndFCO(project.root.guid);
    addNode(stat.MetaModel.RootGUID, project.root.guid);
    guidToMetaNode[stat.MetaModel.RootGUID].attributes.name = 'META_' + stat.ParadigmName;
    traverseMetaTree(project.containment[stat.MetaModel.RootGUID], stat.MetaModel.RootGUID);
    traverseTree(project.containment, project.root.guid, '');
    project.containment[fcoNode._guid] = {};
    createPointers();

    function NodeObj(guid, baseGuid, parent) {
        var cnt = 0;
        this._guid = guid;
        this.attributes = {
            name: chance.last()
        }
        if (baseGuid) {
            this.base = baseGuid;
            this.meta = {};
            do {
                cnt += 1;
                if (guidToMetaNode[baseGuid]) {
                    this.meta.attributes = JSON.parse(JSON.stringify(guidToMetaNode[baseGuid].meta.attributes));
                    break;
                }
                baseGuid = stat.Model.InheritanceTree[baseGuid];
                if (cnt > 1000) {
                    console.error('Caught in a loop!');
                    break;
                }
            } while (true);
        } else {
            this.base = null;
            this.meta = {
                attributes: {
                    name: {
                        type: 'string'
                    }
                }
            };
        }
        this.parent = parent ? parent._guid : null;
        this.pointers = {
            base: this.base
        }
        this.registry = {
            position: {
                x: chance.integer({ min: 0, max: 1000 }),
                y: chance.integer({ min: 0, max: 1000 })
            }
        }
        this.sets = {};
    }

    function createRootNodeAndFCO(rootGuid) {
        var rootNode = new NodeObj(rootGuid),
            fcoGuid = chance.guid(),
            fcoNode = new NodeObj(fcoGuid, null, rootNode),
            metaAspectSet = {
                attributes: {},
                guid: fcoGuid,
                registry: {
                    position: {
                        x: 100,
                        y: 100
                    }
                }
            },
            metaChildren = {
                minItems: [
                    -1
                ],
                maxItems: [
                    -1
                ],
                items: [
                    fcoGuid
                ]
            };
        // Build the root node
        rootNode.attributes.name = 'ROOT';
        rootNode.meta.children = metaChildren;
        rootNode.registry = {
            MetaSheets: [{
                SetID: META_ASPECT_SET,
                order: 0,
                title: 'META'
            }],
            ProjectRegistry: {
                FCO_ID: '/1',
            },
            usedAddOns: 'ConstraintAddOn',
            validPlugins: '',
        };
        rootNode.sets = {
            MetaAspectSet: [metaAspectSet]
        }
        rootNode.sets[META_ASPECT_SET] = [metaAspectSet];
        // Build the fco node
        fcoNode.attributes.name = 'FCO';
        fcoNode.meta.children = metaChildren;
        fcoNode.registry.DisplayFormat = '$name';
        fcoNode.registry.PortSVGIcon = '';
        fcoNode.registry.SVGIcon = '';
        fcoNode.registry.decorator = '';
        fcoNode.registry.isAbstract = false;
        fcoNode.registry.isPort = false;

        // add to nodes and relids.
        project.nodes[rootGuid] = rootNode;
        project.nodes[fcoGuid] = fcoNode;
        project.relids[rootGuid] = null;
        project.relids[fcoGuid] = '1';
        guidToMetaNode[fcoGuid] = fcoNode;
        return fcoNode;
    };

    function traverseMetaTree(root, rootguid) {
        var id,
            path;
        for (id in root) {
            if (root.hasOwnProperty(id)) {
                path = addNode(id, rootguid);
                traverseMetaTree(root[id], id);
            }
        }
    }

    function traverseTree(root, rootguid, rootPath) {
        var id,
            path;
        for (id in root) {
            if (root.hasOwnProperty(id) && guidToMetaNode.hasOwnProperty(id) === false) {
                path = addNode(id, rootguid, rootPath);
                traverseTree(root[id], id, path);
            }
        }
    }

    function addNode(guid, parentGuid, parentPath) {
        var node,
            relId,
            path,
            isMeta,
            base;
        if (statModel.InheritanceTree[guid]) {
            isMeta = false;
            base = statModel.InheritanceTree[guid];
        } else {
            isMeta = true;
            base = fcoNode._guid;
        }

        node = new NodeObj(guid, base, project.nodes[parentGuid]);
        project.nodes[guid] = node;
        relId = relIdCnt.toString();
        project.relids[guid] = relId;
        if (isMeta) {
            guidToMetaNode[guid] = node;
            addToMetaAspectSet(guid);
        } else {
            path = parentPath + '/' + relId;
            pathToModelNode[path] = node;
        }
        relIdCnt += 1;
        return path;
    };

    function addToMetaAspectSet(guid) {
        var rootNode = project.nodes[project.root.guid],
            metaAspectSet = {
                attributes: {},
                guid: guid,
                registry: {
                    position: {
                        x: chance.integer({ min: 0, max: 1000 }),
                        y: chance.integer({ min: 0, max: 1000 })
                    }
                }
            };

        rootNode.sets.MetaAspectSet.push(metaAspectSet);
        rootNode.sets[META_ASPECT_SET].push(metaAspectSet);

        metaSheetCounter += 1;
        if (metaSheetCounter % 30 == 0) {
            META_ASPECT_SET = 'MetaAspectSet_' + chance.guid();
            rootNode.registry.MetaSheets.push({
                SetID: META_ASPECT_SET,
                order: metaSheetCounter/30,
                title: chance.first()
            });
            rootNode.sets[META_ASPECT_SET] = [];
        }
    }
    function createPointers() {
        var pointerTypes = [],
            paths = Object.keys(pathToModelNode),
            index,
            typeIndex,
            targetPath,
            collision,
            whileCnt,
            i;
        for (i = 0; i < nbrOfPointerTypes; i += 1) {
            pointerTypes.push(chance.first());
        }
        console.log('Generated pointerTypes ', pointerTypes);
        for (i = 0; i < nbrOfPointers; i += 1) {
            index = i % paths.length;
            targetPath = paths[chance.integer({min:0, max: paths.length-1})];
            whileCnt = 0;
            do {
                whileCnt += 1;
                typeIndex = chance.integer({min:0, max: nbrOfPointerTypes-1});
                collision = setPointer(pathToModelNode[paths[index]], pointerTypes[typeIndex], targetPath);
                if (collision && whileCnt > 2 * nbrOfPointerTypes) {
                    console.error('Too many collisions, skipping pointer..');
                }
            }
            while (collision)
        }
    };

    function setPointer(node, name, targetPath) {
        var targetNode = pathToModelNode[targetPath];

        if (node.pointers[name]) {
            console.log('Collision of pointer', node._guid, name, targetPath);
            return true;
        }
        node.pointers[name] = targetNode._guid;

        //targetNode.collection = targetNode.collection || {};
        //targetNode.collection[name] = targetNode.collection[name] || [];
        //targetNode.collection[name].push(node._guid);
        return false;
    }

    return project;
};

if (require.main === module) {
    var inputFile = process.argv[2],
        baseName = path.basename(inputFile, '.json'),
        outName = path.join(path.dirname(inputFile), baseName + '_out.json'),
        projectName = process.argv[3],
        mongoOpts = {
            mongoip: process.argv[4] || '127.0.0.1',
            mongoport: process.argv[5] || 27017,
            mongodb: process.argv[6] || 'multi'
        };

    var proj = generateProject(JSON.parse(fs.readFileSync(inputFile, 'utf8')));
    if (projectName) {
        importProject.importProject(projectName, proj, mongoOpts, function (err) {
            if (err) {
                console.error('Could not import project to database!, err', err);
            } else {
                console.log('Project successfully imported to ' + projectName);
            }
        })
    } else {
        console.log('Will write to', outName);
        fs.writeFile(outName, JSON.stringify(proj, function (key, value) {
            if (key === '_guid') {
                return undefined;
            }
            return value;
        }));
    }
}

module.exports.generateProject = generateProject;

<|endoftext|>


<commit_before>'use strict'

const stream = require('readable-stream')
const isStream = require('isstream')
const chalk = require('chalk')
const globby = require('globby')
const co = require('co')

const { tab } = require('./utils.js')
const { File } = require('./types.js')

class Duplex extends stream.Duplex {
  constructor(opts) {
    super(opts)
  }

  _read(size) {
    console.log('reading')
  }

  _write(chunk, encoding, callback) {
    console.log('writing: ' + chunk.toString())

    this.push(chunk)
    callback()
  }
}

// Would use https://www.npmjs.com/package/stream-from-promise but may
// need to handle special resolve values (e.g. promise resolves to a stream) later
class ReadableFromPromise extends stream.Readable {
  constructor(promise, opts) {
    super(opts)

    this._promise = promise
  }

  _read(size) {
    this._promise
      .then((data) => {
        this.push(data)
        this.push(null)
      })
      .catch((err) => {
        this.emit('error', err)
        this.push(null)
      })
  }
}

class ReadableFromCallback extends stream.Readable {
  constructor(action, opts) {
    super(opts)

    this._action = action
  }

  _read(size) {
    this._action((err, data) => {
      if (err !== null) {
        this.emit('error', err)
        this.push(null)
      } else {
        this.push(data)
        this.push(null)
      }
    })
  }
}

/**
 * The Task class.
 * @param  {Object} props         object with input and output
 * @param  {function} actionCreator function to produce an actionCreator
 * @return {stream}               stream to be orchestrated
 */
const task = (props, actionCreator) => () => {
  // TODO check if actionCreator is a function
  if (props === null) {
    console.log('Got null props')
    props = {
      input: null,
      name: 'noname'
    }
  }

  // TODO handle unnamed task
  const { input, name } = props
  let resolvedInput = input
  // TODO task lifecycle
  // 1. preparing
  console.log(`Running task ${chalk.blue(name)}`)
  // 2. resolving input
  // TODO
  // 2. use values passed in from last Task
  console.log(tab(1) + 'Resolving input')
  // 1. resolve props OR
  if (input instanceof File) {
    try {
      const globbyData = globby.sync(input.value)
      resolvedInput = { input: globbyData[0] }
    } catch(e) {
      console.error(e)
    }
    console.log(tab(2) + 'input: ' + resolvedInput.input + ' from ' + input.value)
  }
  // 3. creating
  // TODO use input/output, resolved promise, callback to determine stream type.
  // Or just always be duplex.
  let stream
  // const stream = new Readable()

  // Create the action
  // TODO handle actual callbacks, in which case we cant call this yet
  const resolvedProps = Object.assign(props, resolvedInput)
  console.log(resolvedProps)
  const action = actionCreator(resolvedProps)

  // Get its type: can be stream, promise, function
  const actionType = (() => {
    if (action instanceof Promise) {
      return 'promise'
    } else if (typeof(action) === 'function') {
      // assume action returns function of signature fn(err, data)
      return 'curried-callback'
    } else if (isStream(action)) {
      return 'stream'
    } else {
      return 'unkown'
    }
  })()

  switch(actionType) {
    case 'promise':
      stream = new ReadableFromPromise(action)
      console.log(tab(1) + 'Creating a Readable from promise')
      break
    case 'curried-callback':
      stream = new ReadableFromCallback(action)
      break
    case 'stream':
      stream = action
      console.log(tab(1) + 'Creating a stream from stream')
      break
    default:
      console.log('Bad action type')
  }

  // 4. running
  // 5. resolving output
  // 6. ending, passing on output

  // console.log(stream)

  return stream
}

module.exports = task
<commit_msg>Handles string as input<commit_after>'use strict'

const stream = require('readable-stream')
const isStream = require('isstream')
const chalk = require('chalk')
const globby = require('globby')
const co = require('co')

const { tab } = require('./utils.js')
const { File } = require('./types.js')

class Duplex extends stream.Duplex {
  constructor(opts) {
    super(opts)
  }

  _read(size) {
    console.log('reading')
  }

  _write(chunk, encoding, callback) {
    console.log('writing: ' + chunk.toString())

    this.push(chunk)
    callback()
  }
}

// Would use https://www.npmjs.com/package/stream-from-promise but may
// need to handle special resolve values (e.g. promise resolves to a stream) later
class ReadableFromPromise extends stream.Readable {
  constructor(promise, opts) {
    super(opts)

    this._promise = promise
  }

  _read(size) {
    this._promise
      .then((data) => {
        this.push(data)
        this.push(null)
      })
      .catch((err) => {
        this.emit('error', err)
        this.push(null)
      })
  }
}

class ReadableFromCallback extends stream.Readable {
  constructor(action, opts) {
    super(opts)

    this._action = action
  }

  _read(size) {
    this._action((err, data) => {
      if (err !== null) {
        this.emit('error', err)
        this.push(null)
      } else {
        this.push(data)
        this.push(null)
      }
    })
  }
}

/**
 * The Task class.
 * @param  {Object} props         object with input and output
 * @param  {function} actionCreator function to produce an actionCreator
 * @return {stream}               stream to be orchestrated
 */
const task = (props, actionCreator) => () => {
  // TODO check if actionCreator is a function
  if (props === null) {
    console.log('Got null props')
    props = {
      input: null,
      name: 'noname'
    }
  }

  // TODO handle unnamed task
  const { input, name } = props
  let resolvedInput = { input }
  // TODO task lifecycle
  // 1. preparing
  console.log(`Running task ${chalk.blue(name)}`)
  // 2. resolving input
  // TODO
  // 2. use values passed in from last Task
  console.log(tab(1) + 'Resolving input')
  // 1. resolve props OR
  if (input instanceof File) {
    try {
      const globbyData = globby.sync(input.value)
      resolvedInput = { input: globbyData[0] }
    } catch(e) {
      console.error(e)
    }
    console.log(tab(2) + 'input: ' + resolvedInput.input + ' from ' + input.value)
  } else if (typeof(input) === 'string') {
    console.log(tab(2) + 'input: ' + resolvedInput.input)
  }
  // 3. creating
  // TODO use input/output, resolved promise, callback to determine stream type.
  // Or just always be duplex.
  let stream
  // const stream = new Readable()

  // Create the action
  // TODO handle actual callbacks, in which case we cant call this yet
  const resolvedProps = Object.assign(props, resolvedInput)
  const action = actionCreator(resolvedProps)

  // Get its type: can be stream, promise, function
  const actionType = (() => {
    if (action instanceof Promise) {
      return 'promise'
    } else if (typeof(action) === 'function') {
      // assume action returns function of signature fn(err, data)
      return 'curried-callback'
    } else if (isStream(action)) {
      return 'stream'
    } else {
      return 'unkown'
    }
  })()

  switch(actionType) {
    case 'promise':
      stream = new ReadableFromPromise(action)
      console.log(tab(1) + 'Creating a Readable from promise')
      break
    case 'curried-callback':
      stream = new ReadableFromCallback(action)
      break
    case 'stream':
      stream = action
      console.log(tab(1) + 'Creating a stream from stream')
      break
    default:
      console.log('Bad action type')
  }

  // 4. running
  // 5. resolving output
  // 6. ending, passing on output

  // console.log(stream)

  return stream
}

module.exports = task
<|endoftext|>