<commit_before>var path = require('path');
var Database = require('../../database').Database;
var Domain = require('../../domain').Domain;
var Deferred = require('jsdeferred').Deferred;
var dateFormat = require('dateformat');

exports.version = path.basename(__dirname);

var XMLNS = 'http://cloudsearch.amazonaws.com/doc/2011-02-01';
var FAKE_DOMAIN_ID = '00000000000000000000000000';

function createCommonErrorResponse(errorCode, message) {
  return '<?xml version="1.0"?>\n' +
         '<Response>' +
           '<Errors>' +
             '<Error>' + errorCode +'' +
                     '<Message>' + message + '</Message></Error>' +
             '</Errors>' +
           '<RequestID></RequestID>' +
         '</Response>';
}

var handlers = Object.create(null);

function getBaseDomain(domain) {
  return domain.replace(/^cloudsearch\./, '');
}

function createDomainStatus(options) {
  return '<DomainStatus>' +
           '<Created>' + (options.created || 'false') + '</Created>' +
           '<Deleted>' + (options.deleted || 'false') + '</Deleted>' +
           '<DocService>' +
             '<Endpoint>' + (options.documentsEndpoint || '') + '</Endpoint>' +
           '</DocService>' +
           '<DomainId>' + options.domainId + '/' + options.domainName +
             '</DomainId>' +
           '<DomainName>' + options.domainName + '</DomainName>' +
           '<NumSearchableDocs>' + (options.searchableDocumentsCount || 0) +
             '</NumSearchableDocs>' +
           '<RequiresIndexDocuments>' +
             (options.requiresIndexDocuments || 'false') +
             '</RequiresIndexDocuments>' +
           '<SearchInstanceCount>' + (options.searchInstanceCount || 0) +
             '</SearchInstanceCount>' +
           '<SearchPartitionCount>' + (options.searchPartitionCount || 0) +
             '</SearchPartitionCount>' +
           '<SearchService>' +
             '<Endpoint>' + (options.searchEndpoint || '') + '</Endpoint>' +
           '</SearchService>' +
         '</DomainStatus>';
}

function createCreateDomainResponse(options) {
  return '<?xml version="1.0"?>\n' +
         '<CreateDomainResponse xmlns="' + XMLNS + '">' +
           '<CreateDomainResult>' +
             createDomainStatus(options) +
           '</CreateDomainResult>' +
           '<ResponseMetadata>' +
             '<RequestId>' + (options.requestId || '') + '</RequestId>' +
           '</ResponseMetadata>' +
         '</CreateDomainResponse>';
}

handlers.CreateDomain = function(database, request, response) {
  var domain = new Domain(request);
  var options = {
        name: domain.tableName,
        flags: Database.TABLE_HASH_KEY,
        key_type: Database.ShortText
      };
  database.commandDeferred('table_create', options)
    .next(function(data) {
      var termsOptions = {
            name: domain.termsTableName,
            flags: Database.TABLE_PAT_KEY + '|' + Database.KEY_NORMALIZE,
            key_type: Database.ShortText,
            default_tokenizer: Database.TokenBigram
          };
      return database.commandDeferred('table_create', termsOptions);
    })
    .next(function(data) {
      var host = getBaseDomain(request.headers.host);
      host = host ? '.' + host : '';
      response.contentType('application/xml');
      response.send(createCreateDomainResponse({
        domainName: domain.name,
        domainId: FAKE_DOMAIN_ID,
        searchEndpoint: 'search-' + domain.name + '-' + FAKE_DOMAIN_ID + host,
        documentsEndpoint: 'doc-' + domain.name + '-' + FAKE_DOMAIN_ID + host,
        created: true,
        searchableDocumentsCount: 0,
        searchInstanceCount: 0,
        searchPartitionCount: 0,
        requiresIndexDocuments: false
      }));
    })
    .error(function(error) {
      var body = createCommonErrorResponse('InternalFailure', error.message);
      response.contentType('application/xml');
      return response.send(body, 400);
    });
};

function createDeleteDomainResponse(options) {
  return '<?xml version="1.0"?>\n' +
         '<DeleteDomainResponse xmlns="' + XMLNS + '">' +
           '<DeleteDomainResult>' +
             createDomainStatus(options) +
           '</DeleteDomainResult>' +
           '<ResponseMetadata>' +
             '<RequestId>' + (options.requestId || '') + '</RequestId>' +
           '</ResponseMetadata>' +
         '</DeleteDomainResponse>';
}

handlers.DeleteDomain = function(database, request, response) {
  var domain = new Domain(request);
  var options = {
        name: domain.tableName
      };
  database.commandDeferred('table_remove', options)
    .next(function(data) {
      var termsOptions = {
            name: domain.termsTableName
          };
      return database.commandDeferred('table_remove', termsOptions);
    })
    .next(function(data) {
      var host = getBaseDomain(request.headers.host);
      host = host ? '.' + host : '';
      response.contentType('application/xml');
      response.send(createDeleteDomainResponse({
        domainName: domain.name,
        domainId: FAKE_DOMAIN_ID,
        searchEndpoint: 'search-' + domain.name + '-' + FAKE_DOMAIN_ID + host,
        documentsEndpoint: 'doc-' + domain.name + '-' + FAKE_DOMAIN_ID + host,
        deleted: true,
        searchableDocumentsCount: 0,
        searchInstanceCount: 0,
        searchPartitionCount: 0,
        requiresIndexDocuments: false
      }));
    })
    .error(function(error) {
      var body = createCommonErrorResponse('InternalFailure', error.message);
      response.contentType('application/xml');
      return response.send(body, 400);
    });
};

function createIndexFieldStatus(options) {
  return '<IndexField>' +
           '<Options>' +
             '<IndexFieldName>' + options.fieldName + '</IndexFieldName>' +
             '<IndexFieldType>' + options.fieldType + '</IndexFieldType>' +
             '<TextOptions>' +
               '<DefaultValue/>' +
               '<FacetEnabled>' + (options.facetEnabled || false) +
                 '</FacetEnabled>' +
               '<ResultEnabled>' + (options.resultEnabled || false) +
                 '</ResultEnabled>' +
             '</TextOptions>' +
           '</Options>' +
           '<Status>' +
             '<CreationDate>' + dateFormat(options.createdAt,
                                           'isoUtcDateTime') +
               '</CreationDate>' +
             '<State>' + options.state + '</State>' +
             '<UpdateDate>' + dateFormat(options.updatedAt, 'isoUtcDateTime') +
               '</UpdateDate>' +
             '<UpdateVersion>' + (options.updateVersion || 0) +
               '</UpdateVersion>' +
           '</Status>' +
         '</IndexField>';
}

function createDefineIndexFieldResponse(options) {
  return '<?xml version="1.0"?>\n' +
         '<DefineIndexFieldResponse xmlns="' + XMLNS + '">' +
           '<DefineIndexFieldResult>' +
             createIndexFieldStatus(options) +
           '</DefineIndexFieldResult>' +
           '<ResponseMetadata>' +
             '<RequestId>' + (options.requestId || '') + '</RequestId>' +
           '</ResponseMetadata>' +
         '</DefineIndexFieldResponse>';
}

handlers.DefineIndexField = function(database, request, response) {
  var domain = new Domain(request);

  var fieldName = request.query['IndexField.IndexFieldName'] || '';
  var field = domain.getIndexField(fieldName);

  var createdAt = new Date();
  var options = {
        table: domain.tableName,
        name: field.columnName,
        flags: Database.COLUMN_SCALAR,
        type: Database.ShortText
      };
  database.commandDeferred('column_create', options)
    .next(function(data) {
      var termsOptions = {
            table: domain.termsTableName,
            name: field.indexColumnName,
            flags: Database.COLUMN_INDEX + '|' + Database.WITH_POSITION,
            type: domain.tableName,
            source: field.columnName
          };
      return database.commandDeferred('column_create', termsOptions);
    })
    .next(function() {
      response.contentType('application/xml');
      response.send(createDefineIndexFieldResponse({
        fieldName: fieldName,
        fieldType: 'text',
        facetEnabled: false,
        resultEnabled: true,
        state: 'RequiresIndexDocuments',
        createdAt: createdAt,
        updatedAt: createdAt
      }));
    })
    .error(function(error) {
      var body = createCommonErrorResponse('InternalFailure', error.message);
      response.contentType('application/xml');
      return response.send(body, 400);
    });
};

function createDeleteIndexFieldResponse(options) {
  return '<?xml version="1.0"?>\n' +
         '<DeleteIndexFieldResponse xmlns="' + XMLNS + '">' +
           '<DeleteIndexFieldResult/>' +
           '<ResponseMetadata>' +
             '<RequestId>' + (options.requestId || '') + '</RequestId>' +
           '</ResponseMetadata>' +
         '</DeleteIndexFieldResponse>';
}

handlers.DeleteIndexField = function(database, request, response) {
  var domain = new Domain(request);

  var fieldName = request.query['IndexFieldName'] || '';
  var field = domain.getIndexField(fieldName);

  var options = {
        table: domain.tableName,
        name: field.columnName
      };
  database.commandDeferred('column_remove', options)
    .next(function() {
      response.contentType('application/xml');
      response.send(createDeleteIndexFieldResponse({}));
    })
    .error(function(error) {
      var body = createCommonErrorResponse('InternalFailure', error.message);
      response.contentType('application/xml');
      return response.send(body, 400);
    });
};

exports.createHandler = function(database) {
  return function(request, response, next) {
    var message, body;

    // GCS specific behaviour: fallback to other handlers for the endpoint
    // if no action is given.
    var action = request.query.Action || '';
    if (!action)
      return next();

    var version = request.query.Version;
    if (!version) {
      message = 'An input parameter "Version" that is mandatory for ' +
                'processing the request is not supplied.';
      body = createCommonErrorResponse('MissingParameter', message);
      response.contentType('application/xml');
      return response.send(body, 400);
    }

    if (version != exports.version) {
      message = 'A bad or out-of-range value "' + version + '" was supplied ' +
                'for the "Version" input parameter.';
      body = createCommonErrorResponse('InvalidParameterValue', message);
      response.contentType('application/xml');
      return response.send(body, 400);
    }

    if (!(action in handlers)) {
      message = 'The action ' + action + ' is not valid for this web service.';
      body = createCommonErrorResponse('InvalidAction', message);
      response.contentType('application/xml');
      return response.send(body, 400);
    }

    var handler = handlers[action];
    handler(database, request, response);
  };
};
<commit_msg>Make DeleteDomain synchronous<commit_after>var path = require('path');
var Database = require('../../database').Database;
var Domain = require('../../domain').Domain;
var Deferred = require('jsdeferred').Deferred;
var dateFormat = require('dateformat');

exports.version = path.basename(__dirname);

var XMLNS = 'http://cloudsearch.amazonaws.com/doc/2011-02-01';
var FAKE_DOMAIN_ID = '00000000000000000000000000';

function createCommonErrorResponse(errorCode, message) {
  return '<?xml version="1.0"?>\n' +
         '<Response>' +
           '<Errors>' +
             '<Error>' + errorCode +'' +
                     '<Message>' + message + '</Message></Error>' +
             '</Errors>' +
           '<RequestID></RequestID>' +
         '</Response>';
}

var handlers = Object.create(null);

function getBaseDomain(domain) {
  return domain.replace(/^cloudsearch\./, '');
}

function createDomainStatus(options) {
  return '<DomainStatus>' +
           '<Created>' + (options.created || 'false') + '</Created>' +
           '<Deleted>' + (options.deleted || 'false') + '</Deleted>' +
           '<DocService>' +
             '<Endpoint>' + (options.documentsEndpoint || '') + '</Endpoint>' +
           '</DocService>' +
           '<DomainId>' + options.domainId + '/' + options.domainName +
             '</DomainId>' +
           '<DomainName>' + options.domainName + '</DomainName>' +
           '<NumSearchableDocs>' + (options.searchableDocumentsCount || 0) +
             '</NumSearchableDocs>' +
           '<RequiresIndexDocuments>' +
             (options.requiresIndexDocuments || 'false') +
             '</RequiresIndexDocuments>' +
           '<SearchInstanceCount>' + (options.searchInstanceCount || 0) +
             '</SearchInstanceCount>' +
           '<SearchPartitionCount>' + (options.searchPartitionCount || 0) +
             '</SearchPartitionCount>' +
           '<SearchService>' +
             '<Endpoint>' + (options.searchEndpoint || '') + '</Endpoint>' +
           '</SearchService>' +
         '</DomainStatus>';
}

function createCreateDomainResponse(options) {
  return '<?xml version="1.0"?>\n' +
         '<CreateDomainResponse xmlns="' + XMLNS + '">' +
           '<CreateDomainResult>' +
             createDomainStatus(options) +
           '</CreateDomainResult>' +
           '<ResponseMetadata>' +
             '<RequestId>' + (options.requestId || '') + '</RequestId>' +
           '</ResponseMetadata>' +
         '</CreateDomainResponse>';
}

handlers.CreateDomain = function(database, request, response) {
  var domain = new Domain(request);
  var options = {
        name: domain.tableName,
        flags: Database.TABLE_HASH_KEY,
        key_type: Database.ShortText
      };
  database.commandDeferred('table_create', options)
    .next(function(data) {
      var termsOptions = {
            name: domain.termsTableName,
            flags: Database.TABLE_PAT_KEY + '|' + Database.KEY_NORMALIZE,
            key_type: Database.ShortText,
            default_tokenizer: Database.TokenBigram
          };
      return database.commandDeferred('table_create', termsOptions);
    })
    .next(function(data) {
      var host = getBaseDomain(request.headers.host);
      host = host ? '.' + host : '';
      response.contentType('application/xml');
      response.send(createCreateDomainResponse({
        domainName: domain.name,
        domainId: FAKE_DOMAIN_ID,
        searchEndpoint: 'search-' + domain.name + '-' + FAKE_DOMAIN_ID + host,
        documentsEndpoint: 'doc-' + domain.name + '-' + FAKE_DOMAIN_ID + host,
        created: true,
        searchableDocumentsCount: 0,
        searchInstanceCount: 0,
        searchPartitionCount: 0,
        requiresIndexDocuments: false
      }));
    })
    .error(function(error) {
      var body = createCommonErrorResponse('InternalFailure', error.message);
      response.contentType('application/xml');
      return response.send(body, 400);
    });
};

function createDeleteDomainResponse(options) {
  return '<?xml version="1.0"?>\n' +
         '<DeleteDomainResponse xmlns="' + XMLNS + '">' +
           '<DeleteDomainResult>' +
             createDomainStatus(options) +
           '</DeleteDomainResult>' +
           '<ResponseMetadata>' +
             '<RequestId>' + (options.requestId || '') + '</RequestId>' +
           '</ResponseMetadata>' +
         '</DeleteDomainResponse>';
}

handlers.DeleteDomain = function(database, request, response) {
  var domain = new Domain(request);
  try {
    database.commandSync('table_remove', {
      name: domain.tableName
    });
    database.commandSync('table_remove', {
      name: domain.termsTableName
    });
    var host = getBaseDomain(request.headers.host);
    host = host ? '.' + host : '';
    response.contentType('application/xml');
    response.send(createDeleteDomainResponse({
      domainName: domain.name,
      domainId: FAKE_DOMAIN_ID,
      searchEndpoint: 'search-' + domain.name + '-' + FAKE_DOMAIN_ID + host,
      documentsEndpoint: 'doc-' + domain.name + '-' + FAKE_DOMAIN_ID + host,
      deleted: true,
      searchableDocumentsCount: 0,
      searchInstanceCount: 0,
      searchPartitionCount: 0,
      requiresIndexDocuments: false
    }));
  } catch(error) {
    var body = createCommonErrorResponse('InternalFailure', error.message);
    response.contentType('application/xml');
    response.send(body, 400);
  }
};

function createIndexFieldStatus(options) {
  return '<IndexField>' +
           '<Options>' +
             '<IndexFieldName>' + options.fieldName + '</IndexFieldName>' +
             '<IndexFieldType>' + options.fieldType + '</IndexFieldType>' +
             '<TextOptions>' +
               '<DefaultValue/>' +
               '<FacetEnabled>' + (options.facetEnabled || false) +
                 '</FacetEnabled>' +
               '<ResultEnabled>' + (options.resultEnabled || false) +
                 '</ResultEnabled>' +
             '</TextOptions>' +
           '</Options>' +
           '<Status>' +
             '<CreationDate>' + dateFormat(options.createdAt,
                                           'isoUtcDateTime') +
               '</CreationDate>' +
             '<State>' + options.state + '</State>' +
             '<UpdateDate>' + dateFormat(options.updatedAt, 'isoUtcDateTime') +
               '</UpdateDate>' +
             '<UpdateVersion>' + (options.updateVersion || 0) +
               '</UpdateVersion>' +
           '</Status>' +
         '</IndexField>';
}

function createDefineIndexFieldResponse(options) {
  return '<?xml version="1.0"?>\n' +
         '<DefineIndexFieldResponse xmlns="' + XMLNS + '">' +
           '<DefineIndexFieldResult>' +
             createIndexFieldStatus(options) +
           '</DefineIndexFieldResult>' +
           '<ResponseMetadata>' +
             '<RequestId>' + (options.requestId || '') + '</RequestId>' +
           '</ResponseMetadata>' +
         '</DefineIndexFieldResponse>';
}

handlers.DefineIndexField = function(database, request, response) {
  var domain = new Domain(request);

  var fieldName = request.query['IndexField.IndexFieldName'] || '';
  var field = domain.getIndexField(fieldName);

  var createdAt = new Date();
  var options = {
        table: domain.tableName,
        name: field.columnName,
        flags: Database.COLUMN_SCALAR,
        type: Database.ShortText
      };
  database.commandDeferred('column_create', options)
    .next(function(data) {
      var termsOptions = {
            table: domain.termsTableName,
            name: field.indexColumnName,
            flags: Database.COLUMN_INDEX + '|' + Database.WITH_POSITION,
            type: domain.tableName,
            source: field.columnName
          };
      return database.commandDeferred('column_create', termsOptions);
    })
    .next(function() {
      response.contentType('application/xml');
      response.send(createDefineIndexFieldResponse({
        fieldName: fieldName,
        fieldType: 'text',
        facetEnabled: false,
        resultEnabled: true,
        state: 'RequiresIndexDocuments',
        createdAt: createdAt,
        updatedAt: createdAt
      }));
    })
    .error(function(error) {
      var body = createCommonErrorResponse('InternalFailure', error.message);
      response.contentType('application/xml');
      return response.send(body, 400);
    });
};

function createDeleteIndexFieldResponse(options) {
  return '<?xml version="1.0"?>\n' +
         '<DeleteIndexFieldResponse xmlns="' + XMLNS + '">' +
           '<DeleteIndexFieldResult/>' +
           '<ResponseMetadata>' +
             '<RequestId>' + (options.requestId || '') + '</RequestId>' +
           '</ResponseMetadata>' +
         '</DeleteIndexFieldResponse>';
}

handlers.DeleteIndexField = function(database, request, response) {
  var domain = new Domain(request);

  var fieldName = request.query['IndexFieldName'] || '';
  var field = domain.getIndexField(fieldName);

  var options = {
        table: domain.tableName,
        name: field.columnName
      };
  database.commandDeferred('column_remove', options)
    .next(function() {
      response.contentType('application/xml');
      response.send(createDeleteIndexFieldResponse({}));
    })
    .error(function(error) {
      var body = createCommonErrorResponse('InternalFailure', error.message);
      response.contentType('application/xml');
      return response.send(body, 400);
    });
};

exports.createHandler = function(database) {
  return function(request, response, next) {
    var message, body;

    // GCS specific behaviour: fallback to other handlers for the endpoint
    // if no action is given.
    var action = request.query.Action || '';
    if (!action)
      return next();

    var version = request.query.Version;
    if (!version) {
      message = 'An input parameter "Version" that is mandatory for ' +
                'processing the request is not supplied.';
      body = createCommonErrorResponse('MissingParameter', message);
      response.contentType('application/xml');
      return response.send(body, 400);
    }

    if (version != exports.version) {
      message = 'A bad or out-of-range value "' + version + '" was supplied ' +
                'for the "Version" input parameter.';
      body = createCommonErrorResponse('InvalidParameterValue', message);
      response.contentType('application/xml');
      return response.send(body, 400);
    }

    if (!(action in handlers)) {
      message = 'The action ' + action + ' is not valid for this web service.';
      body = createCommonErrorResponse('InvalidAction', message);
      response.contentType('application/xml');
      return response.send(body, 400);
    }

    var handler = handlers[action];
    handler(database, request, response);
  };
};
<|endoftext|>


<commit_before>/*!
 * jQuery Ticker Plugin v1.0.0
 * https://github.com/BenjaminRH/jquery-ticker
 *
 * Copyright 2014 Benjamin Harris
 * Released under the MIT license
 */
(function($) {

    // The ticker plugin
    $.fn.ticker = function(options) {
        // Extend our defaults with user-specified options
        var opts = $.extend({}, $.fn.ticker.defaults, options);

        // Handle each of the given containers
        return this.each(function () {
            // Setup the ticker elements
            var tickerContainer = $(this);                     // Outer-most ticker container
            var headlineContainer;                             // Inner headline container
            var headlineElements = tickerContainer.find('li'); // Original headline elements
            var headlines = [];                                // List of all the headlines
            var headlineTagMap = {};                           // Maps the indexes of the HTML tags in the headlines to the headline index
            var outerTimeoutId;                                // Stores the outer ticker timeout id for pauses
            var innerTimeoutId;                                // Stores the inner ticker timeout id for pauses
            var currentHeadline = 0;                           // The index of the current headline in the list of headlines
            var currentHeadlinePosition = 0;                   // The index of the current character in the current headline
            var firstOuterTick = true;                         // Whether this is the first time doing the outer tick
            var firstInnerTick = true;                         // Whether this is the first time doing the inner tick in this rendition of the outer one

            var allowedTags = ['a', 'b', 'strong', 'span', 'i', 'em', 'u'];

            // Save all the headline text
            headlineElements.each(function (index, element) {
                headlines.push(stripTags($(this).html(), allowedTags));
            });

            // Randomize?
            if (opts.random) shuffleArray(headlines);

            // Now delete all the elements and add the headline container
            tickerContainer.find('ul').after('

').remove();
            headlineContainer = tickerContainer.find('div');

            // Function to actually do the outer ticker, and handle pausing
            function outerTick() {
                firstInnerTick = true;

                if (firstOuterTick) {
                    firstOuterTick = false;
                    innerTick();
                    return;
                }

                outerTimeoutId = setTimeout(function () {
                    if (opts.pauseOnHover && tickerContainer.is(':hover')) {
                        // User is hovering over the ticker and pause on hover is enabled
                        clearTimeout(innerTimeoutId);
                        outerTick();
                        return;
                    }

                    innerTick();
                }, opts.itemSpeed);
            }

            // Function to handle the ticking for individual headlines
            function innerTick() {
                if (firstInnerTick) {
                    firstInnerTick = false;
                    tick();
                    return;
                }

                if (opts.finishOnHover && opts.pauseOnHover && tickerContainer.is(':hover') && currentHeadlinePosition <= headlines[currentHeadline].length) {
                    // Let's quickly complete the headline
                    // This is outside the timeout because we want to do this instantly without the pause

                    // Update the text
                    headlineContainer.text(getCurrentTick());
                    // Advance our position
                    currentHeadlinePosition += 1;

                    innerTick();
                    return;
                }
                else {
                    // Handle as normal
                    innerTimeoutId = setTimeout(function () {
                        if (opts.pauseOnHover && tickerContainer.is(':hover')) {
                            // User is hovering over the ticker and pause on hover is enabled
                            clearTimeout(innerTimeoutId);
                            innerTick();
                            return;
                        }

                        tick();
                        advance();
                    }, opts.cursorSpeed);
                }
            }

            function advance() {
                // Advance headline and reset character position, if it's at the end of the current headline
                if (currentHeadlinePosition > headlines[currentHeadline].length) { // > here and not == because the ticker cursor takes an extra loop
                    currentHeadline += 1;
                    currentHeadlinePosition = 0;

                    // Reset the headline and character positions if we've cycled through all the headlines
                    if (currentHeadline == headlines.length) currentHeadline = 0;

                    // STOP! We've advanced a headline. Now we just need to pause.
                    clearTimeout(innerTimeoutId);
                    clearTimeout(outerTimeoutId);
                    outerTick();
                }
            }

            // Do the individual ticks
            function tick() {
                // Now let's update the ticker with the current tick string
                if (currentHeadlinePosition === 0 && opts.fade) {
                    clearTimeout(innerTimeoutId);

                    // Animate the transition if it's enabled
                    headlineContainer.fadeOut(opts.fadeOutSpeed, function () {
                        // Now it's faded out, let's update the text
                        headlineContainer.text(getCurrentTick());
                        // And fade in
                        headlineContainer.fadeIn(opts.fadeInSpeed, function () {
                            // Advance our position
                            currentHeadlinePosition += 1;
                            // And now we're in, let's start the thing off again without the delay
                            innerTick();
                        });
                    });
                }
                else {
                    // Update the text
                    headlineContainer.text(getCurrentTick());
                    // Advance our position
                    currentHeadlinePosition += 1;
                    clearTimeout(innerTimeoutId);
                    innerTick();
                }
            }

            // Get the current tick string
            function getCurrentTick() {
                var cursor;
                switch (currentHeadlinePosition % 2) {
                    case 1:
                        cursor = opts.cursorOne;
                        break;
                    case 0:
                        cursor = opts.cursorTwo;
                        break;
                }

                // Don't display the cursor this was the last character of the headline
                if (currentHeadlinePosition >= headlines[currentHeadline].length) cursor = '';

                return headlines[currentHeadline].slice(0, currentHeadlinePosition) + cursor;
            }

            // Start it
            outerTick();
        });
    };

    /**
     * Randomize array element order in-place.
     * Using Fisher-Yates shuffle algorithm.
     */
    function shuffleArray(array) {
        for (var i = array.length - 1; i > 0; i--) {
            var j = Math.floor(Math.random() * (i + 1));
            var temp = array[i];
            array[i] = array[j];
            array[j] = temp;
        }
        return array;
    }

    /**
     * Strip all HTML tags from a string.
     * An array of safe tags can be passed, which will not be
     * stripped from the string with the rest of the tags.
     */
    function stripTags(text, safeTags) {
        safeTags = safeTags || [];
        var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/img;
        var comments = //img;
        return text.replace(comments, '').replace(tags, function (a, b) {
            return safeTags.indexOf(b.toLowerCase()) !== -1 ? a : '';
        });
    }

    /**
     * Locates all of the request tags in a string.
     * Returns an array of locations, each location being an array of the tag's start and end indexes.
     */
    function locateTags(text, tags) {
        var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/img;
        var locations = [];
        var match;

        while (match = tags.exec(text)) {
            locations.push([match.index, match[0].length - 1]);
        }

        return locations;
    }

    // Plugin default settings
    $.fn.ticker.defaults = {
        random:        false, // Whether to display ticker items in a random order
        itemSpeed:     3000,  // The pause on each ticker item before being replaced
        cursorSpeed:   50,    // Speed at which the characters are typed
        pauseOnHover:  true,  // Whether to pause when the mouse hovers over the ticker
        finishOnHover: true,  // Whether or not to complete the ticker item instantly when moused over
        cursorOne:     '_',   // The symbol for the first part of the cursor
        cursorTwo:     '-',   // The symbol for the second part of the cursor
        fade:          true,  // Whether to fade between ticker items or not
        fadeInSpeed:   600,   // Speed of the fade-in animation
        fadeOutSpeed:  300    // Speed of the fade-out animation
    };

})(jQuery);
<commit_msg>Fix bug in locateTags<commit_after>/*!
 * jQuery Ticker Plugin v1.0.0
 * https://github.com/BenjaminRH/jquery-ticker
 *
 * Copyright 2014 Benjamin Harris
 * Released under the MIT license
 */
(function($) {

    // The ticker plugin
    $.fn.ticker = function(options) {
        // Extend our defaults with user-specified options
        var opts = $.extend({}, $.fn.ticker.defaults, options);

        // Handle each of the given containers
        return this.each(function () {
            // Setup the ticker elements
            var tickerContainer = $(this);                     // Outer-most ticker container
            var headlineContainer;                             // Inner headline container
            var headlineElements = tickerContainer.find('li'); // Original headline elements
            var headlines = [];                                // List of all the headlines
            var headlineTagMap = {};                           // Maps the indexes of the HTML tags in the headlines to the headline index
            var outerTimeoutId;                                // Stores the outer ticker timeout id for pauses
            var innerTimeoutId;                                // Stores the inner ticker timeout id for pauses
            var currentHeadline = 0;                           // The index of the current headline in the list of headlines
            var currentHeadlinePosition = 0;                   // The index of the current character in the current headline
            var firstOuterTick = true;                         // Whether this is the first time doing the outer tick
            var firstInnerTick = true;                         // Whether this is the first time doing the inner tick in this rendition of the outer one

            var allowedTags = ['a', 'b', 'strong', 'span', 'i', 'em', 'u'];

            // Save all the headline text
            var h, l;
            headlineElements.each(function (index, element) {
                h = stripTags($(this).html(), allowedTags);
                l = locateTags(h, allowedTags)
                headlines.push(h);
            });

            // Randomize?
            if (opts.random) shuffleArray(headlines);

            // Now delete all the elements and add the headline container
            tickerContainer.find('ul').after('

').remove();
            headlineContainer = tickerContainer.find('div');

            // Function to actually do the outer ticker, and handle pausing
            function outerTick() {
                firstInnerTick = true;

                if (firstOuterTick) {
                    firstOuterTick = false;
                    innerTick();
                    return;
                }

                outerTimeoutId = setTimeout(function () {
                    if (opts.pauseOnHover && tickerContainer.is(':hover')) {
                        // User is hovering over the ticker and pause on hover is enabled
                        clearTimeout(innerTimeoutId);
                        outerTick();
                        return;
                    }

                    innerTick();
                }, opts.itemSpeed);
            }

            // Function to handle the ticking for individual headlines
            function innerTick() {
                if (firstInnerTick) {
                    firstInnerTick = false;
                    tick();
                    return;
                }

                if (opts.finishOnHover && opts.pauseOnHover && tickerContainer.is(':hover') && currentHeadlinePosition <= headlines[currentHeadline].length) {
                    // Let's quickly complete the headline
                    // This is outside the timeout because we want to do this instantly without the pause

                    // Update the text
                    headlineContainer.text(getCurrentTick());
                    // Advance our position
                    currentHeadlinePosition += 1;

                    innerTick();
                    return;
                }
                else {
                    // Handle as normal
                    innerTimeoutId = setTimeout(function () {
                        if (opts.pauseOnHover && tickerContainer.is(':hover')) {
                            // User is hovering over the ticker and pause on hover is enabled
                            clearTimeout(innerTimeoutId);
                            innerTick();
                            return;
                        }

                        tick();
                        advance();
                    }, opts.cursorSpeed);
                }
            }

            function advance() {
                // Advance headline and reset character position, if it's at the end of the current headline
                if (currentHeadlinePosition > headlines[currentHeadline].length) { // > here and not == because the ticker cursor takes an extra loop
                    currentHeadline += 1;
                    currentHeadlinePosition = 0;

                    // Reset the headline and character positions if we've cycled through all the headlines
                    if (currentHeadline == headlines.length) currentHeadline = 0;

                    // STOP! We've advanced a headline. Now we just need to pause.
                    clearTimeout(innerTimeoutId);
                    clearTimeout(outerTimeoutId);
                    outerTick();
                }
            }

            // Do the individual ticks
            function tick() {
                // Now let's update the ticker with the current tick string
                if (currentHeadlinePosition === 0 && opts.fade) {
                    clearTimeout(innerTimeoutId);

                    // Animate the transition if it's enabled
                    headlineContainer.fadeOut(opts.fadeOutSpeed, function () {
                        // Now it's faded out, let's update the text
                        headlineContainer.text(getCurrentTick());
                        // And fade in
                        headlineContainer.fadeIn(opts.fadeInSpeed, function () {
                            // Advance our position
                            currentHeadlinePosition += 1;
                            // And now we're in, let's start the thing off again without the delay
                            innerTick();
                        });
                    });
                }
                else {
                    // Update the text
                    headlineContainer.text(getCurrentTick());
                    // Advance our position
                    currentHeadlinePosition += 1;
                    clearTimeout(innerTimeoutId);
                    innerTick();
                }
            }

            // Get the current tick string
            function getCurrentTick() {
                var cursor;
                switch (currentHeadlinePosition % 2) {
                    case 1:
                        cursor = opts.cursorOne;
                        break;
                    case 0:
                        cursor = opts.cursorTwo;
                        break;
                }

                // Don't display the cursor this was the last character of the headline
                if (currentHeadlinePosition >= headlines[currentHeadline].length) cursor = '';

                return headlines[currentHeadline].slice(0, currentHeadlinePosition) + cursor;
            }

            // Start it
            outerTick();
        });
    };

    /**
     * Randomize array element order in-place.
     * Using Fisher-Yates shuffle algorithm.
     */
    function shuffleArray(array) {
        for (var i = array.length - 1; i > 0; i--) {
            var j = Math.floor(Math.random() * (i + 1));
            var temp = array[i];
            array[i] = array[j];
            array[j] = temp;
        }
        return array;
    }

    /**
     * Strip all HTML tags from a string.
     * An array of safe tags can be passed, which will not be
     * stripped from the string with the rest of the tags.
     */
    function stripTags(text, safeTags) {
        safeTags = safeTags || [];
        var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/img;
        var comments = //img;
        return text.replace(comments, '').replace(tags, function (a, b) {
            return safeTags.indexOf(b.toLowerCase()) !== -1 ? a : '';
        });
    }

    /**
     * Locates all of the request tags in a string.
     * Returns an array of locations, each location being an array of the tag's start and end indexes.
     */
    function locateTags(text, tagList) {
        tagList = tagList || [];
        var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/img;
        var locations = [];
        var match;

        while (match = tags.exec(text)) {
            if (tagList.length === 0 || tagList.indexOf(match[1]) !== -1) {
                locations.push([match.index, match[0].length - 1]);
            }
        }

        return locations;
    }

    // Plugin default settings
    $.fn.ticker.defaults = {
        random:        false, // Whether to display ticker items in a random order
        itemSpeed:     3000,  // The pause on each ticker item before being replaced
        cursorSpeed:   50,    // Speed at which the characters are typed
        pauseOnHover:  true,  // Whether to pause when the mouse hovers over the ticker
        finishOnHover: true,  // Whether or not to complete the ticker item instantly when moused over
        cursorOne:     '_',   // The symbol for the first part of the cursor
        cursorTwo:     '-',   // The symbol for the second part of the cursor
        fade:          true,  // Whether to fade between ticker items or not
        fadeInSpeed:   600,   // Speed of the fade-in animation
        fadeOutSpeed:  300    // Speed of the fade-out animation
    };

})(jQuery);
<|endoftext|>


<commit_before>
/*!--------------------------------*\
   3-Jekyll Theme
   @author Peiwen Lu (P233)
   https://github.com/P233/3-Jekyll
\*---------------------------------*/

// Detect window size, if less than 1280px add class 'mobile' to sidebar therefore it will be auto hide when trigger the pjax request in small screen devices.
if ($(window).width() <= 1280) {
  $('#sidebar').addClass('mobile')
}

// Variables
    tag1       = $('.pl__all'),
    tag2       = $('.android'),
    tag3       = $('.tools_using'),
    tag4       = $('.ubuntu'),
    tag5       = $('.place_your_tag_name_here'),
    tag6       = $('.place_your_tag_name_here');
var sidebar    = $('#sidebar'),
    container  = $('#post'),
    content    = $('#pjax'),
    button     = $('#icon-arrow');

// Tags switcher
var clickHandler = function(k) {
  return function() {
    $(this).addClass('active').siblings().removeClass('active');
    tag1.hide();
    window['tag'+k].delay(50).fadeIn(350);
  }
};
for (var i = 1; i <= 6; i++) {
  $('#js-label' + i).on('click', clickHandler(i));
}

// If sidebar has class 'mobile', hide it after clicking.
tag1.on('click', function() {
  $(this).addClass('active').siblings().removeClass('active');
  if (sidebar.hasClass('mobile')) {
    $('#sidebar, #pjax, #icon-arrow').addClass('fullscreen');
  }
});

// Enable fullscreen.
$('#js-fullscreen').on('click', function() {
  if (button.hasClass('fullscreen')) {
    sidebar.removeClass('fullscreen');
    button.removeClass('fullscreen');
    content.delay(300).queue(function(){
      $(this).removeClass('fullscreen').dequeue();
    });
  } else {
    sidebar.addClass('fullscreen');
    button.addClass('fullscreen');
    content.delay(200).queue(function(){
      $(this).addClass('fullscreen').dequeue();
    });
  }
});

$('#mobile-avatar').on('click', function(){
  $('#sidebar, #pjax, #icon-arrow').addClass('fullscreen');
});

// Pjax
$(document).pjax('#avatar, #mobile-avatar, .pl__all', '#pjax', { fragment: '#pjax', timeout: 10000 });
$(document).on({
  'pjax:click': function() {
    content.removeClass('fadeIn').addClass('fadeOut');
    NProgress.start();
  },
  'pjax:start': function() {
    content.css({'opacity':0});
  },
  'pjax:end': function() {
    NProgress.done();
    container.scrollTop(0);
    content.css({'opacity':1}).removeClass('fadeOut').addClass('fadeIn');
    afterPjax();
  }
});
<commit_msg>change js<commit_after>
/*!--------------------------------*\
   3-Jekyll Theme
   @author Peiwen Lu (P233)
   https://github.com/P233/3-Jekyll
\*---------------------------------*/

// Detect window size, if less than 1280px add class 'mobile' to sidebar therefore it will be auto hide when trigger the pjax request in small screen devices.
if ($(window).width() <= 1280) {
  $('#sidebar').addClass('mobile')
}

// Variables
    tag1       = $('.pl__all'),
    tag2       = $('.android'),
    tag3       = $('.tools_using'),
    tag4       = $('.ubuntu'),
    tag5       = $('.place_your_tag_name_here'),
    tag6       = $('.place_your_tag_name_here');
var sidebar    = $('#sidebar'),
    container  = $('#post'),
    content    = $('#pjax'),
    button     = $('#icon-arrow');

// Tags switcher
var clickHandler = function(k) {
  return function() {
    $(this).addClass('active').siblings().removeClass('active');
    tag1.hide();
    window['tag'+k].delay(50).fadeIn(350);
  }
};
for (var i = 1; i <= 6; i++) {
  $('#js-label' + i).on('click', clickHandler(i));
}

// If sidebar has class 'mobile', hide it after clicking.
tag1.on('click', function() {
  $(this).addClass('active').siblings().removeClass('active');
  if (sidebar.hasClass('mobile')) {
    $('#sidebar, #pjax, #icon-arrow').addClass('fullscreen');
  }
});

// Enable fullscreen.
$('#js-fullscreen').on('click', function() {
  if (button.hasClass('fullscreen')) {
    sidebar.removeClass('fullscreen');
    button.removeClass('fullscreen');
    content.delay(300).queue(function(){
      $(this).removeClass('fullscreen').dequeue();
    });
  } else {
    sidebar.addClass('fullscreen');
    button.addClass('fullscreen');
    content.delay(200).queue(function(){
      $(this).addClass('fullscreen').dequeue();
    });
  }
});

$('#mobile-avatar').on('click', function(){
  $('#sidebar, #pjax, #icon-arrow').addClass('fullscreen');
});

// Pjax
$(document).pjax('#avatar, #mobile-avatar, .pl__all', '#pjax', { fragment: '#pjax', timeout: 10000 });
$(document).on({
  'pjax:click': function() {
    content.removeClass('fadeIn').addClass('fadeOut');
    NProgress.start();
  },
  'pjax:start': function() {
    content.css({'opacity':0});
  },
  'pjax:end': function() {
    NProgress.done();
    container.scrollTop(0);
    content.css({'opacity':1}).removeClass('fadeOut').addClass('fadeIn');
    afterPjax();
  }
});

// Codepen embed js
// http://codepen.io/assets/embed/ei.js
// Added on 17 Nov 2013
var CodePenEmbed={width:"100%",init:function(){this.showCodePenEmbeds(),this.listenToParentPostMessages()},showCodePenEmbeds:function(){var e=document.getElementsByClassName("codepen");for(var t=e.length-1;t>-1;t--){var n=this._getParamsFromAttributes(e[t]);n=this._convertOldDataAttributesToNewDataAttributes(n);var r=this._buildURL(n),i=this._buildIFrame(n,r);this._addIFrameToPage(e[t],i)}},_getParamsFromAttributes:function(e){var t={},n=e.attributes;for(var r=0,i=n.length;r<i;r++)name=n[r].name,name.indexOf("data-")===0&&(t[name.replace("data-","")]=n[r].value);return t},_convertOldDataAttributesToNewDataAttributes:function(e){return e.href&&(e["slug-hash"]=e.href),e.type&&(e["default-tab"]=e.type),e.safe&&(e["safe"]=="true"?e.animations="run":e.animations="stop-after-5"),e},_buildURL:function(e){var t=this._getHost(e),n=e.user?e.user:"anon",r="?"+this._getGetParams(e),i=[t,n,"embed",e["slug-hash"]+r].join("/");return i.replace(/\/\//g,"//")},_getHost:function(e){return e.host?e.host:document.location.protocol=="file:"?"http://codepen.io":"//codepen.io"},_getGetParams:function(e){var t="",n=0;for(var r in e)t!==""&&(t+="&"),t+=r+"="+encodeURIComponent(e[r]);return t},_buildIFrame:function(e,t){var n={id:"cp_embed_"+e["slug-hash"].replace("/","_"),src:t,scrolling:"no",frameborder:"0",height:this._getHeight(e),allowTransparency:"true","class":"cp_embed_iframe",style:"width: "+this.width+"; overflow: hidden;"},r="",r},_getHeight:function(e){return e.height?e["height"]=="auto"?300:e.height:300},_addIFrameToPage:function(e,t){if(e.parentNode){var n=document.createElement("div");n.innerHTML=t,e.parentNode.replaceChild(n,e)}else e.innerHTML=t},listenToParentPostMessages:function(){var eventMethod=window.addEventListener?"addEventListener":"attachEvent",eventListener=window[eventMethod],messageEvent=eventMethod=="attachEvent"?"onmessage":"message";eventListener(messageEvent,function(e){try{var dataObj=eval("("+e.data+")"),iframe=document.getElementById("cp_embed_"+dataObj.hash);iframe&&(iframe.height=dataObj.height)}catch(err){}},!1)}};

// Re-run scripts for post content after pjax
function afterPjax() {
  // Open links in new tab
  $('#post__content a').attr('target','_blank');

  // Embed codepen after pjax
  CodePenEmbed.init();

  // Generate post TOC for h1 h2 and h3
  var toc = $('#post__toc-ul');
  // Empty TOC and generate an entry for h1
  toc.empty().append('
' + $('#post__title').text() + '
');

  // Generate entries for h2 and h3
  $('#post__content').children('h2,h3').each(function() {
    // Generate random ID for each heading
    $(this).attr('id', function() {
      var ID = "",
          alphabet = "abcdefghijklmnopqrstuvwxyz";

      for(var i=0; i < 5; i++) {
        ID += alphabet.charAt(Math.floor(Math.random() * alphabet.length));
      }
      return ID;
    });

    if ($(this).prop("tagName") == 'H2') {
      toc.append('
' + $(this).text() + '
');
    } else {
      toc.append('
' + $(this).text() + '
');
    }
  });

  // Smooth scrolling
  $('.js-anchor-link').on('click', function() {
    var target = $(this.hash);
    container.animate({scrollTop: target.offset().top + container.scrollTop() - 70}, 500, function() {
      target.addClass('flash').delay(700).queue(function() {
        $(this).removeClass('flash').dequeue();
      });
    });
  });
}
afterPjax();
<|endoftext|>


<commit_before>const config = require(__dirname+'/../../config/environment.js');

var validator = require(__dirname+'/../validator.js');
var EnqueueOutgoingPaymentError = require(__dirname+'/../errors/enqueue_outgoing_payment_error.js');
var Promise = require('bluebird');
const RippleTransactions = require(__dirname+'/../data/').models.rippleTransactions;
const RippleAddresses = require(__dirname+'/../data/').models.rippleAddresses;

function enqueueOutgoingPayment(options) {
  return new Promise(function (resolve, reject) {
    _validateRequest(options)
      .then(function () {
        _findOrCreateSenderAddress(options)
          .then(function (senderAddress) {
            _findOrCreateDestinationAddress(options)
              .then(function (destinationAddress) {
                resolve(_recordTransaction(options, destinationAddress, senderAddress));
              }).error(reject);
          }).error(reject);
      }).error(reject);
  });
}

function _validateRequest(options) {
  return new Promise(function(resolve, reject) {
    if (!validator.isFloat(options.amount)) {
      return reject(new EnqueueOutgoingPaymentError({
        field: 'amount',
        message: 'must be numeric'
      }));
    }
    if (!validator.isAlphanumeric(options.currency)) {
      return reject(new EnqueueOutgoingPaymentError({
        field: 'currency',
        message: 'must be a currency code'
      }));
    }
    if (!validator.isRippleAddress(options.address)) {
      return reject(new EnqueueOutgoingPaymentError({
        field: 'address',
        message: 'invalid ripple address'
      }));
    }
    if (options.destinationTag && !validator.isInt(options.destinationTag)) {
      return reject(new EnqueueOutgoingPaymentError({
        field: 'destinationTag',
        message: 'must be an unsigned integer'
      }));
    }
    if (options.issuer && !validator.isRippleAddress(options.issuer)) {
      return reject(new EnqueueOutgoingPaymentError({
        field: 'issuer',
        message: 'invalid ripple address'
      }));
    }
    resolve();
  });
}

function _findOrCreateSenderAddress() {
  return RippleAddresses.findOrCreate({
    address: config.get('HOT_WALLET').address,
    managed: true,
    tag: config.get('HOT_WALLET').id,
    type: 'hosted'
  });
}

function _findOrCreateDestinationAddress(options) {
  return RippleAddresses.findOrCreate({
    address: options.address,
    managed: false,
    tag: options.destinationTag,
    type: options.destinationTag ? 'hosted' : 'independent'
  });
}

function _recordTransaction(options, toAddress, fromAddress) {
  return RippleTransactions.create({
    to_amount: options.amount,
    to_currency: options.currency,
    from_amount: options.amount,
    from_currency: options.currency,
    to_address_id: toAddress.id,
    from_address_id: fromAddress.id,
    to_issuer: options.issuer || config.get('COLD_WALLET'),
    from_issuer: options.issuer || config.get('COLD_WALLET'),
    state: 'outgoing',
    direction: 'to-ripple'
  });
}

module.exports = enqueueOutgoingPayment;

<commit_msg>[FIX] store memos and invoice_id<commit_after>const config = require(__dirname+'/../../config/environment.js');

var validator = require(__dirname+'/../validator.js');
var EnqueueOutgoingPaymentError = require(__dirname+'/../errors/enqueue_outgoing_payment_error.js');
var Promise = require('bluebird');
const RippleTransactions = require(__dirname+'/../data/').models.rippleTransactions;
const RippleAddresses = require(__dirname+'/../data/').models.rippleAddresses;

function enqueueOutgoingPayment(options) {
  return new Promise(function (resolve, reject) {
    _validateRequest(options)
      .then(function () {
        _findOrCreateSenderAddress(options)
          .then(function (senderAddress) {
            _findOrCreateDestinationAddress(options)
              .then(function (destinationAddress) {
                resolve(_recordTransaction(options, destinationAddress, senderAddress));
              }).error(reject);
          }).error(reject);
      }).error(reject);
  });
}

function _validateRequest(options) {
  return new Promise(function(resolve, reject) {
    if (!validator.isFloat(options.amount)) {
      return reject(new EnqueueOutgoingPaymentError({
        field: 'amount',
        message: 'must be numeric'
      }));
    }
    if (!validator.isAlphanumeric(options.currency)) {
      return reject(new EnqueueOutgoingPaymentError({
        field: 'currency',
        message: 'must be a currency code'
      }));
    }
    if (!validator.isRippleAddress(options.address)) {
      return reject(new EnqueueOutgoingPaymentError({
        field: 'address',
        message: 'invalid ripple address'
      }));
    }
    if (options.destinationTag && !validator.isInt(options.destinationTag)) {
      return reject(new EnqueueOutgoingPaymentError({
        field: 'destinationTag',
        message: 'must be an unsigned integer'
      }));
    }
    if (options.issuer && !validator.isRippleAddress(options.issuer)) {
      return reject(new EnqueueOutgoingPaymentError({
        field: 'issuer',
        message: 'invalid ripple address'
      }));
    }
    resolve();
  });
}

function _findOrCreateSenderAddress() {
  return RippleAddresses.findOrCreate({
    address: config.get('HOT_WALLET').address,
    managed: true,
    tag: config.get('HOT_WALLET').id,
    type: 'hosted'
  });
}

function _findOrCreateDestinationAddress(options) {
  return RippleAddresses.findOrCreate({
    address: options.address,
    managed: false,
    tag: options.destinationTag,
    type: options.destinationTag ? 'hosted' : 'independent'
  });
}

function _recordTransaction(options, toAddress, fromAddress) {
  return RippleTransactions.create({
    to_amount: options.amount,
    to_currency: options.currency,
    from_amount: options.amount,
    from_currency: options.currency,
    to_address_id: toAddress.id,
    from_address_id: fromAddress.id,
    to_issuer: options.issuer || config.get('COLD_WALLET'),
    from_issuer: options.issuer || config.get('COLD_WALLET'),
    state: 'outgoing',
    direction: 'to-ripple',
    memos: options.memos,
    invoice_id: options.invoice_id
  });
}

module.exports = enqueueOutgoingPayment;

<|endoftext|>


<commit_before>---
layout: null
---
function str_sim (a, b) {
	if (!a || !b || a.length ==0 || b.length ==0 ) {
		return 0.0
	}
	a = a.toUpperCase()
	b = b.toUpperCase()
	if (a.indexOf(b)>=0 || b.indexOf(a)>=0) {
		return 1.0;
	}
	var min = a.length>b.length ? b.length: a.length
	var intersect = 0.0
	for(var i = 0; i < a.length - 1; i++ ){
		for(var j = 0; j < b.length - 1 ; j++ )
			if (a.substr(i,2) == b.substr(j,2))
				intersect +=1
	}
	return intersect / min;
}
$(function(){
	var today = "{{ site.time | date: "%Y%m%d" }}"
	var feed_url = "{{ site.url }}/feed.json?date=" + today

	var args = window.location.search.split('&')
	var query_search = ''
	for (var i = 0; i<args.length; i++)
		if(args[i].indexOf('q=') >= 0)
			query_search = args[i];
	if( query_search ) {
	  var query = decodeURI(query_search.split('=')[1])
	  $.getJSON(feed_url, function(posts) {
		$.each(posts,function(idx, post) {
			if( str_sim (query, post.title) >= 0.9 ){
				var li='
' + post.title+ '
'
				$('#search-ul').append(li)
			}
		})
		switch($('#search-ul li').size()){
			case 0 :
                $('#search-results').hide()
                $('#no-search-results').show()
                setTimeout(function(){
                    window.location.href="{{site.url}}/posts.html"
                }, 1500)
                break;
			case 1 :
                $('#no-search-results').hide()
                $('#search-results').show()
                $('#search-ul li a')[0].click();
                break;
			default:
                $('#no-search-results').hide()
                $('#search-results').show()
		}
	}).fail(function(){
    window.location.href="{{site.url}}/search.html?q="+query_search
  })
	}else window.location.href="{{site.url}}/posts.html";

})
<commit_msg>add fail function for search.html<commit_after>---
layout: null
---
function str_sim (a, b) {
	if (!a || !b || a.length ==0 || b.length ==0 ) {
		return 0.0
	}
	a = a.toUpperCase()
	b = b.toUpperCase()
	if (a.indexOf(b)>=0 || b.indexOf(a)>=0) {
		return 1.0;
	}
	var min = a.length>b.length ? b.length: a.length
	var intersect = 0.0
	for(var i = 0; i < a.length - 1; i++ ){
		for(var j = 0; j < b.length - 1 ; j++ )
			if (a.substr(i,2) == b.substr(j,2))
				intersect +=1
	}
	return intersect / min;
}
$(function(){
	var today = "{{ site.time | date: "%Y%m%d" }}"
	var feed_url = "{{ site.url }}/feed.json?date=" + today

	var args = window.location.search.split('&')
	var query_search = ''
	for (var i = 0; i<args.length; i++)
		if(args[i].indexOf('q=') >= 0)
			query_search = args[i];
	if( query_search ) {
	  var query = decodeURI(query_search.split('=')[1])
	  $.getJSON(feed_url, function(posts) {
		$.each(posts,function(idx, post) {
			if( str_sim (query, post.title) >= 0.9 ){
				var li='
' + post.title+ '
'
				$('#search-ul').append(li)
			}
		})
		switch($('#search-ul li').size()){
			case 0 :
                $('#search-results').hide()
                $('#no-search-results').show()
                setTimeout(function(){
                    window.location.href="{{site.url}}/posts.html"
                }, 1500)
                break;
			case 1 :
                $('#no-search-results').hide()
                $('#search-results').show()
                $('#search-ul li a')[0].click();
                break;
			default:
                $('#no-search-results').hide()
                $('#search-results').show()
		}
	}).fail(function(){
    window.location.href="{{site.url}}/search.html?"+query_search
  })
	}else window.location.href="{{site.url}}/posts.html";

})
<|endoftext|>


<commit_before>$(function() {
    $("[data-toggle='tooltip']").tooltip();
});

function showDialog(msg, style, timeout) {
    var modalHtml = "<" + style + " id='message-dialog-msg'></" + style + ">";
    $("#message-dialog .modal-body").empty();
    $("#message-dialog .modal-body").append(modalHtml);
    $("#message-dialog-msg").text(msg);
    $("#message-dialog").modal("show");
    if(null !== timeout) {
        setTimeout('$("#message-dialog").modal("hide")', timeout);
    }
}

function showSuccessDialog() {
    showInfoDialog("操作已成功完成");
}

function showInfoDialog(msg) {
    showDialog(msg, "h4", 2000);
}

function showFailureDialog(msg) {
    showDialog(msg, "h4", null);
}

function authorityControl() {
    $.ajax({
        type: "HEAD",
        url : "/",
        complete: function(xhr, data) {
            if ("guest" === xhr.getResponseHeader("identify")) {
                $("table").on("all.bs.table", function() {
                    $(".index-content .btn-xs").attr("disabled", true);
                    $(".btn-info").attr("disabled", false);
                });
            }
            $(".authority").text(xhr.getResponseHeader("identify"));
        }
    });
}

function showDeleteConfirmModal() {
    $("#confirm-info").text("确认要删除吗？");
}

function showShutdownConfirmModal() {
    $("#confirm-info").text("确认要关闭吗？");
}

function showUpdateConfirmModal() {
    $("#confirm-info").text("该更新会对运行中的作业造成影响，请慎重操作！");
}
<commit_msg>refactor code for modal dialog<commit_after>$(function() {
    $("[data-toggle='tooltip']").tooltip();
});

function showDialog(msg, style, timeout) {
    var modalHtml = "<" + style + " id='message-dialog-msg'></" + style + ">";
    $("#message-dialog .modal-body").empty();
    $("#message-dialog .modal-body").append(modalHtml);
    $("#message-dialog-msg").text(msg);
    $("#message-dialog").modal("show");
    if(null !== timeout) {
        setTimeout('$("#message-dialog").modal("hide")', timeout);
    }
}

function showSuccessDialog() {
    showInfoDialog("操作已成功完成");
}

function showInfoDialog(msg) {
    showDialog(msg, "h4", 2000);
}

function showFailureDialog(msg) {
    showDialog(msg, "h4", null);
}

function authorityControl() {
    $.ajax({
        type: "HEAD",
        url : "/",
        complete: function(xhr, data) {
            if ("guest" === xhr.getResponseHeader("identify")) {
                $("table").on("all.bs.table", function() {
                    $(".index-content .btn-xs").attr("disabled", true);
                    $(".btn-info").attr("disabled", false);
                });
            }
            $("#authority").text(xhr.getResponseHeader("identify"));
        }
    });
}

function showDeleteConfirmModal() {
    $("#confirm-info").text("确认要删除吗？");
}

function showShutdownConfirmModal() {
    $("#confirm-info").text("确认要关闭吗？");
}

function showUpdateConfirmModal() {
    $("#confirm-info").text("该更新会对运行中的作业造成影响，请慎重操作！");
}
<|endoftext|>


<commit_before>
function CyPathDemoInit(){

    ///
    /// Setup and preamble.
    ///

    //var DEBUG = false;
    var DEBUG = true;

    // HTML connctions.
    var demo_output_id = 'cydemo';
    var demo_output_elt = '#' + demo_output_id;
    var demo_input_id = 'demo_input';
    var demo_input_elt = '#' + demo_input_id;
    var auto_1_input_id = 'auto_1_input';
    var auto_1_input_elt = '#' + auto_1_input_id;
    var auto_2_input_id = 'auto_2_input';
    var auto_2_input_elt = '#' + auto_2_input_id;
    var sel_1_input_id = 'sel_1_input';
    var sel_1_input_elt = '#' + sel_1_input_id;
    var sel_2_input_id = 'sel_2_input';
    var sel_2_input_elt = '#' + sel_2_input_id;

    // Aliases.
    var each = bbop.core.each;
    var ll = function(str){
	if( DEBUG && console && console.log ){
	    console.log(str);
	}
    };

    ll('Start ready!');

    ///
    /// Renderer originally lifted from AmiGO 2 demo.
    ///

    //
    function draw_graph(graph, focus_id){

	//ll('in');

	jQuery(demo_output_elt).empty();

	// Nodes.
	var cyroots = [];
	var cynodes = [];
	var info_lookup = {};
	each(graph.all_nodes(),
	     function(node){
		 ll('node: ' + node.id());
		 info_lookup[node.id()] = {
		     'id': node.id(),
		     'label': node.label() || node.id()
		 };
		 if( graph.is_root_node(node.id()) ){
		     cyroots.push(node.id());
		 }
		 var clr;
		 if( focus && node.id() == focus_id ){

		 }
		 var node_opts = {
		     //'group': 'nodes',
		     'data': {
			 'id': node.id(),
			 'label': node.label() || node.id()
		     },
		     'grabbable': true
		 };
		 // Highlight the focus if there.
		 if( focus_id && node.id() == focus_id ){
		     node_opts['css'] = { 'background-color': '#111111' };
		 }
		 cynodes.push(node_opts);
	     });

	// Edges.
	var cyedges = [];
	each(graph.all_edges(),
	     function(edge){
		 var sub = edge.subject_id();
		 var obj = edge.object_id();
		 var prd = edge.predicate_id();
		 //var clr = context.color(prd); TODO
		 var clr = '#808080';
                 var eid = '' + prd + '_' + sub + '_' + obj;
		 ll('edge: ' + eid);
		 cyedges.push(
                     {
			 //'group': 'edges',
			 'data': {
                             'id': eid,
                             'pred': prd,
                             // 'source': sub,
                             // 'target': obj
                             'source': obj,
                             'target': sub
			 },
			 css: {
			     'line-color': clr
			 }
                     });
	     });

	// Render.
	var elements = {nodes: cynodes, edges: cyedges};

	jQuery(demo_output_elt).cytoscape(
            {
		userPanningEnabled: true, // pan over box select
		'elements': elements,
		'layout': {
                    'name': 'breadthfirst',
                    'directed': true,
                    //'fit': true,
		    //'maximalAdjustments': 0,
		    'circle': false,
		    'roots': cyroots
		},
		// 'layout': {
                //     'name': 'cose'//,
                //     // 'directed': true,
                //     // //'fit': true,
		//     // //'maximalAdjustments': 0,
		//     // 'circle': false,
		//     // 'roots': cyroots
		// },
		hideLabelsOnViewport: true, // opt
		hideEdgesOnViewport: true, // opt
		textureOnViewport: true, // opt
		'style': [
                    {
			selector: 'node',
			css: {
                            'content': 'data(label)',
			    'font-size': 8,
			    'min-zoomed-font-size': 6, //10,
                            'text-valign': 'center',
                            'color': 'white',
			    'shape': 'roundrectangle',
                            'text-outline-width': 2,
                            'text-outline-color': '#222222'
			}
                    },
                    {
			selector: 'edge',
			css: {
                            //'content': 'data(pred)', // opt
                            'width': 2,
			    //'curve-style': 'haystack', // opt
                            'line-color': '#6fb1fc'
                            //'source-arrow-shape': 'triangle' // opt
			}
                    }
		]
            });

	var cy = jQuery(demo_output_elt).cytoscape('get');

	// Bind events.
	// cy.nodes().bind('click',
	// 		function(e){
	// 		    e.stopPropagation();
	// 		    var nid = e.cyTarget.id();
	// 		    man.set_id(nid);
	// 		    //spin.show();
	// 		    man.search();
	// 		});
	cy.nodes().bind('mouseover',
			function(e){
			    e.stopPropagation();
			    var nid = e.cyTarget.id();
			    var nlbl = info_lookup[nid]['label'];
 			    var popt = {
				title: nid,
				content: nlbl,
				animation: false,
				placement: 'top',
				trigger: 'manual'
			    };
			    //jQuery(this).popover(popt);
			    //jQuery(this).popover('show');
			    // TODO/BUG: this popover positioning got out of
			    // hand; just rewrite doing it manually with a
			    // div from bootstrap like normal people.
			    // (couldn't do it the obvious way because the
			    // canvas elements are just layers with nothing
			    // to adere to).
			    var epos = e.cyRenderedPosition;
			    jQuery(e.originalEvent.target).popover(popt);
			    jQuery(e.originalEvent.target).popover('show');
			    jQuery('.arrow').hide();
			    jQuery('.popover').css('top', epos.y -100);
			    jQuery('.popover').css('left', epos.x -100);
			    //ll('node: ' + nid);
			});
	cy.nodes().bind('mouseout',
			function(e){
			    e.stopPropagation();
			    jQuery(e.originalEvent.target).popover('destroy');
			});
	// each(cy.nodes(),
	//      function(nkey, node){
	// 	 jQuery(node.element()).popover(popt);
	//      });

	cy.edges().unselectify(); // opt
	cy.boxSelectionEnabled(false);
	cy.resize();

	// Make sure re respect resizing.
	jQuery(window).off('resize');
	jQuery(window).on('resize',
			  function(){
			      cy.resize();
			  });

	//spin.hide();
	//ll('done');
    }

    ///
    /// Demo runner.
    ///

    // For now, use a generic manager with a generic response.
    var manager = new bbop.rest.manager.jquery(bbop.rest.response.json);
    // Generic responder.
    function _success_callback(resp, man){
	// The response is a generic bbop.rest.response.json.
	// Peel out the graph and render it.
	if( resp.okay() ){
	    // var gj = JSON.parse(resp.raw());
	    var g = new bbop.model.graph();
	    g.load_json(resp.raw());
	    draw_graph(g);
	}else{
	    ll('the response was not okay');
	}
    }
    manager.register('success', 'draw', _success_callback);
    function data_call(arg1, arg2, arg3, arg4){
	var base = 'http://kato.crbs.ucsd.edu:9000/scigraph/graph/paths/' + arg4;
	var rsrc = base + '/' + arg1 + '/' + arg2 + '.jsonp?length=' + arg3;
	manager.resource(rsrc);
	manager.method('get');
	manager.use_jsonp(true);
	manager.jsonp_callback('callback');
	manager.action();
    }

    ///
    /// Activate autocomplete and actions on inputs for demo.
    ///

    // Arguments for autocomplete box.
    var ac_args = {
	position : {
       	    my: "left top",
            at: "left bottom",
	    collision: "none"
	},
	source: function(request, response) {
	    console.log("trying autocomplete on " + request.term);

	    // Argument response from source gets map as argument.
	    var _parse_data_item = function(item){

		// If has a category, append that; if not try to use
		// namespace; otherwise, nothing.
		var appendee = '';
		if( item ){
		    if( item['categories'] && ! bbop.core.is_empty(item['categories']) ){
			appendee = item['categories'].join(' ');
		    }else if( item['fragment'] ){
			// Get first split on '_'.
			var fspl = bbop.core.first_split('_', item['fragment']);
			if( fspl[0] ){
			    appendee = fspl[0];
			}
		    }
		}

		return {
		    label: item.label,
		    tag: appendee,
		    name: item.fragment
		};
	    };
	    var _on_success = function(data) {

		// Get the list out of the return.
		if( data && data['list'] ){

		    var ldata = data['list'];

		    // Pare out duplicates. Assume existance of 'id'
		    // field. Would really be nice to have bbop.core in
		    // here...
		    var pared_data = [];
		    var seen_ids = {};
		    for( var di = 0; di < ldata.length; di++ ){
			var datum = ldata[di];
			var datum_id = datum['uri'];
			if( ! seen_ids[datum_id] ){
			    // Only add new ids to pared data list.
			    pared_data.push(datum);

			    // Block them in the future.
			    seen_ids[datum_id] = true;
			}
		    }

		    // Map out into the display format.
		    var map = jQuery.map(pared_data, _parse_data_item);
		    response(map);
		}
	    };

	    //var query = "/autocomplete/"+request.term+".json";
	    var query = 'http://kato.crbs.ucsd.edu:9000/scigraph/vocabulary/search/' + request.term + '*.jsonp?limit=20&searchSynonyms=true';
	    //var query = "/autocomplete/"+request.term+".json";
	    jQuery.ajax({
			    url: query,
			    dataType: 'jsonp',
			    'jsonp': 'callback',
			    /*data: {
			     prefix: request.term,
			     },*/
			    success: _on_success
			});
	},
	messages: {
            noResults: '',
	    results: function() {}
        }
    };

    // Create our own custom rendering to make the categories a little
    // nicer to look at (as minor data).
    // http://jqueryui.com/autocomplete/#custom-data
    function _sub_render(ul, item){
	var li = jQuery('
');
	li.append('' +
		  '' +
		  item.label +
		  '' +
		  ' ' +
		  '' +
		  item.tag +
		  '' +
		  '');
	li.appendTo(ul);
	return li;
    }

    // Activate first autocomplete.
    ac_args['select'] = function(event, ui) {
	event.preventDefault();
	if (ui.item !== null) {
	    ll('got: ' + ui.item.name);
	    jQuery(auto_1_input_elt).val(ui.item.name);
	}
    };
    var jac1 = jQuery(auto_1_input_elt).autocomplete(ac_args);
    jac1.data('ui-autocomplete')._renderItem = _sub_render;

    // Activate second autocomplete.
    ac_args['select'] = function(event, ui) {
	event.preventDefault();
	if (ui.item !== null) {
	    ll('got: ' + ui.item.name);
	    jQuery(auto_2_input_elt).val(ui.item.name);
	}
    };
    var jac2 = jQuery(auto_2_input_elt).autocomplete(ac_args);
    jac2.data('ui-autocomplete')._renderItem = _sub_render;

    // Rewire the form to produce the graph.
    jQuery(demo_input_elt).submit(
	function(event){
	    event.preventDefault();

	    var v1 = jQuery(auto_1_input_elt).val() || '';
	    var v2 = jQuery(auto_2_input_elt).val() || '';
	    var s1 = jQuery(sel_1_input_elt).val() || '';
	    var s2 = jQuery(sel_2_input_elt).val() || '';

	    // TODO:
	    if( v1 != '' && v2 != '' && s1 != '' && s2 != '' ){
		// alert('TODO: only using demo input; ignoring: ' +
		// 	 [v1, v2, s1].join(', '));
		data_call(v1, v2, s1, s2);
	    }else{
		alert('insufficient args: ' + [v1, v2, s1, s2].join(', ') +
		      '; fall back on demo');
		// TODO: need good data source
		// This demo lifted from: http://beta.neuinfo.org:9000/graphdemo/graph/path/short/UBERON_0000004/UBERON_0001062.jsonp?length=5
		var dgraph = {"nodes":[{"id":"http://purl.obolibrary.org/obo/UBERON_0000004","lbl":"olfactory apparatus"},{"id":"http://purl.obolibrary.org/obo/UBERON_0004121","lbl":"ectoderm-derived structure"},{"id":"http://purl.obolibrary.org/obo/UBERON_0000061","lbl":"anatomical structure"},{"id":"http://purl.obolibrary.org/obo/UBERON_0000465","lbl":"material anatomical entity"},{"id":"http://purl.obolibrary.org/obo/UBERON_0001062","lbl":"anatomical entity"}],"edges":[{"sub":"http://purl.obolibrary.org/obo/UBERON_0000004","obj":"http://purl.obolibrary.org/obo/UBERON_0004121","pred":"SUBCLASS_OF"},{"sub":"http://purl.obolibrary.org/obo/UBERON_0004121","obj":"http://purl.obolibrary.org/obo/UBERON_0000061","pred":"SUBCLASS_OF"},{"sub":"http://purl.obolibrary.org/obo/UBERON_0000061","obj":"http://purl.obolibrary.org/obo/UBERON_0000465","pred":"SUBCLASS_OF"},{"sub":"http://purl.obolibrary.org/obo/UBERON_0000465","obj":"http://purl.obolibrary.org/obo/UBERON_0001062","pred":"SUBCLASS_OF"}]};
		// TODO: need real managed data source; see above
		var dg = new bbop.model.graph();
		dg.load_json(dgraph);
		draw_graph(dg);
	    }

	});

    ll('Done ready!');
};

// jQuery gets to bootstrap everything.
jQuery(document).ready(
    function(){
	CyPathDemoInit();
    });
<commit_msg>backed by a more proper term search<commit_after>
function CyPathDemoInit(){

    ///
    /// Setup and preamble.
    ///

    //var DEBUG = false;
    var DEBUG = true;

    // HTML connctions.
    var demo_output_id = 'cydemo';
    var demo_output_elt = '#' + demo_output_id;
    var demo_input_id = 'demo_input';
    var demo_input_elt = '#' + demo_input_id;
    var auto_1_input_id = 'auto_1_input';
    var auto_1_input_elt = '#' + auto_1_input_id;
    var auto_2_input_id = 'auto_2_input';
    var auto_2_input_elt = '#' + auto_2_input_id;
    var sel_1_input_id = 'sel_1_input';
    var sel_1_input_elt = '#' + sel_1_input_id;
    var sel_2_input_id = 'sel_2_input';
    var sel_2_input_elt = '#' + sel_2_input_id;

    // Aliases.
    var each = bbop.core.each;
    var ll = function(str){
	if( DEBUG && console && console.log ){
	    console.log(str);
	}
    };

    ll('Start ready!');

    ///
    /// Renderer originally lifted from AmiGO 2 demo.
    ///

    //
    function draw_graph(graph, focus_id){

	//ll('in');

	jQuery(demo_output_elt).empty();

	// Nodes.
	var cyroots = [];
	var cynodes = [];
	var info_lookup = {};
	each(graph.all_nodes(),
	     function(node){
		 ll('node: ' + node.id());
		 info_lookup[node.id()] = {
		     'id': node.id(),
		     'label': node.label() || node.id()
		 };
		 if( graph.is_root_node(node.id()) ){
		     cyroots.push(node.id());
		 }
		 var clr;
		 if( focus && node.id() == focus_id ){

		 }
		 var node_opts = {
		     //'group': 'nodes',
		     'data': {
			 'id': node.id(),
			 'label': node.label() || node.id()
		     },
		     'grabbable': true
		 };
		 // Highlight the focus if there.
		 if( focus_id && node.id() == focus_id ){
		     node_opts['css'] = { 'background-color': '#111111' };
		 }
		 cynodes.push(node_opts);
	     });

	// Edges.
	var cyedges = [];
	each(graph.all_edges(),
	     function(edge){
		 var sub = edge.subject_id();
		 var obj = edge.object_id();
		 var prd = edge.predicate_id();
		 //var clr = context.color(prd); TODO
		 var clr = '#808080';
                 var eid = '' + prd + '_' + sub + '_' + obj;
		 ll('edge: ' + eid);
		 cyedges.push(
                     {
			 //'group': 'edges',
			 'data': {
                             'id': eid,
                             'pred': prd,
                             // 'source': sub,
                             // 'target': obj
                             'source': obj,
                             'target': sub
			 },
			 css: {
			     'line-color': clr
			 }
                     });
	     });

	// Render.
	var elements = {nodes: cynodes, edges: cyedges};

	jQuery(demo_output_elt).cytoscape(
            {
		userPanningEnabled: true, // pan over box select
		'elements': elements,
		'layout': {
                    'name': 'breadthfirst',
                    'directed': true,
                    //'fit': true,
		    //'maximalAdjustments': 0,
		    'circle': false,
		    'roots': cyroots
		},
		// 'layout': {
                //     'name': 'cose'//,
                //     // 'directed': true,
                //     // //'fit': true,
		//     // //'maximalAdjustments': 0,
		//     // 'circle': false,
		//     // 'roots': cyroots
		// },
		hideLabelsOnViewport: true, // opt
		hideEdgesOnViewport: true, // opt
		textureOnViewport: true, // opt
		'style': [
                    {
			selector: 'node',
			css: {
                            'content': 'data(label)',
			    'font-size': 8,
			    'min-zoomed-font-size': 6, //10,
                            'text-valign': 'center',
                            'color': 'white',
			    'shape': 'roundrectangle',
                            'text-outline-width': 2,
                            'text-outline-color': '#222222'
			}
                    },
                    {
			selector: 'edge',
			css: {
                            //'content': 'data(pred)', // opt
                            'width': 2,
			    //'curve-style': 'haystack', // opt
                            'line-color': '#6fb1fc'
                            //'source-arrow-shape': 'triangle' // opt
			}
                    }
		]
            });

	var cy = jQuery(demo_output_elt).cytoscape('get');

	// Bind events.
	// cy.nodes().bind('click',
	// 		function(e){
	// 		    e.stopPropagation();
	// 		    var nid = e.cyTarget.id();
	// 		    man.set_id(nid);
	// 		    //spin.show();
	// 		    man.search();
	// 		});
	cy.nodes().bind('mouseover',
			function(e){
			    e.stopPropagation();
			    var nid = e.cyTarget.id();
			    var nlbl = info_lookup[nid]['label'];
 			    var popt = {
				title: nid,
				content: nlbl,
				animation: false,
				placement: 'top',
				trigger: 'manual'
			    };
			    //jQuery(this).popover(popt);
			    //jQuery(this).popover('show');
			    // TODO/BUG: this popover positioning got out of
			    // hand; just rewrite doing it manually with a
			    // div from bootstrap like normal people.
			    // (couldn't do it the obvious way because the
			    // canvas elements are just layers with nothing
			    // to adere to).
			    var epos = e.cyRenderedPosition;
			    jQuery(e.originalEvent.target).popover(popt);
			    jQuery(e.originalEvent.target).popover('show');
			    jQuery('.arrow').hide();
			    jQuery('.popover').css('top', epos.y -100);
			    jQuery('.popover').css('left', epos.x -100);
			    //ll('node: ' + nid);
			});
	cy.nodes().bind('mouseout',
			function(e){
			    e.stopPropagation();
			    jQuery(e.originalEvent.target).popover('destroy');
			});
	// each(cy.nodes(),
	//      function(nkey, node){
	// 	 jQuery(node.element()).popover(popt);
	//      });

	cy.edges().unselectify(); // opt
	cy.boxSelectionEnabled(false);
	cy.resize();

	// Make sure re respect resizing.
	jQuery(window).off('resize');
	jQuery(window).on('resize',
			  function(){
			      cy.resize();
			  });

	//spin.hide();
	//ll('done');
    }

    ///
    /// Demo runner.
    ///

    // For now, use a generic manager with a generic response.
    var manager = new bbop.rest.manager.jquery(bbop.rest.response.json);
    // Generic responder.
    function _success_callback(resp, man){
	// The response is a generic bbop.rest.response.json.
	// Peel out the graph and render it.
	if( resp.okay() ){
	    // var gj = JSON.parse(resp.raw());
	    var g = new bbop.model.graph();
	    g.load_json(resp.raw());
	    draw_graph(g);
	}else{
	    ll('the response was not okay');
	}
    }
    manager.register('success', 'draw', _success_callback);
    function data_call(arg1, arg2, arg3, arg4){
	var base = 'http://kato.crbs.ucsd.edu:9000/scigraph/graph/paths/' + arg4;
	var rsrc = base + '/' + arg1 + '/' + arg2 + '.jsonp?length=' + arg3;
	manager.resource(rsrc);
	manager.method('get');
	manager.use_jsonp(true);
	manager.jsonp_callback('callback');
	manager.action();
    }

    ///
    /// Activate autocomplete and actions on inputs for demo.
    ///

    // Arguments for autocomplete box.
    var ac_args = {
	position : {
       	    my: "left top",
            at: "left bottom",
	    collision: "none"
	},
	source: function(request, response) {
	    console.log("trying autocomplete on " + request.term);

	    // Argument response from source gets map as argument.
	    var _parse_data_item = function(item){

		// If has a category, append that; if not try to use
		// namespace; otherwise, nothing.
		var appendee = '';
		if( item ){
		    if( item['concept']['categories'] && ! bbop.core.is_empty(item['concept']['categories']) ){
			appendee = item['concept']['categories'].join(' ');
		    }else if( item['concept']['fragment'] ){
			// Get first split on '_'.
			var fspl = bbop.core.first_split('_', item['concept']['fragment']);
			if( fspl[0] ){
			    appendee = fspl[0];
			}
		    }
		}

		return {
		    label: item['completion'],
		    tag: appendee,
		    name: item['concept']['fragment']
		};
	    };
	    var _on_success = function(data) {

		// Get the list out of the return.
		if( data && data['list'] ){

		    var ldata = data['list'];

		    // Pare out duplicates. Assume existance of structure.
		    var pared_data = [];
		    var seen_ids = {};
		    for( var di = 0; di < ldata.length; di++ ){
			var datum = ldata[di];
			var datum_id = datum['concept']['uri'];
			if( ! seen_ids[datum_id] ){
			    // Only add new ids to pared data list.
			    pared_data.push(datum);

			    // Block them in the future.
			    seen_ids[datum_id] = true;
			}
		    }

		    // Map out into the display format.
		    var map = jQuery.map(pared_data, _parse_data_item);
		    response(map);
		}
	    };

	    //var query = "/autocomplete/"+request.term+".json";
	    var query = 'http://kato.crbs.ucsd.edu:9000/scigraph/vocabulary/prefix/' + request.term + '.jsonp?limit=20&searchSynonyms=true';
	    //var query = "/autocomplete/"+request.term+".json";
	    jQuery.ajax({
			    url: query,
			    dataType: 'jsonp',
			    'jsonp': 'callback',
			    /*data: {
			     prefix: request.term,
			     },*/
			    success: _on_success
			});
	},
	messages: {
            noResults: '',
	    results: function() {}
        }
    };

    // Create our own custom rendering to make the categories a little
    // nicer to look at (as minor data).
    // http://jqueryui.com/autocomplete/#custom-data
    function _sub_render(ul, item){
	var li = jQuery('
');
	li.append('' +
		  '' +
		  item.label +
		  '' +
		  ' ' +
		  '' +
		  item.tag +
		  '' +
		  '');
	li.appendTo(ul);
	return li;
    }

    // Activate first autocomplete.
    ac_args['select'] = function(event, ui) {
	event.preventDefault();
	if (ui.item !== null) {
	    ll('got: ' + ui.item.name);
	    jQuery(auto_1_input_elt).val(ui.item.name);
	}
    };
    var jac1 = jQuery(auto_1_input_elt).autocomplete(ac_args);
    jac1.data('ui-autocomplete')._renderItem = _sub_render;

    // Activate second autocomplete.
    ac_args['select'] = function(event, ui) {
	event.preventDefault();
	if (ui.item !== null) {
	    ll('got: ' + ui.item.name);
	    jQuery(auto_2_input_elt).val(ui.item.name);
	}
    };
    var jac2 = jQuery(auto_2_input_elt).autocomplete(ac_args);
    jac2.data('ui-autocomplete')._renderItem = _sub_render;

    // Rewire the form to produce the graph.
    jQuery(demo_input_elt).submit(
	function(event){
	    event.preventDefault();

	    var v1 = jQuery(auto_1_input_elt).val() || '';
	    var v2 = jQuery(auto_2_input_elt).val() || '';
	    var s1 = jQuery(sel_1_input_elt).val() || '';
	    var s2 = jQuery(sel_2_input_elt).val() || '';

	    // TODO:
	    if( v1 != '' && v2 != '' && s1 != '' && s2 != '' ){
		// alert('TODO: only using demo input; ignoring: ' +
		// 	 [v1, v2, s1].join(', '));
		data_call(v1, v2, s1, s2);
	    }else{
		alert('insufficient args: ' + [v1, v2, s1, s2].join(', ') +
		      '; fall back on demo');
		// TODO: need good data source
		// This demo lifted from: http://beta.neuinfo.org:9000/graphdemo/graph/path/short/UBERON_0000004/UBERON_0001062.jsonp?length=5
		var dgraph = {"nodes":[{"id":"http://purl.obolibrary.org/obo/UBERON_0000004","lbl":"olfactory apparatus"},{"id":"http://purl.obolibrary.org/obo/UBERON_0004121","lbl":"ectoderm-derived structure"},{"id":"http://purl.obolibrary.org/obo/UBERON_0000061","lbl":"anatomical structure"},{"id":"http://purl.obolibrary.org/obo/UBERON_0000465","lbl":"material anatomical entity"},{"id":"http://purl.obolibrary.org/obo/UBERON_0001062","lbl":"anatomical entity"}],"edges":[{"sub":"http://purl.obolibrary.org/obo/UBERON_0000004","obj":"http://purl.obolibrary.org/obo/UBERON_0004121","pred":"SUBCLASS_OF"},{"sub":"http://purl.obolibrary.org/obo/UBERON_0004121","obj":"http://purl.obolibrary.org/obo/UBERON_0000061","pred":"SUBCLASS_OF"},{"sub":"http://purl.obolibrary.org/obo/UBERON_0000061","obj":"http://purl.obolibrary.org/obo/UBERON_0000465","pred":"SUBCLASS_OF"},{"sub":"http://purl.obolibrary.org/obo/UBERON_0000465","obj":"http://purl.obolibrary.org/obo/UBERON_0001062","pred":"SUBCLASS_OF"}]};
		// TODO: need real managed data source; see above
		var dg = new bbop.model.graph();
		dg.load_json(dgraph);
		draw_graph(dg);
	    }

	});

    ll('Done ready!');
};

// jQuery gets to bootstrap everything.
jQuery(document).ready(
    function(){
	CyPathDemoInit();
    });
<|endoftext|>