<commit_before>if (!window.emp3) {
  emp3 = {};
}
if (!window.emp3.api) {
  emp3.api = {};
}
/**
 * @namespace
 * @memberof emp3.api
 * @desc Contains global settings properties and utility functions for EMP.

 * @property {Object} configuration Contains configuration properties for EMP.
 * @property {String} configuration.urlProxy Specifies the location of a proxy for outgoing
 * requests of the map.  The proxy will be used for WMS, fetching images,
 * and other map service related requests.
 */
emp3.api.global = emp3.api.global || {

    version: "2.6.0_dev",
    /**
     * @name emp3.api.global#configuration
     */
    configuration: (function() {
      var _urlProxy = "../urlproxy.jsp"; // NOTICE: this file location was selected on purpose

      /**
       * @name emp3.api.global.configuration#urlProxy
       * @type {string}
       */
      Object.defineProperty(this, "urlProxy", {
        enumerable: true,
        get: function() {
          return _urlProxy;
        },
        set: function(value) {
          if (typeof value === "string") {
            _urlProxy = value;
          } else {
            throw new Error("Invalid value type, property urlProxy must be a string");
          }
        }
      });
      return this;
    }())
  };

/**
 * Searches globally for an {@link emp3.api.Overlay}
 *
 * @param {object} args
 * @param {string} args.uuid Id of the feature to search for
 * @param {global~findOverlaySuccess} args.onSuccess Success callback to be invoked on a successful query.
 * @param {ErrorCallback} [args.onError] The error callback will fire only if there was an error performing the query.
 *
 * @example
 * emp3.api.global.findOverlay({
 *   uuid: '71d6f802-16cb47c0-b08806e9-29ae1a3e',
 *   onSuccess: function(cbArgs) {
 *     if (cbArgs.overlay) {
 *       window.console.debug('Overlay found', cbArgs.overlay.name);
 *     }
 *   }
 * });
 */
emp3.api.global.findOverlay = function(args) {
  var message = {},
    callInfo = {};

  message.cmd = emp3.api.enums.channel.get;
  message.filter = [{
    property: "overlayId",
    term: args.uuid
  }];
  message.types = ["overlay"];
  message.select = ["overlayId", "name", "description", "properties"];
  message.recursive = false;
  message.onSuccess = args.onSuccess;
  message.onError = args.onError;

  callInfo.source = "global";
  callInfo.method = "global.findOverlay";
  callInfo.args = args;

  emp3.api.MessageHandler.getInstance().sendMessage(message, callInfo);
};

/**
 * Searches globally for a {@link emp3.api.Feature}
 * @param {object} args
 * @param {string} args.uuid Id of the feature to search for
 * @param {global~findOverlaySuccess} args.onSuccess Success callback to be invoked on a successful query
 * @param {ErrorCallback} [args.onError] The error callback will fire only if there was an error performing the query.
 *
 * @example
 * emp3.api.global.findFeature({
 *   uuid: '71d6f802-16cb47c0-b08806e9-29ae1a3e',
 *   onSuccess: function(cbArgs) {
 *     if (cbArgs.feature) {
 *       window.console.log('Feature found', cbArgs.feature.name);
 *     }
 *   }
 * });
 */
emp3.api.global.findFeature = function(args) {
  var message = {},
    callInfo = {};

  message.cmd = emp3.api.enums.channel.get;
  message.filter = [{
    property: "featureId",
    term: args.uuid
  }];
  message.types = ["feature"];
  message.select = ["featureId", "name", "description", "properties"];
  message.recursive = false;
  message.onSuccess = args.onSuccess;
  message.onError = args.onError;

  callInfo.source = "global";
  callInfo.method = "global.findFeature";
  callInfo.args = args;

  emp3.api.MessageHandler.getInstance().sendMessage(message, callInfo);
};

/**
 * Finds a container on any instantiated map. It will not find Map objects.
 *
 * @param {object} args
 * @param {string} args.uuid Id of the container to search for
 * @param {global~findContainerSuccess} args.onSuccess The success callback will fire even if no container with the
 *     given uuid is found.
 * @param {ErrorCallback} [args.onError] The error callback will fire only if there was an error performing the query.
 *
 * @example
 * emp3.api.global.findContainer({
 *   uuid: '3404301c-6d8c4695-be359d80-cf7b5003',
 *   onSuccess: function(cbArgs) {
 *     if (cbArgs.container) {
 *       window.console.debug(instanceof cbArgs === emp3.api.Overlay ? 'Overlay found' : 'Feature Found');
 *     }
 *   }
 * });
 */
emp3.api.global.findContainer = function(args) {
  args = args || {};
  if (!args.onSuccess) {
    throw new Error('Missing argument: onSuccess');
  }

  if (!args.uuid) {
    throw new Error('Missing argument: uuid');
  } else if (typeof args.uuid !== 'string') {
    throw new TypeError('Invalid type: expected uuid to be a string');
  }

  var message = {
    cmd: emp3.api.enums.channel.get,
    types: ['feature', 'overlay'],
    select: ['featureId', 'overlayId', 'name', 'description', 'properties'],
    filter: [{
      property: 'featureId',
      term: args.uuid
    }, {
      property: 'overlayId',
      term: args.uuid
    }],
    recursive: false,
    onSuccess: args.onSuccess,
    onError: args.onError
  };

  var callInfo = {
    source: 'global',
    method: 'global.findContainer',
    args: args
  };

  emp3.api.MessageHandler.getInstance().sendMessage(message, callInfo);
};

//======================================================================================================================
// Callbacks
//======================================================================================================================
/**
 * This callback will container an {@link emp3.api.Overlay} in the overlay property if one has been found.
 *
 * @callback global~findOverlaySuccess
 * @param {object} cbArgs
 * @param {undefined|emp3.api.Overlay} cbArgs.overlay
 */

/**
 * This callback will container an {@link emp3.api.Feature} in the feature property if one has been found.
 *
 * @callback global~findFeatureSuccess
 * @param {object} cbArgs
 * @param {undefined|emp3.api.Feature} cbArgs.feature
 */

/**
 * This callback will contain either an {@link emp3.api.Overlay} or {@link emp3.api.Feature} in the container property
 * of the callback object.
 *
 * @callback global~findContainerSuccess
 * @param {object} cbArgs
 * @param {undefined|emp3.api.Feature|emp3.api.Overlay} cbArgs.container
 */
<commit_msg>-upgraded version of api global file to 2.6.0<commit_after>if (!window.emp3) {
  emp3 = {};
}
if (!window.emp3.api) {
  emp3.api = {};
}
/**
 * @namespace
 * @memberof emp3.api
 * @desc Contains global settings properties and utility functions for EMP.

 * @property {Object} configuration Contains configuration properties for EMP.
 * @property {String} configuration.urlProxy Specifies the location of a proxy for outgoing
 * requests of the map.  The proxy will be used for WMS, fetching images,
 * and other map service related requests.
 */
emp3.api.global = emp3.api.global || {

    version: "2.6.0",
    /**
     * @name emp3.api.global#configuration
     */
    configuration: (function() {
      var _urlProxy = "../urlproxy.jsp"; // NOTICE: this file location was selected on purpose

      /**
       * @name emp3.api.global.configuration#urlProxy
       * @type {string}
       */
      Object.defineProperty(this, "urlProxy", {
        enumerable: true,
        get: function() {
          return _urlProxy;
        },
        set: function(value) {
          if (typeof value === "string") {
            _urlProxy = value;
          } else {
            throw new Error("Invalid value type, property urlProxy must be a string");
          }
        }
      });
      return this;
    }())
  };

/**
 * Searches globally for an {@link emp3.api.Overlay}
 *
 * @param {object} args
 * @param {string} args.uuid Id of the feature to search for
 * @param {global~findOverlaySuccess} args.onSuccess Success callback to be invoked on a successful query.
 * @param {ErrorCallback} [args.onError] The error callback will fire only if there was an error performing the query.
 *
 * @example
 * emp3.api.global.findOverlay({
 *   uuid: '71d6f802-16cb47c0-b08806e9-29ae1a3e',
 *   onSuccess: function(cbArgs) {
 *     if (cbArgs.overlay) {
 *       window.console.debug('Overlay found', cbArgs.overlay.name);
 *     }
 *   }
 * });
 */
emp3.api.global.findOverlay = function(args) {
  var message = {},
    callInfo = {};

  message.cmd = emp3.api.enums.channel.get;
  message.filter = [{
    property: "overlayId",
    term: args.uuid
  }];
  message.types = ["overlay"];
  message.select = ["overlayId", "name", "description", "properties"];
  message.recursive = false;
  message.onSuccess = args.onSuccess;
  message.onError = args.onError;

  callInfo.source = "global";
  callInfo.method = "global.findOverlay";
  callInfo.args = args;

  emp3.api.MessageHandler.getInstance().sendMessage(message, callInfo);
};

/**
 * Searches globally for a {@link emp3.api.Feature}
 * @param {object} args
 * @param {string} args.uuid Id of the feature to search for
 * @param {global~findOverlaySuccess} args.onSuccess Success callback to be invoked on a successful query
 * @param {ErrorCallback} [args.onError] The error callback will fire only if there was an error performing the query.
 *
 * @example
 * emp3.api.global.findFeature({
 *   uuid: '71d6f802-16cb47c0-b08806e9-29ae1a3e',
 *   onSuccess: function(cbArgs) {
 *     if (cbArgs.feature) {
 *       window.console.log('Feature found', cbArgs.feature.name);
 *     }
 *   }
 * });
 */
emp3.api.global.findFeature = function(args) {
  var message = {},
    callInfo = {};

  message.cmd = emp3.api.enums.channel.get;
  message.filter = [{
    property: "featureId",
    term: args.uuid
  }];
  message.types = ["feature"];
  message.select = ["featureId", "name", "description", "properties"];
  message.recursive = false;
  message.onSuccess = args.onSuccess;
  message.onError = args.onError;

  callInfo.source = "global";
  callInfo.method = "global.findFeature";
  callInfo.args = args;

  emp3.api.MessageHandler.getInstance().sendMessage(message, callInfo);
};

/**
 * Finds a container on any instantiated map. It will not find Map objects.
 *
 * @param {object} args
 * @param {string} args.uuid Id of the container to search for
 * @param {global~findContainerSuccess} args.onSuccess The success callback will fire even if no container with the
 *     given uuid is found.
 * @param {ErrorCallback} [args.onError] The error callback will fire only if there was an error performing the query.
 *
 * @example
 * emp3.api.global.findContainer({
 *   uuid: '3404301c-6d8c4695-be359d80-cf7b5003',
 *   onSuccess: function(cbArgs) {
 *     if (cbArgs.container) {
 *       window.console.debug(instanceof cbArgs === emp3.api.Overlay ? 'Overlay found' : 'Feature Found');
 *     }
 *   }
 * });
 */
emp3.api.global.findContainer = function(args) {
  args = args || {};
  if (!args.onSuccess) {
    throw new Error('Missing argument: onSuccess');
  }

  if (!args.uuid) {
    throw new Error('Missing argument: uuid');
  } else if (typeof args.uuid !== 'string') {
    throw new TypeError('Invalid type: expected uuid to be a string');
  }

  var message = {
    cmd: emp3.api.enums.channel.get,
    types: ['feature', 'overlay'],
    select: ['featureId', 'overlayId', 'name', 'description', 'properties'],
    filter: [{
      property: 'featureId',
      term: args.uuid
    }, {
      property: 'overlayId',
      term: args.uuid
    }],
    recursive: false,
    onSuccess: args.onSuccess,
    onError: args.onError
  };

  var callInfo = {
    source: 'global',
    method: 'global.findContainer',
    args: args
  };

  emp3.api.MessageHandler.getInstance().sendMessage(message, callInfo);
};

//======================================================================================================================
// Callbacks
//======================================================================================================================
/**
 * This callback will container an {@link emp3.api.Overlay} in the overlay property if one has been found.
 *
 * @callback global~findOverlaySuccess
 * @param {object} cbArgs
 * @param {undefined|emp3.api.Overlay} cbArgs.overlay
 */

/**
 * This callback will container an {@link emp3.api.Feature} in the feature property if one has been found.
 *
 * @callback global~findFeatureSuccess
 * @param {object} cbArgs
 * @param {undefined|emp3.api.Feature} cbArgs.feature
 */

/**
 * This callback will contain either an {@link emp3.api.Overlay} or {@link emp3.api.Feature} in the container property
 * of the callback object.
 *
 * @callback global~findContainerSuccess
 * @param {object} cbArgs
 * @param {undefined|emp3.api.Feature|emp3.api.Overlay} cbArgs.container
 */
<|endoftext|>


<commit_before>var fieldRegistry = require('kwf/frontend-form/field-registry');
var Field = require('kwf/frontend-form/field/field');
var kwfExtend = require('kwf/extend');

var Select = kwfExtend(Field, {
    initField: function() {
        this.el.select('select').each((function(input) {
            $(input).on('change', (function() {
                this.el.trigger('kwf-form-change', this.getValue());
            }).bind(this));
        }).bind(this));
    },
    getFieldName: function() {
        return this.el.find('select').get(0).name;
    },
    getValue: function() {
        return this.el.find('select').get(0).value;
    },
    clearValue: function() {
        this.el.find('select').get(0).value = '';
    },
    setValue: function(value) {
        this.el.find('select').get(0).value = value;
    }
});

fieldRegistry.register('kwfFormFieldSelect', Select);
module.exports = Select;
<commit_msg>add more requires<commit_after>var $ = require('jQuery');
var fieldRegistry = require('kwf/frontend-form/field-registry');
var Field = require('kwf/frontend-form/field/field');
var kwfExtend = require('kwf/extend');

var Select = kwfExtend(Field, {
    initField: function() {
        this.el.select('select').each((function(input) {
            $(input).on('change', (function() {
                this.el.trigger('kwf-form-change', this.getValue());
            }).bind(this));
        }).bind(this));
    },
    getFieldName: function() {
        return this.el.find('select').get(0).name;
    },
    getValue: function() {
        return this.el.find('select').get(0).value;
    },
    clearValue: function() {
        this.el.find('select').get(0).value = '';
    },
    setValue: function(value) {
        this.el.find('select').get(0).value = value;
    }
});

fieldRegistry.register('kwfFormFieldSelect', Select);
module.exports = Select;
<|endoftext|>


<commit_before>var dbname = window.location.pathname.split("/")[1];
var appName = window.location.pathname.split("/")[3];
var db = $.couch.db(dbname);

var detailed  = false;
var collapsed = true;

// ____________________________________________________________________________________
$(function(){

  // Tabs
  $('#tabs').tabs();

  // Menu bars
  $( "input:submit", ".menu-bar" ).button();
  $( ".menu-bar" ).click(function() { return false; });

  // Plug-in to style placeholder in old Browsers
  $( "input, textarea" ).placehold( "something-temporary" );

  /*
  // Search box auto-complete [CURRENTLY DISABLED]
  var availableTags = ["all"];

  $.ajax({
    url: '/mj_assays/_design/test/_view/index',
    dataType: 'json',
    async: false,
    success: function(data) {
      $.each(data.rows, function() {
        availableTags.push("\"" + this.key + "\"");
        });
      }
    });
    $( '#box-search' ).autocomplete({
    source: availableTags
  });
  */

  // Template - input
  $.get('templates/default_input.html', function(tmp) {

    $.template("input_template", tmp);
    $.tmpl("input_template", null).appendTo("#input-form");

    $( ".add-entry" ).button({
      icons: {
        primary: "ui-icon-plus"
      },
      text: false
    })

    $( ".remove-entry" ).button({
      icons: {
        primary: "ui-icon-minus"
      },
      text: false
    })

    $(function() {
      $( "#idate" ).datepicker();
    });

    // Form validation

    var validator = $("#input").validate({

      rules: {
        iname:     "required",
        idesc:     "required",
        isrc:      "required",
        iown:      "required",
        itags:     "required",
        itech:     "required",
        iinst:     "required",
        idate:     "required date",
        ireq:      "required",
        reqcon:   "required",
        iprac:     "required",
        ipraccon:  "required",
        imdesc:    "required",
        iisotope:  "required",
        iref:      "required",
        ientry:    "required",
        ientrycon: "required email"
      },

      messages: {
        iname:     "Required",
        idesc:     "Full description required (> 10 characters)",
        isrc:      "Required",
        iown:      "Required",
        itags:     "At least one tag required",
        itech:     "Required (e.g. ICP-MS, gamma)",
        iinst:     "Required",
        idate:     "Required",
        ireq:      "Required",
        ireqcon:   "Required",
        iprac:     "Required",
        ipraccon:  "Required",
        imdesc:    "Required",
        iisotope:  "Test",
        iref:      "Required",
        ientry:    "Required",
        ientrycon: "Valid email required"
      },

      errorPlacement: function(error, element) {
        error.appendTo(element.next('.istatus'));
      }

    });

  });

  // Template - output
  $.get('templates/default_output.html', function(tmp) {
    $.template("output_template", tmp);
  });

  // Search button icon
  $( "#button-search" ).button({
    icons: {
      primary: "ui-icon-search"
    },
    text: false
  });

  $( "#button-expand" ).button();
  $( "#button-detail" ).button();

  $( "#button-clear1" ).button();
  $( "#button-clear2" ).button();
  $( "#button-check" ).button();
  $( "#button-submit" ).button();

  $( "#button-feedback" ).button();

  $( "#dialog-submit" ).dialog({ autoOpen: false, modal: true, resizable: false });
  $( "#dialog-feedback" ).dialog({ autoOpen: false, modal: true, resizable: false });

  $("input:text:visible:first").focus();

  var validator = $("#feedback").validate({

    rules: {
      fname:     "required",
      femail:    "required email",
    },

    messages: {
      fname:     "Required",
      femail:    "Valid email required",
    },

    errorPlacement: function(error, element) {
       error.appendTo(element.next('.istatus'));
    }

  });

});

// ____________________________________________________________________________________
function add_result_entry(elem) {

  $("div.results-block > div:first-child")
    .clone()
    .removeClass('template')
    .addClass('result-row')
    .insertAfter($(elem).parent()).show();

}

// ____________________________________________________________________________________
function remove_result_entry(elem) {

  $(elem).parent().remove();

}

// ____________________________________________________________________________________
function limit_error(elem) {

  if ( $(elem).val() == "Meas" ) {
    $(elem).next().next().attr("placeholder", "Error");
  } else {
    $(elem).next().next().attr("placeholder", "Confidence level");
  }

}

// ____________________________________________________________________________________
function click_clear_all() {

  $(':input','#input')
    .not(':button, :submit, :reset, :hidden')
    .val('')
    .removeAttr('checked')
    .removeAttr('selected');

  $("#input").validate().resetForm()

}

// ____________________________________________________________________________________
function click_clear_warnings() {

  $("#input").validate().resetForm()

}

// ____________________________________________________________________________________
function click_check() {

  $("#input").validate().form()

}

// ____________________________________________________________________________________
function click_submit() {

  $("#input").validate().form();

  if ( $("#input").validate().numberOfInvalids() == 0 ) {

    // Parse the date

    var arr_idate = $("#idate").val().split("/");

    var imonth = arr_idate[0];
    var iday   = arr_idate[1];
    var iyear  = arr_idate[2];

    // Build the JSON for the results
    //   (complex because fields don't have unique IDs)

    //var n_results = $(".results-block").children('div.result-row').length;

    var iresult = {};

    $(".results-block").children('div.result-row').each(function(i) {

      // Loop through all the results for this measurement

      var iisotope = $(this).find(".iisotope").val();
      var iselect  = $(this).find(".iselect").val();
      var ivalue   = $(this).find(".ivalue").val();
      var ierror   = $(this).find(".ierror").val();
      var iunit    = $(this).find(".iunit").val();

      if ( iselect == "Meas" ) {

        // Measurement

        iresult[i] = {
          "isotope": iisotope,
          "value":   ivalue,
          "error":   ierror,
          "unit":    iunit
        };

      } else {

        // Limit

        iresult[i] = {
          "isotope": iisotope,
          "limit":   ivalue,
          "error":   ierror,
          "unit":    iunit
        };

      }

    });

    // Build the overall JSON

    var output_json =  {

      "type": "measurement-provisional",
      "sample": {
        "name":        $("#iname").val(),
        "description": $("#idesc").val(),
        "source":      $("#isrc").val(),
        "owner":       $("#iown").val(),
        "set":         $("#itags").val(),
        "mass":        $("#imass").val(),
        "geometry":    $("#igeom").val()
      },
      "measurement": {
        "institution": $("#iinst").val(),
        "technique":   $("#itech").val(),
        "date": {
        "day":     iday,
        "month":   imonth,
        "year":    iyear
      },
      "results":     iresult,
      "requestor":            $("#ireq").val(),
      "requestor_contact":    $("#ireqcon").val(),
      "practitioner":         $("#iprac").val(),
      "practitioner_contact": $("#ipraccon").val(),
      "description":          $("#imdesc").val()
      },
      "data_source": {
         "reference":          $("#iref").val(),
         "data_entry_name":    $("#ientry").val(),
         "data_entry_contact": $("#ientrycon").val()
      }

    };

    db.saveDoc(

      output_json,

      { success: function() {
        $( "#dialog-submit" ).dialog( "open" );
        $(':input','#feedback')
          .not(':button, :submit, :reset, :hidden')
          .val('')
          .removeAttr('checked')
          .removeAttr('selected');
        }}

      );

   }

}

// ____________________________________________________________________________________
function click_feedback() {

  $("#feedback").validate().form();

  if ( $("#feedback").validate().numberOfInvalids() == 0 ) {

    db.saveDoc(
      {
        "type"             : "feedback",
        "name"             : $("#fname").val(),
        "email_feedback"   : $("#femail").val(),
        "feedback"         : $("#fcomment").val()
      },
      { success: function() {
        $( "#dialog-feedback" ).dialog( "open" );
        $(':input','#feedback')
          .not(':button, :submit, :reset, :hidden')
          .val('')
          .removeAttr('checked')
          .removeAttr('selected');
        }}
      );

   }

}

// ____________________________________________________________________________________
function click_detail() {

  if (detailed) {

    $(".hideable").hide();
    $("input#button-detail").val("More detail");
    detailed = false;

  } else {

    $(".hideable").show();
    $("input#button-detail").val("Less detail");
    detailed = true;

  };

}

// ____________________________________________________________________________________
function click_expand() {

  if (collapsed) {

    $("img[class='collapsibleClosed']").click();
    $("input#button-expand").val("Collapse");
    collapsed = false;

  } else {

    $("img[class='collapsibleOpen']").click();
    $("input#button-expand").val("Expand");
    collapsed = true;

  };

}

// ____________________________________________________________________________________
function click_search() {

  var entry = $("#box-search").val();

  if ( entry == "" || entry == "e.g. all") {
    $("#box-search").focus();
    $("div#materials").empty();
    return false;
  }

  searchResults($("#box-search").val());

  collapsed = true;
  $("input#button-expand").val("Expand");

  detailed = false;
  $("input#button-detail").val("More detail");

  return false;

};

// ____________________________________________________________________________________
function searchResults(val) {

  var search_url;

  // By default return all documents from the search

  search_url = '/' + dbname + '/_all_docs?include_docs=true';

  if ( window.location.host.split(".")[1] == "cloudant" ) {
    search_url = window.location.protocol + '//' + window.location.host
               + '/' + dbname + '/_design/views/_search/assays?q='
               + val + '&include_docs=true';
  }

  if ( val.toLowerCase() == "all" ) {
    search_url = '/' + dbname + '/_all_docs?include_docs=true';
  };

  $("#materials").empty();

  $.ajax({

    url: search_url,
    dataType: 'json',
    async: false,
    success: function(data) {

    if ( data.total_rows > 0 ) {

      $("#materials").append('
');

        for ( j = 0; j < data.total_rows; j++ ) {

          var doc = data.rows[j].doc;

          if ( doc.type == "measurement" ) {
            $.tmpl("output_template", doc).appendTo("#output");
          }

        }

        $("#materials").append('
');
        makeCollapsible(document.getElementById('output'));
        $(".hideable").hide();

      }

    }

  })

};

// ____________________________________________________________________________________
function enter_box(event) {

  if (event.keyCode == 13) {

    //$( "#box-search" ).autocomplete("close");
    click_search();
    event.returnValue = false; // for IE
    if (event.preventDefault()) event.preventDefault();

  }

  return false;

}

<commit_msg>Add Ben's changes to this file to handle specification v1.00<commit_after>var dbname = window.location.pathname.split("/")[1];
var appName = window.location.pathname.split("/")[3];
var db = $.couch.db(dbname);

var detailed  = false;
var collapsed = true;

// ____________________________________________________________________________________
$(function(){

  // Tabs
  $('#tabs').tabs();

  // Menu bars
  $( "input:submit", ".menu-bar" ).button();
  $( ".menu-bar" ).click(function() { return false; });

  // Plug-in to style placeholder in old Browsers
  $( "input, textarea" ).placehold( "something-temporary" );

  /*
  // Search box auto-complete [CURRENTLY DISABLED]
  var availableTags = ["all"];

  $.ajax({
    url: '/mj_assays/_design/test/_view/index',
    dataType: 'json',
    async: false,
    success: function(data) {
      $.each(data.rows, function() {
        availableTags.push("\"" + this.key + "\"");
        });
      }
    });
    $( '#box-search' ).autocomplete({
    source: availableTags
  });
  */

  // Template - input
  $.get('templates/default_input.html', function(tmp) {

    $.template("input_template", tmp);
    $.tmpl("input_template", null).appendTo("#input-form");

    $( ".add-entry" ).button({
      icons: {
        primary: "ui-icon-plus"
      },
      text: false
    })

    $( ".remove-entry" ).button({
      icons: {
        primary: "ui-icon-minus"
      },
      text: false
    })

    $(function() {
      $( "#idate" ).datepicker();
    });

    // Form validation

    var validator = $("#input").validate({

      rules: {
        iname:     "required",
        idesc:     "required",
        isrc:      "required",
        iown:      "required",
        itags:     "required",
        itech:     "required",
        iinst:     "required",
        idate:     "required date",
        ireq:      "required",
        reqcon:   "required",
        iprac:     "required",
        ipraccon:  "required",
        imdesc:    "required",
        iisotope:  "required",
        iref:      "required",
        ientry:    "required",
        ientrycon: "required email"
      },

      messages: {
        iname:     "Required",
        idesc:     "Full description required (> 10 characters)",
        isrc:      "Required",
        iown:      "Required",
        itags:     "At least one tag required",
        itech:     "Required (e.g. ICP-MS, gamma)",
        iinst:     "Required",
        idate:     "Required",
        ireq:      "Required",
        ireqcon:   "Required",
        iprac:     "Required",
        ipraccon:  "Required",
        imdesc:    "Required",
        iisotope:  "Test",
        iref:      "Required",
        ientry:    "Required",
        ientrycon: "Valid email required"
      },

      errorPlacement: function(error, element) {
        error.appendTo(element.next('.istatus'));
      }

    });

  });

  // Template - output
  $.get('templates/default_output.html', function(tmp) {
    $.template("output_template", tmp);
  });

  // Search button icon
  $( "#button-search" ).button({
    icons: {
      primary: "ui-icon-search"
    },
    text: false
  });

  $( "#button-expand" ).button();
  $( "#button-detail" ).button();

  $( "#button-clear1" ).button();
  $( "#button-clear2" ).button();
  $( "#button-check" ).button();
  $( "#button-submit" ).button();

  $( "#button-feedback" ).button();

  $( "#dialog-submit" ).dialog({ autoOpen: false, modal: true, resizable: false });
  $( "#dialog-feedback" ).dialog({ autoOpen: false, modal: true, resizable: false });

  $("input:text:visible:first").focus();

  var validator = $("#feedback").validate({

    rules: {
      fname:     "required",
      femail:    "required email",
    },

    messages: {
      fname:     "Required",
      femail:    "Valid email required",
    },

    errorPlacement: function(error, element) {
       error.appendTo(element.next('.istatus'));
    }

  });

});

// ____________________________________________________________________________________
function add_result_entry(elem) {

  $("div.results-block > div:first-child")
    .clone()
    .removeClass('template')
    .addClass('result-row')
    .insertAfter($(elem).parent()).show();

}

// ____________________________________________________________________________________
function remove_result_entry(elem) {

  $(elem).parent().remove();

}

// ____________________________________________________________________________________
function limit_error(elem) {

  if ( $(elem).val() == "Meas" ) {
    $(elem).next().next().attr("placeholder", "Error");
  } else {
    $(elem).next().next().attr("placeholder", "Confidence level");
  }

}

// ____________________________________________________________________________________
function click_clear_all() {

  $(':input','#input')
    .not(':button, :submit, :reset, :hidden')
    .val('')
    .removeAttr('checked')
    .removeAttr('selected');

  $("#input").validate().resetForm()

}

// ____________________________________________________________________________________
function click_clear_warnings() {

  $("#input").validate().resetForm()

}

// ____________________________________________________________________________________
function click_check() {

  $("#input").validate().form()

}

// ____________________________________________________________________________________
function click_submit() {

  $("#input").validate().form();

  if ( $("#input").validate().numberOfInvalids() == 0 ) {

    // Build the JSON for the results
    //   (complex because fields don't have unique IDs)

    var iresult = {};

    $(".results-block").children('div.result-row').each(function(i) {

      // Loop through all the results for this measurement

      var iisotope = $(this).find(".iisotope").val();
      var iselect  = $(this).find(".iselect").val();
      var ivalue   = $(this).find(".ivalue").val();
      var ierror   = $(this).find(".ierror").val();
      var iunit    = $(this).find(".iunit").val();

      if ( iselect == "Meas" ) {

        // Measurement

        iresult[i] = {
          "isotope": iisotope,
          "value":   ivalue,
          "error":   ierror,
          "unit":    iunit
        };

      } else {

        // Limit

        iresult[i] = {
          "isotope": iisotope,
          "limit":   ivalue,
          "error":   ierror,
          "unit":    iunit
        };

      }

    });

    // Build the overall JSON

    var output_json =  {

      "type": "measurement-provisional",
      "grouping": $("#igrouping").val(),
      "sample": {
        "m_name":        $("#iname").val(),
        "m_description": $("#idesc").val(),
        "m_id":         $("#iid").val(),
        "m_source":      $("#isrc").val(),
        "m_owner":
                {
                "name" : $("#iown").val(),
                "contact" : $("#iowncontact").val()
                }
           },
      "m_measurement": {
        "m_institution": $("#iinst").val(),
        "m_technique":   $("#itech").val(),
        "m_date": $("#idate").val(),
        "m_results":     iresult,
      "m_requestor":  {
            "name": $("#ireq").val(),
            "contact":    $("#ireqcon").val()
                        },
      "m_practitioner":  {
            "name" : $("#iprac").val(),
            "contact": $("#ipraccon").val()
                        },
      "m_description":          $("#imdesc").val()
      },
      "m_data_source": {
         "m_reference":          $("#iref").val(),
         "m_input" : {
             "name": $("#ientry").val(),
             "contact": $("#ientrycon").val(),
             "date": $("#ientrydate").val()
                    },
         "m_notes" : $("#inotes").val()
      },
      "specification" : "1.0"

    };

    db.saveDoc(

      output_json,

      { success: function() {
        $( "#dialog-submit" ).dialog( "open" );
        $(':input','#feedback')
          .not(':button, :submit, :reset, :hidden')
          .val('')
          .removeAttr('checked')
          .removeAttr('selected');
        }}

      );

   }

}

// ____________________________________________________________________________________
function click_feedback() {

  $("#feedback").validate().form();

  if ( $("#feedback").validate().numberOfInvalids() == 0 ) {

    db.saveDoc(
      {
        "type"             : "feedback",
        "name"             : $("#fname").val(),
        "email_feedback"   : $("#femail").val(),
        "feedback"         : $("#fcomment").val()
      },
      { success: function() {
        $( "#dialog-feedback" ).dialog( "open" );
        $(':input','#feedback')
          .not(':button, :submit, :reset, :hidden')
          .val('')
          .removeAttr('checked')
          .removeAttr('selected');
        }}
      );

   }

}

// ____________________________________________________________________________________
function click_detail() {

  if (detailed) {

    $(".hideable").hide();
    $("input#button-detail").val("More detail");
    detailed = false;

  } else {

    $(".hideable").show();
    $("input#button-detail").val("Less detail");
    detailed = true;

  };

}

// ____________________________________________________________________________________
function click_expand() {

  if (collapsed) {

    $("img[class='collapsibleClosed']").click();
    $("input#button-expand").val("Collapse");
    collapsed = false;

  } else {

    $("img[class='collapsibleOpen']").click();
    $("input#button-expand").val("Expand");
    collapsed = true;

  };

}

// ____________________________________________________________________________________
function click_search() {

  var entry = $("#box-search").val();

  if ( entry == "" || entry == "e.g. all") {
    $("#box-search").focus();
    $("div#materials").empty();
    return false;
  }

  searchResults($("#box-search").val());

  collapsed = true;
  $("input#button-expand").val("Expand");

  detailed = false;
  $("input#button-detail").val("More detail");

  return false;

};

// ____________________________________________________________________________________
function searchResults(val) {

  var search_url;

  // By default return all documents from the search

  search_url = '/' + dbname + '/_all_docs?include_docs=true';

  if ( window.location.host.split(".")[1] == "cloudant" ) {
    search_url = window.location.protocol + '//' + window.location.host
               + '/' + dbname + '/_design/views/_search/assays?q='
               + val + '&include_docs=true';
  }

  if ( val.toLowerCase() == "all" ) {
    search_url = '/' + dbname + '/_all_docs?include_docs=true';
  };

  $("#materials").empty();

  $.ajax({

    url: search_url,
    dataType: 'json',
    async: false,
    success: function(data) {

    if ( data.total_rows > 0 ) {

      $("#materials").append('
');

        for ( j = 0; j < data.total_rows; j++ ) {

          var doc = data.rows[j].doc;

          if ( doc.type == "measurement" ) {
            $.tmpl("output_template", doc).appendTo("#output");
          }

        }

        $("#materials").append('
');
        makeCollapsible(document.getElementById('output'));
        $(".hideable").hide();

      }

    }

  })

};

// ____________________________________________________________________________________
function enter_box(event) {

  if (event.keyCode == 13) {

    //$( "#box-search" ).autocomplete("close");
    click_search();
    event.returnValue = false; // for IE
    if (event.preventDefault()) event.preventDefault();

  }

  return false;

}

<|endoftext|>


<commit_before>var Ws = require('ws');
var request = require('request');
var slackWebApi = require(__dirname + '/Slack_web_api.js');

module.exports = function(botkit, config) {
    var bot = {
        botkit: botkit,
        config: config || {},
        utterances: botkit.utterances,
        api: slackWebApi(botkit, config || {})
    };

    /**
     * Set up API to send incoming webhook
     */
    bot.configureIncomingWebhook = function(options) {
        if (!options.url)
            throw new Error('No incoming webhook URL specified!');

        bot.config.incoming_webhook = options;

        return bot;
    };

    bot.sendWebhook = function(options, cb) {
        if (!bot.config.incoming_webhook || !bot.config.incoming_webhook.url) {
            botkit.debug('CANNOT SEND WEBHOOK!!');

            return cb && cb('No webhook url specified');
        }

        request.post(bot.config.incoming_webhook.url, function(err, res, body) {
            if (err) {
                botkit.debug('WEBHOOK ERROR', err);
                return cb && cb(err);
            }
            botkit.debug('WEBHOOK SUCCESS', body);
            cb && cb(null, body);
        }).form({ payload: JSON.stringify(options) });
    };

    bot.configureRTM = function(config) {
        bot.config.token = config.token;
        return bot;
    };

    bot.closeRTM = function() {
        if (bot.rtm)
            bot.rtm.close();
    };

    bot.startRTM = function(cb) {
        bot.api.rtm.start({
            no_unreads: true,
            simple_latest: true,
        }, function(err, res) {
            if (err) {
                return cb && cb(err);
            }

            if (!res) {
                return cb && cb('Invalid response from rtm.start');
            }

            bot.identity = res.self;
            bot.team_info = res.team;

            /**
             * Also available:
             * res.users, res.channels, res.groups, res.ims,
             * res.bots
             *
             * Could be stored & cached for later use.
             */

            botkit.log.notice('** BOT ID:', bot.identity.name, '...attempting to connect to RTM!');

            bot.rtm = new Ws(res.url);
            bot.msgcount = 1;

            var pingIntervalId = null;
            bot.rtm.on('open', function() {

                pingIntervalId = setInterval(function() {
                    bot.rtm.ping(null, null, true);
                }, 5000);

                botkit.trigger('rtm_open', [this]);

                bot.rtm.on('message', function(data, flags) {

                    var message = JSON.parse(data);

                    /**
                     * Lets construct a nice quasi-standard botkit message
                     * it leaves the main slack message at the root
                     * but adds in additional fields for internal use!
                     * (including the teams api details)
                     */
                    botkit.receiveMessage(bot, message);

                });

                botkit.startTicking();

                cb && cb(null, bot, res);
            });

            bot.rtm.on('error', function(err) {
                botkit.log.error('RTM websocket error!', err);
                botkit.trigger('rtm_close', [bot, err]);
            });

            bot.rtm.on('close', function() {
                if (pingIntervalId) {
                    clearInterval(pingIntervalId);
                }
                botkit.trigger('rtm_close', [bot]);

            });
        });

        return bot;
    };

    bot.identifyBot = function(cb) {
        if (bot.identity) {
            bot.identifyTeam(function(err, team) {
                cb(null, {
                    name: bot.identity.name,
                    id: bot.identity.id,
                    team_id: team
                });
            });
        } else {
            /**
             * Note: Are there scenarios other than the RTM
             * where we might pull identity info, perhaps from
             * bot.api.auth.test on a given token?
             */
            cb('Identity Unknown: Not using RTM api');
        };
    };

    bot.identifyTeam = function(cb) {
        if (bot.team_info)
            return cb(null, bot.team_info.id);

        /**
         * Note: Are there scenarios other than the RTM
         * where we might pull identity info, perhaps from
         * bot.api.auth.test on a given token?
         */
        cb('Unknown Team!');
    };

    /**
     * Convenience method for creating a DM convo.
     */
    bot.startPrivateConversation = function(message, cb) {
        botkit.startTask(this, message, function(task, convo) {
            bot._startDM(task, message.user, function(err, dm) {
                convo.stop();
                cb(err, dm);
            });
        });
    };

    bot.startConversation = function(message, cb) {
        botkit.startConversation(this, message, cb);
    };

    /**
     * Convenience method for creating a DM convo.
     */
    bot._startDM = function(task, user_id, cb) {
        bot.api.im.open({ user: user_id }, function(err, channel) {
            if (err) return cb(err);

            cb(null, task.startConversation({
                channel: channel.channel.id,
                user: user_id
            }));
        });
    };

    bot.say = function(message, cb) {
        botkit.debug('SAY', message);

        /**
         * Construct a valid slack message.
         */
        var slack_message = {
            id: message.id || bot.msgcount,
            type: message.type || 'message',
            channel: message.channel,
            text: message.text || null,
            username: message.username || null,
            parse: message.parse || null,
            link_names: message.link_names || null,
            attachments: message.attachments ?
                JSON.stringify(message.attachments) : null,
            unfurl_links: message.unfurl_links || null,
            unfurl_media: message.unfurl_media || null,
            icon_url: message.icon_url || null,
            icon_emoji: message.icon_emoji || null,
        };
        bot.msgcount++;

        if (message.icon_url || message.icon_emoji || message.username) {
            slack_message.as_user = false;
        } else {
            slack_message.as_user = message.as_user || true;
        }

        /**
         * These options are not supported by the RTM
         * so if they are specified, we use the web API to send messages.
         */
        if (message.attachments || message.icon_emoji ||
            message.username || message.icon_url) {

            if (!bot.config.token) {
                throw new Error('Cannot use web API to send messages.');
            }

            bot.api.chat.postMessage(slack_message, function(err, res) {
                if (err) {
                    cb && cb(err);
                } else {
                    cb && cb(null, res);
                }
            });

        } else {
            if (!bot.rtm)
                throw new Error('Cannot use the RTM API to send messages.');

            try {
                bot.rtm.send(JSON.stringify(slack_message), function(err) {
                    if (err) {
                        cb && cb(err);
                    } else {
                        cb && cb();
                    }
                });
            } catch (err) {
                /**
                 * The RTM failed and for some reason it didn't get caught
                 * elsewhere. This happens sometimes when the rtm has closed but
                 * We are sending messages anyways.
                 * Bot probably needs to reconnect!
                 */
                cb && cb(err);
            }
        }
    };

    bot.replyPublic = function(src, resp, cb) {
        if (!bot.res) {
            cb && cb('No web response object found');
        } else {
            var msg = {};

            if (typeof(resp) == 'string') {
                msg.text = resp;
            } else {
                msg = resp;
            }

            msg.channel = src.channel;

            msg.response_type = 'in_channel';
            bot.res.json(msg);
            cb && cb();
        }
    };

    bot.replyPublicDelayed = function(src, resp, cb) {
        if (!src.response_url) {
            cb && cb('No response_url found');
        } else {
            var msg = {};

            if (typeof(resp) == 'string') {
                msg.text = resp;
            } else {
                msg = resp;
            }

            msg.channel = src.channel;

            msg.response_type = 'in_channel';
            request.post(src.response_url, function(err, resp, body) {
                /**
                 * Do something?
                 */
                if (err) {
                    botkit.log.error('Error sending slash command response:', err);
                    cb && cb(err);
                } else {
                    cb && cb();
                }
            }).form(JSON.stringify(msg));
        }
    };

    bot.replyPrivate = function(src, resp, cb) {
        if (!bot.res) {
            cb && cb('No web response object found');
        } else {
            var msg = {};

            if (typeof(resp) == 'string') {
                msg.text = resp;
            } else {
                msg = resp;
            }

            msg.channel = src.channel;

            msg.response_type = 'ephemeral';
            bot.res.json(msg);

            cb && cb();
        }
    };

    bot.replyPrivateDelayed = function(src, resp, cb) {
        if (!src.response_url) {
            cb && cb('No response_url found');
        } else {
            var msg = {};

            if (typeof(resp) == 'string') {
                msg.text = resp;
            } else {
                msg = resp;
            }

            msg.channel = src.channel;

            msg.response_type = 'ephemeral';
            request.post(src.response_url, function(err, resp, body) {
                /**
                 * Do something?
                 */
                if (err) {
                    botkit.log.error('Error sending slash command response:', err);
                    cb && cb(err);
                } else {
                    cb && cb();
                }
            }).form(JSON.stringify(msg));
        }
    };

    bot.reply = function(src, resp, cb) {
        var msg = {};

        if (typeof(resp) == 'string') {
            msg.text = resp;
        } else {
            msg = resp;
        }

        msg.channel = src.channel;

        bot.say(msg, cb);
    };

    /**
     * sends a typing message to the source channel
     *
     * @param {Object} src message source
     */
    bot.startTyping = function(src) {
        bot.reply(src, { type: 'typing' });
    };

    /**
     * replies with message after typing delay
     *
     * @param {Object} src message source
     * @param {(string|Object)} resp string or object
     * @param {function} cb optional request callback
     */
    bot.replyWithTyping = function(src, resp, cb) {
        var text;

        if (typeof(resp) == 'string') {
            text = resp;
        } else {
            text = resp.text;
        }

        var typingLength = 1200 / 60 * text.length;
        typingLength = typingLength > 2000 ? 2000 : typingLength;

        bot.startTyping(src);

        setTimeout(function() {
            bot.reply(src, resp, cb);
        }, typingLength);
    };

    /**
     * This handles the particulars of finding an existing conversation or
     * topic to fit the message into...
     */
    bot.findConversation = function(message, cb) {
        botkit.debug('CUSTOM FIND CONVO', message.user, message.channel);
        if (message.type == 'message' || message.type == 'slash_command' ||
            message.type == 'outgoing_webhook') {
            for (var t = 0; t < botkit.tasks.length; t++) {
                for (var c = 0; c < botkit.tasks[t].convos.length; c++) {
                    if (
                        botkit.tasks[t].convos[c].isActive() &&
                        botkit.tasks[t].convos[c].source_message.user == message.user &&
                            botkit.tasks[t].convos[c].source_message.channel == message.channel
                    ) {
                        botkit.debug('FOUND EXISTING CONVO!');
                        cb(botkit.tasks[t].convos[c]);
                        return;
                    }
                }
            }
        }

        cb();
    };

    if (bot.config.incoming_webhook)
        bot.configureIncomingWebhook(config.incoming_webhook);

    if (bot.config.bot)
        bot.configureRTM(config.bot);

    return bot;
};
<commit_msg>clean up newlines<commit_after>var Ws = require('ws');
var request = require('request');
var slackWebApi = require(__dirname + '/Slack_web_api.js');

module.exports = function(botkit, config) {
    var bot = {
        botkit: botkit,
        config: config || {},
        utterances: botkit.utterances,
        api: slackWebApi(botkit, config || {})
    };

    /**
     * Set up API to send incoming webhook
     */
    bot.configureIncomingWebhook = function(options) {
        if (!options.url)
            throw new Error('No incoming webhook URL specified!');

        bot.config.incoming_webhook = options;

        return bot;
    };

    bot.sendWebhook = function(options, cb) {
        if (!bot.config.incoming_webhook || !bot.config.incoming_webhook.url) {
            botkit.debug('CANNOT SEND WEBHOOK!!');

            return cb && cb('No webhook url specified');
        }

        request.post(bot.config.incoming_webhook.url, function(err, res, body) {
            if (err) {
                botkit.debug('WEBHOOK ERROR', err);
                return cb && cb(err);
            }
            botkit.debug('WEBHOOK SUCCESS', body);
            cb && cb(null, body);
        }).form({ payload: JSON.stringify(options) });
    };

    bot.configureRTM = function(config) {
        bot.config.token = config.token;
        return bot;
    };

    bot.closeRTM = function() {
        if (bot.rtm)
            bot.rtm.close();
    };

    bot.startRTM = function(cb) {
        bot.api.rtm.start({
            no_unreads: true,
            simple_latest: true,
        }, function(err, res) {
            if (err) {
                return cb && cb(err);
            }

            if (!res) {
                return cb && cb('Invalid response from rtm.start');
            }

            bot.identity = res.self;
            bot.team_info = res.team;

            /**
             * Also available:
             * res.users, res.channels, res.groups, res.ims,
             * res.bots
             *
             * Could be stored & cached for later use.
             */

            botkit.log.notice('** BOT ID:', bot.identity.name, '...attempting to connect to RTM!');

            bot.rtm = new Ws(res.url);
            bot.msgcount = 1;

            var pingIntervalId = null;
            bot.rtm.on('open', function() {

                pingIntervalId = setInterval(function() {
                    bot.rtm.ping(null, null, true);
                }, 5000);

                botkit.trigger('rtm_open', [this]);

                bot.rtm.on('message', function(data, flags) {
                    var message = JSON.parse(data);

                    /**
                     * Lets construct a nice quasi-standard botkit message
                     * it leaves the main slack message at the root
                     * but adds in additional fields for internal use!
                     * (including the teams api details)
                     */
                    botkit.receiveMessage(bot, message);

                });

                botkit.startTicking();

                cb && cb(null, bot, res);
            });

            bot.rtm.on('error', function(err) {
                botkit.log.error('RTM websocket error!', err);
                botkit.trigger('rtm_close', [bot, err]);
            });

            bot.rtm.on('close', function() {
                if (pingIntervalId) {
                    clearInterval(pingIntervalId);
                }
                botkit.trigger('rtm_close', [bot]);
            });
        });

        return bot;
    };

    bot.identifyBot = function(cb) {
        if (bot.identity) {
            bot.identifyTeam(function(err, team) {
                cb(null, {
                    name: bot.identity.name,
                    id: bot.identity.id,
                    team_id: team
                });
            });
        } else {
            /**
             * Note: Are there scenarios other than the RTM
             * where we might pull identity info, perhaps from
             * bot.api.auth.test on a given token?
             */
            cb('Identity Unknown: Not using RTM api');
        };
    };

    bot.identifyTeam = function(cb) {
        if (bot.team_info)
            return cb(null, bot.team_info.id);

        /**
         * Note: Are there scenarios other than the RTM
         * where we might pull identity info, perhaps from
         * bot.api.auth.test on a given token?
         */
        cb('Unknown Team!');
    };

    /**
     * Convenience method for creating a DM convo.
     */
    bot.startPrivateConversation = function(message, cb) {
        botkit.startTask(this, message, function(task, convo) {
            bot._startDM(task, message.user, function(err, dm) {
                convo.stop();
                cb(err, dm);
            });
        });
    };

    bot.startConversation = function(message, cb) {
        botkit.startConversation(this, message, cb);
    };

    /**
     * Convenience method for creating a DM convo.
     */
    bot._startDM = function(task, user_id, cb) {
        bot.api.im.open({ user: user_id }, function(err, channel) {
            if (err) return cb(err);

            cb(null, task.startConversation({
                channel: channel.channel.id,
                user: user_id
            }));
        });
    };

    bot.say = function(message, cb) {
        botkit.debug('SAY', message);

        /**
         * Construct a valid slack message.
         */
        var slack_message = {
            id: message.id || bot.msgcount,
            type: message.type || 'message',
            channel: message.channel,
            text: message.text || null,
            username: message.username || null,
            parse: message.parse || null,
            link_names: message.link_names || null,
            attachments: message.attachments ?
                JSON.stringify(message.attachments) : null,
            unfurl_links: message.unfurl_links || null,
            unfurl_media: message.unfurl_media || null,
            icon_url: message.icon_url || null,
            icon_emoji: message.icon_emoji || null,
        };
        bot.msgcount++;

        if (message.icon_url || message.icon_emoji || message.username) {
            slack_message.as_user = false;
        } else {
            slack_message.as_user = message.as_user || true;
        }

        /**
         * These options are not supported by the RTM
         * so if they are specified, we use the web API to send messages.
         */
        if (message.attachments || message.icon_emoji ||
            message.username || message.icon_url) {

            if (!bot.config.token) {
                throw new Error('Cannot use web API to send messages.');
            }

            bot.api.chat.postMessage(slack_message, function(err, res) {
                if (err) {
                    cb && cb(err);
                } else {
                    cb && cb(null, res);
                }
            });

        } else {
            if (!bot.rtm)
                throw new Error('Cannot use the RTM API to send messages.');

            try {
                bot.rtm.send(JSON.stringify(slack_message), function(err) {
                    if (err) {
                        cb && cb(err);
                    } else {
                        cb && cb();
                    }
                });
            } catch (err) {
                /**
                 * The RTM failed and for some reason it didn't get caught
                 * elsewhere. This happens sometimes when the rtm has closed but
                 * We are sending messages anyways.
                 * Bot probably needs to reconnect!
                 */
                cb && cb(err);
            }
        }
    };

    bot.replyPublic = function(src, resp, cb) {
        if (!bot.res) {
            cb && cb('No web response object found');
        } else {
            var msg = {};

            if (typeof(resp) == 'string') {
                msg.text = resp;
            } else {
                msg = resp;
            }

            msg.channel = src.channel;

            msg.response_type = 'in_channel';
            bot.res.json(msg);
            cb && cb();
        }
    };

    bot.replyPublicDelayed = function(src, resp, cb) {
        if (!src.response_url) {
            cb && cb('No response_url found');
        } else {
            var msg = {};

            if (typeof(resp) == 'string') {
                msg.text = resp;
            } else {
                msg = resp;
            }

            msg.channel = src.channel;

            msg.response_type = 'in_channel';
            request.post(src.response_url, function(err, resp, body) {
                /**
                 * Do something?
                 */
                if (err) {
                    botkit.log.error('Error sending slash command response:', err);
                    cb && cb(err);
                } else {
                    cb && cb();
                }
            }).form(JSON.stringify(msg));
        }
    };

    bot.replyPrivate = function(src, resp, cb) {
        if (!bot.res) {
            cb && cb('No web response object found');
        } else {
            var msg = {};

            if (typeof(resp) == 'string') {
                msg.text = resp;
            } else {
                msg = resp;
            }

            msg.channel = src.channel;

            msg.response_type = 'ephemeral';
            bot.res.json(msg);

            cb && cb();
        }
    };

    bot.replyPrivateDelayed = function(src, resp, cb) {
        if (!src.response_url) {
            cb && cb('No response_url found');
        } else {
            var msg = {};

            if (typeof(resp) == 'string') {
                msg.text = resp;
            } else {
                msg = resp;
            }

            msg.channel = src.channel;

            msg.response_type = 'ephemeral';
            request.post(src.response_url, function(err, resp, body) {
                /**
                 * Do something?
                 */
                if (err) {
                    botkit.log.error('Error sending slash command response:', err);
                    cb && cb(err);
                } else {
                    cb && cb();
                }
            }).form(JSON.stringify(msg));
        }
    };

    bot.reply = function(src, resp, cb) {
        var msg = {};

        if (typeof(resp) == 'string') {
            msg.text = resp;
        } else {
            msg = resp;
        }

        msg.channel = src.channel;

        bot.say(msg, cb);
    };

    /**
     * sends a typing message to the source channel
     *
     * @param {Object} src message source
     */
    bot.startTyping = function(src) {
        bot.reply(src, { type: 'typing' });
    };

    /**
     * replies with message after typing delay
     *
     * @param {Object} src message source
     * @param {(string|Object)} resp string or object
     * @param {function} cb optional request callback
     */
    bot.replyWithTyping = function(src, resp, cb) {
        var text;

        if (typeof(resp) == 'string') {
            text = resp;
        } else {
            text = resp.text;
        }

        var typingLength = 1200 / 60 * text.length;
        typingLength = typingLength > 2000 ? 2000 : typingLength;

        bot.startTyping(src);

        setTimeout(function() {
            bot.reply(src, resp, cb);
        }, typingLength);
    };

    /**
     * This handles the particulars of finding an existing conversation or
     * topic to fit the message into...
     */
    bot.findConversation = function(message, cb) {
        botkit.debug('CUSTOM FIND CONVO', message.user, message.channel);
        if (message.type == 'message' || message.type == 'slash_command' ||
            message.type == 'outgoing_webhook') {
            for (var t = 0; t < botkit.tasks.length; t++) {
                for (var c = 0; c < botkit.tasks[t].convos.length; c++) {
                    if (
                        botkit.tasks[t].convos[c].isActive() &&
                        botkit.tasks[t].convos[c].source_message.user == message.user &&
                            botkit.tasks[t].convos[c].source_message.channel == message.channel
                    ) {
                        botkit.debug('FOUND EXISTING CONVO!');
                        cb(botkit.tasks[t].convos[c]);
                        return;
                    }
                }
            }
        }

        cb();
    };

    if (bot.config.incoming_webhook)
        bot.configureIncomingWebhook(config.incoming_webhook);

    if (bot.config.bot)
        bot.configureRTM(config.bot);

    return bot;
};
<|endoftext|>


<commit_before>var tilelive = require('..');
var url = require('url');
var fs = require('fs');
var Scheme = require('./scheme');

module.exports = CopyTask;
require('util').inherits(CopyTask, process.EventEmitter);
function CopyTask(from, to, scheme, job) {
    if (typeof from.getInfo === 'function') {
        this.source = from;
        from = 'temporary://';
    }
    if (typeof to.putInfo === 'function') {
        this.sink = to;
        to = 'temporary://';
    }
    this.from = typeof from === 'string' ? url.parse(from) : from;
    this.to = typeof to === 'string' ? url.parse(to) : to;
    this.scheme = scheme;
    this.started = null;
    this.ended = null;
    this.job = job || '/tmp/tilelive-' + (+new Date) + '.job';
    this.formats = [];
    this.cache = { tile: {}, grid: {} };
    this.initialize();
}

CopyTask.prototype.initialize = function() {
    var task = this;

    this.stats = this.scheme.stats;
    this.emit('progress', this.stats.snapshot());

    // Make sure this is non-enumerable;
    Object.defineProperty(this.scheme, 'task', { value: this });

    // State persistence
    console.warn('Persisting state in ' + this.job + ' every minute');

    // NOTE - This will no longer throw as of node v0.8.9
    // https://github.com/joyent/node/commit/ea1cba6246a8b1784e22d076139b9244a9ff42f8
    if ((process.platform !== 'win32')) {
        process.on('SIGINT', function() {
            task.pause(function(err) {
                if (err) throw err;
                console.warn('\nWrote state to ' + task.job);
            });
        });
    }
};

CopyTask.prototype.toJSON = function() {
    return {
        started: this.started,
        ended: this.ended,
        from: this.from,
        to: this.to,
        scheme: this.scheme
    };
};

CopyTask.prototype.finished = function() {
    var task = this;
    this.pause(function(err) {
        if (err) {
            if (err.stack) console.warn('\n' + err.stack);
            else console.warn('\n' + err.message);
        }
        task.emit('finished');
    });
};

CopyTask.prototype.pause = function(callback) {
    // Don't call the callback if already pausing as callers often
    // expect they are the only ones doing teardown operations.
    if (this.pausing) return;

    var task = this;
    this.pausing = true;

    this.scheme.once('paused', function() {
        clearInterval(task.progressInterval);
        clearInterval(task.stateInterval);
        task.emit('progress', task.stats.snapshot());

        task.sink.stopWriting(function(err) {
            task.ended = Date.now();
            task.emit('progress', task.stats.snapshot());
            if (err) return callback(err);
            fs.writeFile(task.job, JSON.stringify(task), function(err) {
                if (err) return callback(err);
                task.sink.close(function(err) {
                    if (err) return callback(err);
                    task.source.close(callback);
                });
            });
        });
    });

    this.scheme.pause();
};

CopyTask.prototype.start = function(callback) {
    callback = callback || new Function;

    var task = this
    if (!this.started) this.started = Date.now();

    this.progressInterval = setInterval(function() {
        task.emit('progress', task.stats.snapshot());
    }, 1000);

    this.stateInterval = setInterval(function() {
        fs.writeFile(task.job, JSON.stringify(task));
    }, 60000);

    var init = function() {
        if (!task.source) return tilelive.load(task.from, function(err, source) {
            if (err) return callback(err);
            task.source = source;
            init();
        });
        if (!task.formats.length) return task.source.getInfo(function(err, info) {
            if (err) return callback(err);
            // @TODO the tilelive API currently has no standard way
            // of determining whether a tilesource has tiles, grids
            // or both. See issue #44.
            task.formats.push('tile');
            // Use template as an indicator that grids are present.
            if (info.template) {
                task.formats.push('grid');
                task.stats.total = (task.stats.total || 0) * 2;
            }
            init();
        });
        if (!task.sink) return tilelive.load(task.to, function(err, sink) {
            if (err) return callback(err);
            task.sink = sink;
            init();
        });
        task.sink.startWriting(function(err) {
            if (err) return callback();

            // It is possible for a CopyTask to be paused before it
            // ever starts (SIGINT, exceptions, etc.) In these cases
            // respect the pause rather than forging ahead.
            if (task.pausing) return callback(null);

            task.scheme.start();
            callback(null);
        });
    };
    init();
};

CopyTask.prototype.render = function(tile, type) {
    var get = type === 'grid' ? 'getGrid' : 'getTile';
    var put = type === 'grid' ? 'putGrid' : 'putTile';
    var task = this;

    // If tile key is set and we have cached its buffer in memory,
    // skip rendering and use the existing buffer.
    if (tile.key !== false && task.cache[type][tile.key]) {
        var data = task.cache[type][tile.key];
        task.sink[put](tile.z, tile.x, tile.y, data, function(err) {
            if (err) {
                task.emit('error', err, tile);
                task.scheme.error(tile);
            } else {
                task.scheme.duplicate(tile);
            }
        });
    // Render the tile.
    } else {
        task.source[get](tile.z, tile.x, tile.y, function(err, data) {
            if (err) {
                if (err.message.match(/Tile|Grid does not exist/)) {
                    task.scheme.skip(tile);
                } else {
                    task.emit('error', err, tile);
                    task.scheme.error(tile);
                }
                return;
            }
            if (data.solid) switch(type) {
            case 'grid':
                // Empty grid.
                if (data.solid === '0') {
                    data.key = tile.key = 0;
                // String grid key.
                } else {
                    data.key = tile.key = data.solid;
                }
                task.cache[type][tile.key] = data;
                break;
            case 'tile':
                var color = data.solid.split(',');
                // Empty tile.
                if (color[3] === '0') {
                    data.key = tile.key = 0;
                // Negative encoded RGBA value.
                } else {
                    data.key = tile.key = -(color[0]*(1<<24) + ((color[1]<<16) | (color[2]<<8) | color[3]));
                }
                task.cache[type][tile.key] = data;
                break;
            }
            if (tile.key === 0) {
                task.scheme.skip(tile);
            } else {
                task.sink[put](tile.z, tile.x, tile.y, data, function(err) {
                    if (err) {
                        task.emit('error', err, tile);
                        task.scheme.error(tile);
                    } else if (tile.key === false) {
                        // This is a unique tile
                        task.scheme.unique(tile);
                    } else {
                        task.scheme.duplicate(tile);
                    }
                });
            }
        });
    }
};
<commit_msg>Pass on any errors when sink.startWriting<commit_after>var tilelive = require('..');
var url = require('url');
var fs = require('fs');
var Scheme = require('./scheme');

module.exports = CopyTask;
require('util').inherits(CopyTask, process.EventEmitter);
function CopyTask(from, to, scheme, job) {
    if (typeof from.getInfo === 'function') {
        this.source = from;
        from = 'temporary://';
    }
    if (typeof to.putInfo === 'function') {
        this.sink = to;
        to = 'temporary://';
    }
    this.from = typeof from === 'string' ? url.parse(from) : from;
    this.to = typeof to === 'string' ? url.parse(to) : to;
    this.scheme = scheme;
    this.started = null;
    this.ended = null;
    this.job = job || '/tmp/tilelive-' + (+new Date) + '.job';
    this.formats = [];
    this.cache = { tile: {}, grid: {} };
    this.initialize();
}

CopyTask.prototype.initialize = function() {
    var task = this;

    this.stats = this.scheme.stats;
    this.emit('progress', this.stats.snapshot());

    // Make sure this is non-enumerable;
    Object.defineProperty(this.scheme, 'task', { value: this });

    // State persistence
    console.warn('Persisting state in ' + this.job + ' every minute');

    // NOTE - This will no longer throw as of node v0.8.9
    // https://github.com/joyent/node/commit/ea1cba6246a8b1784e22d076139b9244a9ff42f8
    if ((process.platform !== 'win32')) {
        process.on('SIGINT', function() {
            task.pause(function(err) {
                if (err) throw err;
                console.warn('\nWrote state to ' + task.job);
            });
        });
    }
};

CopyTask.prototype.toJSON = function() {
    return {
        started: this.started,
        ended: this.ended,
        from: this.from,
        to: this.to,
        scheme: this.scheme
    };
};

CopyTask.prototype.finished = function() {
    var task = this;
    this.pause(function(err) {
        if (err) {
            if (err.stack) console.warn('\n' + err.stack);
            else console.warn('\n' + err.message);
        }
        task.emit('finished');
    });
};

CopyTask.prototype.pause = function(callback) {
    // Don't call the callback if already pausing as callers often
    // expect they are the only ones doing teardown operations.
    if (this.pausing) return;

    var task = this;
    this.pausing = true;

    this.scheme.once('paused', function() {
        clearInterval(task.progressInterval);
        clearInterval(task.stateInterval);
        task.emit('progress', task.stats.snapshot());

        task.sink.stopWriting(function(err) {
            task.ended = Date.now();
            task.emit('progress', task.stats.snapshot());
            if (err) return callback(err);
            fs.writeFile(task.job, JSON.stringify(task), function(err) {
                if (err) return callback(err);
                task.sink.close(function(err) {
                    if (err) return callback(err);
                    task.source.close(callback);
                });
            });
        });
    });

    this.scheme.pause();
};

CopyTask.prototype.start = function(callback) {
    callback = callback || new Function;

    var task = this
    if (!this.started) this.started = Date.now();

    this.progressInterval = setInterval(function() {
        task.emit('progress', task.stats.snapshot());
    }, 1000);

    this.stateInterval = setInterval(function() {
        fs.writeFile(task.job, JSON.stringify(task));
    }, 60000);

    var init = function() {
        if (!task.source) return tilelive.load(task.from, function(err, source) {
            if (err) return callback(err);
            task.source = source;
            init();
        });
        if (!task.formats.length) return task.source.getInfo(function(err, info) {
            if (err) return callback(err);
            // @TODO the tilelive API currently has no standard way
            // of determining whether a tilesource has tiles, grids
            // or both. See issue #44.
            task.formats.push('tile');
            // Use template as an indicator that grids are present.
            if (info.template) {
                task.formats.push('grid');
                task.stats.total = (task.stats.total || 0) * 2;
            }
            init();
        });
        if (!task.sink) return tilelive.load(task.to, function(err, sink) {
            if (err) return callback(err);
            task.sink = sink;
            init();
        });
        task.sink.startWriting(function(err) {
            if (err) return callback(err);

            // It is possible for a CopyTask to be paused before it
            // ever starts (SIGINT, exceptions, etc.) In these cases
            // respect the pause rather than forging ahead.
            if (task.pausing) return callback(null);

            task.scheme.start();
            callback(null);
        });
    };
    init();
};

CopyTask.prototype.render = function(tile, type) {
    var get = type === 'grid' ? 'getGrid' : 'getTile';
    var put = type === 'grid' ? 'putGrid' : 'putTile';
    var task = this;

    // If tile key is set and we have cached its buffer in memory,
    // skip rendering and use the existing buffer.
    if (tile.key !== false && task.cache[type][tile.key]) {
        var data = task.cache[type][tile.key];
        task.sink[put](tile.z, tile.x, tile.y, data, function(err) {
            if (err) {
                task.emit('error', err, tile);
                task.scheme.error(tile);
            } else {
                task.scheme.duplicate(tile);
            }
        });
    // Render the tile.
    } else {
        task.source[get](tile.z, tile.x, tile.y, function(err, data) {
            if (err) {
                if (err.message.match(/Tile|Grid does not exist/)) {
                    task.scheme.skip(tile);
                } else {
                    task.emit('error', err, tile);
                    task.scheme.error(tile);
                }
                return;
            }
            if (data.solid) switch(type) {
            case 'grid':
                // Empty grid.
                if (data.solid === '0') {
                    data.key = tile.key = 0;
                // String grid key.
                } else {
                    data.key = tile.key = data.solid;
                }
                task.cache[type][tile.key] = data;
                break;
            case 'tile':
                var color = data.solid.split(',');
                // Empty tile.
                if (color[3] === '0') {
                    data.key = tile.key = 0;
                // Negative encoded RGBA value.
                } else {
                    data.key = tile.key = -(color[0]*(1<<24) + ((color[1]<<16) | (color[2]<<8) | color[3]));
                }
                task.cache[type][tile.key] = data;
                break;
            }
            if (tile.key === 0) {
                task.scheme.skip(tile);
            } else {
                task.sink[put](tile.z, tile.x, tile.y, data, function(err) {
                    if (err) {
                        task.emit('error', err, tile);
                        task.scheme.error(tile);
                    } else if (tile.key === false) {
                        // This is a unique tile
                        task.scheme.unique(tile);
                    } else {
                        task.scheme.duplicate(tile);
                    }
                });
            }
        });
    }
};
<|endoftext|>


<commit_before>var path = require('path'),
    argv = require('yargs').argv;

var playgroundPath = __dirname,
    cwd = process.cwd();

var getAbsPath = function(relativePath) {
  return path.join(cwd, relativePath);
};

module.exports = {
  entry: path.join(playgroundPath, 'entry.js'),
  resolve: {
    alias: {
      components: getAbsPath(argv.componentsPath || 'components'),
      fixtures: getAbsPath(argv.fixturesPath || 'fixtures')
    },
    extensions: ['', '.js', '.jsx']
  },
  module: {
    loaders: [{
      test: /\.jsx?$/,
      exclude: /node_modules/,
      loader: 'jsx-loader?harmony'
    }, {
      test: /\.css$/,
      loader: 'style-loader!css-loader'
    }, {
      test: /\.less$/,
      loader: 'style-loader!css-loader!less-loader'
    }]
  },
  output: {
    libraryTarget: 'umd',
    library: 'cosmosRouter',
    path: path.join(playgroundPath, 'public', 'build'),
    filename: 'bundle.js'
  }
};
<commit_msg>Load loaders from the cosmos module (for now) #115<commit_after>var path = require('path'),
    argv = require('yargs').argv;

var playgroundPath = __dirname,
    rootPath = path.join(playgroundPath, '..'),
    modulesPath = path.join(rootPath, 'node_modules'),
    cwd = process.cwd();

var getAbsPath = function(relativePath) {
  return path.join(cwd, relativePath);
};

module.exports = {
  entry: path.join(playgroundPath, 'entry.js'),
  resolve: {
    alias: {
      components: getAbsPath(argv.componentsPath || 'components'),
      fixtures: getAbsPath(argv.fixturesPath || 'fixtures')
    },
    extensions: ['', '.js', '.jsx']
  },
  resolveLoader: {
    root: modulesPath
  },
  module: {
    loaders: [{
      test: /\.jsx?$/,
      exclude: /node_modules/,
      loader: 'jsx-loader?harmony'
    }, {
      test: /\.css$/,
      loader: 'style-loader!css-loader'
    }, {
      test: /\.less$/,
      loader: 'style-loader!css-loader!less-loader'
    }]
  },
  output: {
    libraryTarget: 'umd',
    library: 'cosmosRouter',
    path: path.join(playgroundPath, 'public', 'build'),
    filename: 'bundle.js'
  }
};
<|endoftext|>


<commit_before>var XSD_INTEGER = 'http://www.w3.org/2001/XMLSchema#integer';

module.exports = function SparqlGenerator() { return { stringify: toQuery }; };

// Converts the parsed query object into a SPARQL query
function toQuery(q) {
  var query = '';
  for (var key in q.prefixes)
    query += 'PREFIX ' + key + ': <' + q.prefixes[key] + '>\n';

  if (q.queryType)
    query += q.queryType.toUpperCase() + ' ';
  if (q.reduced)
    query += 'REDUCED ';
  if (q.distinct)
    query += 'DISTINCT ';

  if (q.variables)
    query += mapJoin(q.variables, function (variable) {
      return isString(variable) ? toEntity(variable) :
             '(' + toExpression(variable.expression) + ' AS ' + variable.variable + ')';
    }) + ' ';
  else if (q.template)
    query += patterns.group(q.template, true) + '\n';

  if (q.from)
    query += mapJoin(q.from.default || [], function (g) { return 'FROM ' + toEntity(g) + '\n'; }, '') +
             mapJoin(q.from.named || [], function (g) { return 'FROM NAMED ' + toEntity(g) + '\n'; }, '');
  if (q.where)
    query += 'WHERE ' + patterns.group(q.where, true)  + '\n';

  if (q.updates)
    query += mapJoin(q.updates, toUpdate, ';\n');
  else if (q.values)
    query += patterns.values(q);

  if (q.group)
    query += 'GROUP BY ' + mapJoin(q.group, function (it) {
      return isString(it.expression) ? it.expression : '(' + toExpression(it.expression) + ')';
    }) + '\n';
  if (q.having)
    query += 'HAVING (' + mapJoin(q.having, toExpression) + ')\n';
  if (q.order)
    query += 'ORDER BY ' + mapJoin(q.order, function (it) {
      var expr = toExpression(it.expression);
      return !it.descending ? expr : 'DESC(' + expr + ')';
    }) + '\n';

  if (q.offset)
    query += 'OFFSET ' + q.offset + '\n';
  if (q.limit)
    query += 'LIMIT ' + q.limit + '\n';
  return query.trim();
}

// Converts the parsed SPARQL pattern into a SPARQL pattern
function toPattern(pattern) {
  var type = pattern.type || (pattern instanceof Array) && 'array' ||
             (pattern.subject && pattern.predicate && pattern.object ? 'triple' : '');
  if (!(type in patterns))
    throw new Error('Unknown entry type: ' + type);
  return patterns[type](pattern);
}
var patterns = {
  triple: function (t) {
    return toEntity(t.subject) + ' ' + toEntity(t.predicate) + ' ' + toEntity(t.object) + '.';
  },
  array: function (items) {
    return mapJoin(items, toPattern, '\n');
  },
  bgp: function (bgp) {
    return mapJoin(bgp.triples, patterns.triple, '\n');
  },
  graph: function (graph) {
    return 'GRAPH ' + toEntity(graph.name) + ' ' + patterns.group(graph);
  },
  group: function (group, inline) {
    group = inline !== true ? patterns.array(group.patterns || group.triples)
                            : toPattern(group.type !== 'group' ? group : group.patterns);
    return group.indexOf('\n') === -1 ? '{ ' + group + ' }' : '{\n' + indent(group) + '\n}';
  },
  query: function (query) {
    return '{\n' + indent(toQuery(query)) + '\n}';
  },
  filter: function (filter) {
    return 'FILTER(' + toExpression(filter.expression) + ')';
  },
  bind: function (bind) {
    return 'BIND(' + toExpression(bind.expression) + ' AS ' + bind.variable + ')';
  },
  optional: function (optional) {
    return 'OPTIONAL ' + patterns.group(optional);
  },
  union: function (union) {
    return mapJoin(union.patterns, function (p) { return patterns.group(p, true); }, '\nUNION\n');
  },
  minus: function (minus) {
    return 'MINUS ' + patterns.group(minus);
  },
  values: function (valuesList) {
    // Gather unique keys
    var keys = Object.keys(valuesList.values.reduce(function (keyHash, values) {
      for (var key in values) keyHash[key] = true;
      return keyHash;
    }, {}));
    // Create value rows
    return 'VALUES (' + keys.join(' ') + ') {\n' +
      mapJoin(valuesList.values, function (values) {
        return '  (' + mapJoin(keys, function (key) {
          return values[key] !== undefined ? toEntity(values[key]) : 'UNDEF';
        }) + ')';
      }, '\n') + '\n}';
  },
  service: function (service) {
    return 'SERVICE ' + (service.silent ? 'SILENT ' : '') + toEntity(service.name) + ' ' +
           patterns.group(service);
  },
};

// Converts the parsed expression object into a SPARQL expression
function toExpression(expr) {
  if (isString(expr))
    return toEntity(expr);

  switch (expr.type.toLowerCase()) {
    case 'aggregate':
      return expr.aggregation.toUpperCase() +
             '(' + (expr.distinct ? 'DISTINCT ' : '') + toExpression(expr.expression) +
             (expr.separator ? '; SEPARATOR = ' + toEntity('"' + expr.separator + '"') : '') + ')';
    case 'functioncall':
      return toEntity(expr.function) + '(' + mapJoin(expr.args, toExpression, ', ') + ')';
    case 'operation':
      var operator = expr.operator.toUpperCase(), args = expr.args || [], arg = args[0];
      switch (expr.operator.toLowerCase()) {
      // Infix operators
      case '<':
      case '>':
      case '>=':
      case '<=':
      case '&&':
      case '||':
      case '=':
      case '!=':
      case '+':
      case '-':
      case '*':
      case '/':
        return mapJoin(args, function (arg) {
          return isString(arg) ? toEntity(arg) : '(' + toExpression(arg) + ')';
        }, ' ' + operator + ' ');
      // Unary operators
      case '!':
        return '!' + toExpression(arg);
      // IN and NOT IN
      case 'notin':
        operator = 'NOT IN';
      case 'in':
        return toExpression(arg) + ' ' + operator +
               '(' + (isString(arg = args[1]) ? arg : mapJoin(arg, toExpression, ', ')) + ')';
      // EXISTS and NOT EXISTS
      case 'notexists':
        operator = 'NOT EXISTS';
      case 'exists':
        return operator + ' ' + patterns.group(arg, true);
      // Other expressions
      default:
        return operator + '(' + mapJoin(args, toExpression, ', ') + ')';
      }
    default:
      throw new Error('Unknown expression type: ' + expr.type);
  }
}

// Converts the parsed entity (or property path) into a SPARQL entity
function toEntity(value) {
  // regular entity
  if (isString(value)) {
    switch (value[0]) {
    // variable, * selector, or blank node
    case '?':
    case '$':
    case '*':
    case '_':
      return value;
    // literal
    case '"':
      var match = value.match(/^"(.*)"(?:(@.+)|\^\^(.+))?$/) || {},
          lexical = match[1] || '', language = match[2] || '', datatype = match[3];
      value = '"' + lexical.replace(escape, escapeReplacer) + '"' + language;
      if (datatype) {
        if (datatype === XSD_INTEGER && /^\d+$/.test(lexical)) return lexical;
        value += '^^<' + datatype + '>';
      }
      return value;
    // IRI
    default:
      return '<' + value + '>';
    }
  }
  // property path
  else {
    var items = value.items.map(toEntity), path = value.pathType;
    switch (path) {
    // prefix operator
    case '^':
    case '!':
      return path + items[0];
    // postfix operator
    case '*':
    case '+':
    case '?':
      return items[0] + path;
    // infix operator
    default:
      return '(' + items.join(path) + ')';
    }
  }
}
var escape = /["\\\t\n\r\b\f]/g,
    escapeReplacer = function (c) { return escapeReplacements[c]; },
    escapeReplacements = { '\\': '\\\\', '"': '\\"', '\t': '\\t',
                           '\n': '\\n', '\r': '\\r', '\b': '\\b', '\f': '\\f' };

// Converts the parsed update object into a SPARQL update clause
function toUpdate(update) {
  switch (update.type || update.updateType) {
  case 'load':
    return 'LOAD' + (update.source ? ' ' + toEntity(update.source) : '') +
           (update.destination ? ' INTO GRAPH ' + toEntity(update.destination) : '');
  case 'insert':
    return 'INSERT DATA '  + patterns.group(update.insert, true);
  case 'delete':
    return 'DELETE DATA '  + patterns.group(update.delete, true);
  case 'deletewhere':
    return 'DELETE WHERE ' + patterns.group(update.delete, true);
  case 'insertdelete':
    return (update.graph ? 'WITH ' + toEntity(update.graph) + '\n' : '') +
           (update.delete.length ? 'DELETE ' + patterns.group(update.delete, true) + '\n' : '') +
           (update.insert.length ? 'INSERT ' + patterns.group(update.insert, true) + '\n' : '') +
           'WHERE ' + patterns.group(update.where, true);
  case 'add':
  case 'copy':
  case 'move':
    return update.type.toUpperCase() + (update.source.default ? ' DEFAULT ' : ' ') +
           'TO ' + toEntity(update.destination.name);
  default:
    throw new Error('Unknown update query type: ' + update.type);
  }
}

// Checks whether the object is a string
function isString(object) { return typeof object === 'string'; }

// Maps the array with the given function, and joins the results using the separator
function mapJoin(array, func, sep) { return array.map(func).join(isString(sep) ? sep : ' '); }

// Indents each line of the string
function indent(text) { return text.replace(/^/gm, '  '); }
<commit_msg>add a space before dot so the generated sparql can be used with Virtuoso<commit_after>var XSD_INTEGER = 'http://www.w3.org/2001/XMLSchema#integer';

module.exports = function SparqlGenerator() { return { stringify: toQuery }; };

// Converts the parsed query object into a SPARQL query
function toQuery(q) {
  var query = '';
  for (var key in q.prefixes)
    query += 'PREFIX ' + key + ': <' + q.prefixes[key] + '>\n';

  if (q.queryType)
    query += q.queryType.toUpperCase() + ' ';
  if (q.reduced)
    query += 'REDUCED ';
  if (q.distinct)
    query += 'DISTINCT ';

  if (q.variables)
    query += mapJoin(q.variables, function (variable) {
      return isString(variable) ? toEntity(variable) :
             '(' + toExpression(variable.expression) + ' AS ' + variable.variable + ')';
    }) + ' ';
  else if (q.template)
    query += patterns.group(q.template, true) + '\n';

  if (q.from)
    query += mapJoin(q.from.default || [], function (g) { return 'FROM ' + toEntity(g) + '\n'; }, '') +
             mapJoin(q.from.named || [], function (g) { return 'FROM NAMED ' + toEntity(g) + '\n'; }, '');
  if (q.where)
    query += 'WHERE ' + patterns.group(q.where, true)  + '\n';

  if (q.updates)
    query += mapJoin(q.updates, toUpdate, ';\n');
  else if (q.values)
    query += patterns.values(q);

  if (q.group)
    query += 'GROUP BY ' + mapJoin(q.group, function (it) {
      return isString(it.expression) ? it.expression : '(' + toExpression(it.expression) + ')';
    }) + '\n';
  if (q.having)
    query += 'HAVING (' + mapJoin(q.having, toExpression) + ')\n';
  if (q.order)
    query += 'ORDER BY ' + mapJoin(q.order, function (it) {
      var expr = toExpression(it.expression);
      return !it.descending ? expr : 'DESC(' + expr + ')';
    }) + '\n';

  if (q.offset)
    query += 'OFFSET ' + q.offset + '\n';
  if (q.limit)
    query += 'LIMIT ' + q.limit + '\n';
  return query.trim();
}

// Converts the parsed SPARQL pattern into a SPARQL pattern
function toPattern(pattern) {
  var type = pattern.type || (pattern instanceof Array) && 'array' ||
             (pattern.subject && pattern.predicate && pattern.object ? 'triple' : '');
  if (!(type in patterns))
    throw new Error('Unknown entry type: ' + type);
  return patterns[type](pattern);
}
var patterns = {
  triple: function (t) {
    return toEntity(t.subject) + ' ' + toEntity(t.predicate) + ' ' + toEntity(t.object) + ' .';
  },
  array: function (items) {
    return mapJoin(items, toPattern, '\n');
  },
  bgp: function (bgp) {
    return mapJoin(bgp.triples, patterns.triple, '\n');
  },
  graph: function (graph) {
    return 'GRAPH ' + toEntity(graph.name) + ' ' + patterns.group(graph);
  },
  group: function (group, inline) {
    group = inline !== true ? patterns.array(group.patterns || group.triples)
                            : toPattern(group.type !== 'group' ? group : group.patterns);
    return group.indexOf('\n') === -1 ? '{ ' + group + ' }' : '{\n' + indent(group) + '\n}';
  },
  query: function (query) {
    return '{\n' + indent(toQuery(query)) + '\n}';
  },
  filter: function (filter) {
    return 'FILTER(' + toExpression(filter.expression) + ')';
  },
  bind: function (bind) {
    return 'BIND(' + toExpression(bind.expression) + ' AS ' + bind.variable + ')';
  },
  optional: function (optional) {
    return 'OPTIONAL ' + patterns.group(optional);
  },
  union: function (union) {
    return mapJoin(union.patterns, function (p) { return patterns.group(p, true); }, '\nUNION\n');
  },
  minus: function (minus) {
    return 'MINUS ' + patterns.group(minus);
  },
  values: function (valuesList) {
    // Gather unique keys
    var keys = Object.keys(valuesList.values.reduce(function (keyHash, values) {
      for (var key in values) keyHash[key] = true;
      return keyHash;
    }, {}));
    // Create value rows
    return 'VALUES (' + keys.join(' ') + ') {\n' +
      mapJoin(valuesList.values, function (values) {
        return '  (' + mapJoin(keys, function (key) {
          return values[key] !== undefined ? toEntity(values[key]) : 'UNDEF';
        }) + ')';
      }, '\n') + '\n}';
  },
  service: function (service) {
    return 'SERVICE ' + (service.silent ? 'SILENT ' : '') + toEntity(service.name) + ' ' +
           patterns.group(service);
  },
};

// Converts the parsed expression object into a SPARQL expression
function toExpression(expr) {
  if (isString(expr))
    return toEntity(expr);

  switch (expr.type.toLowerCase()) {
    case 'aggregate':
      return expr.aggregation.toUpperCase() +
             '(' + (expr.distinct ? 'DISTINCT ' : '') + toExpression(expr.expression) +
             (expr.separator ? '; SEPARATOR = ' + toEntity('"' + expr.separator + '"') : '') + ')';
    case 'functioncall':
      return toEntity(expr.function) + '(' + mapJoin(expr.args, toExpression, ', ') + ')';
    case 'operation':
      var operator = expr.operator.toUpperCase(), args = expr.args || [], arg = args[0];
      switch (expr.operator.toLowerCase()) {
      // Infix operators
      case '<':
      case '>':
      case '>=':
      case '<=':
      case '&&':
      case '||':
      case '=':
      case '!=':
      case '+':
      case '-':
      case '*':
      case '/':
        return mapJoin(args, function (arg) {
          return isString(arg) ? toEntity(arg) : '(' + toExpression(arg) + ')';
        }, ' ' + operator + ' ');
      // Unary operators
      case '!':
        return '!' + toExpression(arg);
      // IN and NOT IN
      case 'notin':
        operator = 'NOT IN';
      case 'in':
        return toExpression(arg) + ' ' + operator +
               '(' + (isString(arg = args[1]) ? arg : mapJoin(arg, toExpression, ', ')) + ')';
      // EXISTS and NOT EXISTS
      case 'notexists':
        operator = 'NOT EXISTS';
      case 'exists':
        return operator + ' ' + patterns.group(arg, true);
      // Other expressions
      default:
        return operator + '(' + mapJoin(args, toExpression, ', ') + ')';
      }
    default:
      throw new Error('Unknown expression type: ' + expr.type);
  }
}

// Converts the parsed entity (or property path) into a SPARQL entity
function toEntity(value) {
  // regular entity
  if (isString(value)) {
    switch (value[0]) {
    // variable, * selector, or blank node
    case '?':
    case '$':
    case '*':
    case '_':
      return value;
    // literal
    case '"':
      var match = value.match(/^"(.*)"(?:(@.+)|\^\^(.+))?$/) || {},
          lexical = match[1] || '', language = match[2] || '', datatype = match[3];
      value = '"' + lexical.replace(escape, escapeReplacer) + '"' + language;
      if (datatype) {
        if (datatype === XSD_INTEGER && /^\d+$/.test(lexical)) return lexical;
        value += '^^<' + datatype + '>';
      }
      return value;
    // IRI
    default:
      return '<' + value + '>';
    }
  }
  // property path
  else {
    var items = value.items.map(toEntity), path = value.pathType;
    switch (path) {
    // prefix operator
    case '^':
    case '!':
      return path + items[0];
    // postfix operator
    case '*':
    case '+':
    case '?':
      return items[0] + path;
    // infix operator
    default:
      return '(' + items.join(path) + ')';
    }
  }
}
var escape = /["\\\t\n\r\b\f]/g,
    escapeReplacer = function (c) { return escapeReplacements[c]; },
    escapeReplacements = { '\\': '\\\\', '"': '\\"', '\t': '\\t',
                           '\n': '\\n', '\r': '\\r', '\b': '\\b', '\f': '\\f' };

// Converts the parsed update object into a SPARQL update clause
function toUpdate(update) {
  switch (update.type || update.updateType) {
  case 'load':
    return 'LOAD' + (update.source ? ' ' + toEntity(update.source) : '') +
           (update.destination ? ' INTO GRAPH ' + toEntity(update.destination) : '');
  case 'insert':
    return 'INSERT DATA '  + patterns.group(update.insert, true);
  case 'delete':
    return 'DELETE DATA '  + patterns.group(update.delete, true);
  case 'deletewhere':
    return 'DELETE WHERE ' + patterns.group(update.delete, true);
  case 'insertdelete':
    return (update.graph ? 'WITH ' + toEntity(update.graph) + '\n' : '') +
           (update.delete.length ? 'DELETE ' + patterns.group(update.delete, true) + '\n' : '') +
           (update.insert.length ? 'INSERT ' + patterns.group(update.insert, true) + '\n' : '') +
           'WHERE ' + patterns.group(update.where, true);
  case 'add':
  case 'copy':
  case 'move':
    return update.type.toUpperCase() + (update.source.default ? ' DEFAULT ' : ' ') +
           'TO ' + toEntity(update.destination.name);
  default:
    throw new Error('Unknown update query type: ' + update.type);
  }
}

// Checks whether the object is a string
function isString(object) { return typeof object === 'string'; }

// Maps the array with the given function, and joins the results using the separator
function mapJoin(array, func, sep) { return array.map(func).join(isString(sep) ? sep : ' '); }

// Indents each line of the string
function indent(text) { return text.replace(/^/gm, '  '); }
<|endoftext|>


<commit_before>var Db = require('../odm/db')
var db = new Db('mongodb://localhost/game')
db.model('weapons', {name: String})
<commit_msg>weaponSchema is all working<commit_after>var Db = require('../odm/db')
var db = new Db('mongodb://localhost/game')
var weaponSchema = require('./Weapon')
db.model('weapons', weaponSchema)
<|endoftext|>