<commit_before>var m = require('mithril');
var Raven = require('raven-js');
var $osf = require('js/osfHelpers');
var Markdown = require('pagedown-ace-converter');
Markdown.getSanitizingConverter = require('pagedown-ace-sanitizer').getSanitizingConverter;
require('imports?Markdown=pagedown-ace-converter!pagedown-ace-editor');
require('ace-noconflict');
require('ace-mode-markdown');
require('ace-ext-language_tools');
require('addons/wiki/static/ace-markdown-snippets.js');

var util = require('./util.js');

var FileEditor = {
    controller: function(contentUrl) {
        var self = this;
        self.url = contentUrl;
        self.loaded = false;
        self.initialText = '';
        self.editor = undefined;

        self.bindAce = function(element, isInitialized, context) {
            if (isInitialized) return;
            self.editor = ace.edit(element.id);
        };

        self.reloadFile = function() {
            self.loaded = false;
            $.ajax({
                type: 'GET',
                url: self.url,
                beforeSend: $osf.setXHRAuthorization
            }).done(function (response) {
                m.startComputation();
                self.loaded = true;
                self.initialText = response;
                m.endComputation();
            }).fail(function (xhr, textStatus, error) {
                $osf.growl('Error','The file content could not be loaded.');
                Raven.captureMessage('Could not GET file contents.', {
                    url: self.url,
                    textStatus: textStatus,
                    error: error
                });
            });
        };

        self.reloadFile();
    },
    view: function(ctrl) {
        if (!ctrl.loaded) return util.Spinner;

        return m('.editor-pane', [
            m('.editor', {config: ctrl.bindAce}),
            m('.panel', [
                m('button.btn.btn-danger', 'Revert'),
                m('button.btn.btn-danger', 'Save')
            ])
        ]);

    }
};

module.exports = FileEditor;

///

///

///

///

///

///

///

///

///

///                                                Edit
///

///

///

///

///

///
///
///
///
///
///
///

///

///

///

///

///

///

///

///                        <form id="file-edit-form">
///

///

///

///

///

///                                              {{#ifnot: id === '${user['id']}'}}
///

///
///

///                                              {{/ifnot}}
///

///

///
Loading. . .

///

///

///

///

///

///

///

///

///                                            <button id="revert-button" class="btn btn-danger" data-bind="click: revertChanges, enable: changed()">Revert</button>
///                                            <button id="save-button" class="btn btn-success" data-bind="click: saveChanges, enable: changed()">Save</button>
///

///

///

///
///                                <textarea id="original_content" style="display: none;"></textarea>
///                                <textarea id="edit_content" style="display: none;" data-bind="value: currentText"></textarea>

///

///                        </form>
///

///

///

<commit_msg>Some of editor now works<commit_after>var m = require('mithril');
var Raven = require('raven-js');
var $osf = require('js/osfHelpers');
require('ace-noconflict');
require('ace-mode-markdown');
require('ace-ext-language_tools');
require('addons/wiki/static/ace-markdown-snippets.js');
var Markdown = require('pagedown-ace-converter');
Markdown.getSanitizingConverter = require('pagedown-ace-sanitizer').getSanitizingConverter;
require('imports?Markdown=pagedown-ace-converter!pagedown-ace-editor');

var util = require('./util.js');

var FileEditor = {
    controller: function(contentUrl, shareWSUrl, editorMeta, triggerReload) {
        var self = this;
        self.url = contentUrl;
        self.loaded = false;
        self.initialText = '';
        self.editor = undefined;
        self.editorMeta = editorMeta;
        self.triggerReload = triggerReload;
        self.changed = m.prop(false);

        self.bindAce = function(element, isInitialized, context) {
            if (isInitialized) return;
            self.editor = ace.edit(element.id);
            self.editor.setValue(self.initialText);
            self.editor.on('change', self.onChanged);
            // var ShareJSDoc = require('js/pages/ShareJSDocFile.js');
            // new ShareJSDoc(self.contentURL, self.editorMetadata, self.editor);
        };

        self.reloadFile = function() {
            self.loaded = false;
            $.ajax({
                type: 'GET',
                url: self.url,
                beforeSend: $osf.setXHRAuthorization
            }).done(function (response) {
                m.startComputation();
                self.loaded = true;
                self.initialText = response;
                m.endComputation();
            }).fail(function (xhr, textStatus, error) {
                $osf.growl('Error','The file content could not be loaded.');
                Raven.captureMessage('Could not GET file contents.', {
                    url: self.url,
                    textStatus: textStatus,
                    error: error
                });
            });
        };

        self.saveChanges = function() {
            var request = $.ajax({
                type: 'PUT',
                url: self.url,
                data: self.editor.getValue(),
                beforeSend: $osf.setXHRAuthorization
            }).done(function () {
                self.triggerReload();
                self.initText = self.editor.getValue();
            }).fail(function(error) {
                self.editor.setValue(self.initialText);
                $osf.growl('Error', 'The file could not be updated.');
                Raven.captureMessage('Could not PUT file content.', {
                    error: error,
                    url: self.url,
                });
            });
        };

        self.revertChanges = function() {
            self.reloadFile();
        };

        self.onChanged = function(e) {
            //To avoid extra typing
            var file1 = self.initialText;
            var file2 = !self.editor ? '' : self.editor.getValue();

            var clean1 = typeof file1 === 'string' ?
                file1.replace(/(\r\n|\n|\r)/gm, '\n') : '';
            var clean2 = typeof file2 === 'string' ?
                file2.replace(/(\r\n|\n|\r)/gm, '\n') : '';

            self.changed(clean1 !== clean2);
        };

        self.reloadFile();
    },
    view: function(ctrl) {
        if (!ctrl.loaded) return util.Spinner;

        return m('.editor-pane', [
            m('.wmd-input.wiki-editor#editor', {config: ctrl.bindAce}),
            m('.osf-panel-footer', [
                m('.col-xs-12', [
                    m('.pull-right', [
                        // m('button.btn.btn-danger', {onclick: ctrl.revertChanges, disabled: ctrl.changed() ? '' : 'disabled'}, 'Revert'),
                        // m('button.btn.btn-success', {onclick: ctrl.saveChanges, disabled: ctrl.changed() ? '' : 'disabled'}, 'Save')
                        m('button.btn.btn-danger', {onclick: ctrl.revertChanges}, 'Revert'),
                        m('button.btn.btn-success', {onclick: ctrl.saveChanges}, 'Save')
                    ])
                ])
            ])
        ]);

    }
};

module.exports = FileEditor;
<|endoftext|>


<commit_before>/* eslint-disable max-len */
/* eslint-disable no-param-reassign */
import { UPDATE_LOCATION } from 'react-router-redux'
import uniq from 'lodash.uniq'
import * as ACTION_TYPES from '../constants/action_types'
import * as MAPPING_TYPES from '../constants/mapping_types'
import commentMethods from './experience_updates/comments'
import postMethods from './experience_updates/posts'
import relationshipMethods from './experience_updates/relationships'

// adding methods and accessing them from this object
// allows the unit tests to stub methods in this module
const methods = {}
let path = '/'
let prevTerms = null
let hasLoadedFirstStream = false

function mergeModel(state, type, params) {
  if (params.id) {
    const newType = { ...state[type] }
    newType[params.id] = { ...newType[params.id], ...params }
    state[type] = newType
  }
}
methods.mergeModel = (state, type, params) =>
  mergeModel(state, type, params)

function addModels(state, type, data) {
  // add state['modelType']
  if (!state[type]) { state[type] = {} }
  const ids = []
  if (type === MAPPING_TYPES.CATEGORIES) {
    data[type].map((category, index) => {
      const newType = { ...state[type] }
      const id = index + 1
      newType[id] = category
      state[type] = newType
      ids.push(id)
    })
  } else if (data[type] && data[type].length) {
    // add arrays of models to state['modelType']['id']
    data[type].map((model) => {
      methods.mergeModel(state, type, model)
      ids.push(model.id)
    })
  } else if (data[type] && typeof data[type] === 'object') {
    // add single model objects to state['modelType']['id']
    const model = data[type]
    methods.mergeModel(state, type, model)
    ids.push(model.id)
  }
  return ids
}
methods.addModels = (state, type, data) =>
  addModels(state, type, data)

function addNewIdsToResult(state, newState) {
  if (!newState.pages) { newState.pages = {} }
  const result = newState.pages[path]
  if (!result || !result.newIds) { return state }
  result.ids = result.newIds.concat(result.ids)
  delete result.newIds
  return newState
}
methods.addNewIdsToResult = (state, newState) =>
  addNewIdsToResult(state, newState)

function setLayoutMode(action, state, newState) {
  if (!newState.pages) { newState.pages = {} }
  const result = newState.pages[path]
  if (!result || (result && result.mode === action.payload.mode)) { return state }
  result.mode = action.payload.mode
  return newState
}
methods.setLayoutMode = (action, state, newState) =>
  setLayoutMode(action, state, newState)

// parses the 'linked' node of the JSON
// api responses into the json store
function parseLinked(linked, newState) {
  if (!linked) { return }
  for (const linkedType in linked) {
    if ({}.hasOwnProperty.call(linked, linkedType)) {
      methods.addModels(newState, linkedType, linked)
    }
  }
}
methods.parseLinked = (linked, newState) =>
  parseLinked(linked, newState)

// parse main part of request into the state and
// pull out the ids as this is the main payload
function getResult(response, newState, action) {
  const { mappingType, resultFilter } = action.meta
  const ids = methods.addModels(newState, mappingType, response)
  // set the result to the resultFilter if it exists
  const result = (typeof resultFilter === 'function') ? resultFilter(response[mappingType]) : { type: mappingType, ids }
  result.pagination = action.payload.pagination
  return result
}
methods.getResult = (response, newState, action) =>
  getResult(response, newState, action)

// TODO: need to test the existingResult conditional logic!!!!
function updateResult(response, newState, action) {
  if (!newState.pages) { newState.pages = {} }
  const result = methods.getResult(response, newState, action)
  const { resultKey } = action.meta
  // the action payload pathname comes from before the fetch so that
  // we can be sure that the result is being assigned to the proper page
  const pathname = action.payload && action.payload.pathname ? action.payload.pathname : path
  const resultPath = resultKey ? `${pathname}_${resultKey}` : pathname
  const existingResult = newState.pages[resultPath]
  if (existingResult && action.type === ACTION_TYPES.LOAD_NEXT_CONTENT_SUCCESS) {
    existingResult.pagination = result.pagination
    if (existingResult.next) {
      existingResult.next.ids = uniq(existingResult.next.ids.concat(result.ids))
    } else {
      existingResult.next = result
    }
  } else if (existingResult && existingResult.ids[0] !== result.ids[0]) {
    const existingIndex = result.ids.indexOf(existingResult.ids[0])
    // only do this for top level streams, nested ones like lovers/reposters
    // should just update with the new results
    if (hasLoadedFirstStream && !resultKey && existingIndex > 0 && !pathname.match(/\/(find|search)/)) {
      existingResult.newIds = result.ids.slice(0, existingIndex)
    } else {
      // this condition should only happen if there was an existingResult
      // and the new result is more than one page away from the existingResult
      // resetting the result would clear out any of the 'old' pages in next
      // this could break down if the results were random and needed a seed
      // for pagination at which point we would want to check against the seed
      // and reset the result if the previous seed didn't match the new one
      // to avoid duplicate results
      newState.pages[resultPath] = { ...existingResult, ...result }
    }
  } else if (existingResult) {
    // this keeps the pagination correct on a refresh
    // should probably be resetting the results here, but the more button breaks
    newState.pages[resultPath] = { ...result, ...existingResult }
  } else {
    newState.pages[resultPath] = result
  }
}
methods.updateResult = (response, newState, action) =>
  updateResult(response, newState, action)

function clearSearchResults(state, newState, action) {
  if (!newState.pages) return state
  const pathname = action.payload.pathname
  const existingResult = newState.pages[pathname]
  if (existingResult) {
    existingResult.ids = []
    if (existingResult.next) {
      existingResult.next.ids = []
    }
    return newState
  }
  return state
}
methods.clearSearchResults = (state, newState, action) =>
  clearSearchResults(state, newState, action)

export default function json(state = {}, action = { type: '' }) {
  let newState = { ...state }
  // whitelist actions
  switch (action.type) {
    case ACTION_TYPES.ADD_NEW_IDS_TO_RESULT:
      return methods.addNewIdsToResult(state, newState)
    case ACTION_TYPES.COMMENT.DELETE_REQUEST:
    case ACTION_TYPES.COMMENT.DELETE_SUCCESS:
    case ACTION_TYPES.COMMENT.DELETE_FAILURE:
      return commentMethods.deleteComment(state, newState, action)
    case ACTION_TYPES.LOAD_NEXT_CONTENT_SUCCESS:
    case ACTION_TYPES.LOAD_STREAM_SUCCESS:
      // fall through to parse the rest
      break
    case ACTION_TYPES.POST.DELETE_REQUEST:
    case ACTION_TYPES.POST.DELETE_SUCCESS:
    case ACTION_TYPES.POST.DELETE_FAILURE:
      return postMethods.deletePost(state, newState, action)
    case ACTION_TYPES.POST.LOVE_REQUEST:
    case ACTION_TYPES.POST.LOVE_FAILURE:
      return postMethods.updatePostLoves(state, newState, action)
    case ACTION_TYPES.RELATIONSHIPS.BATCH_UPDATE_INTERNAL:
      return relationshipMethods.batchUpdateRelationship(newState, action)
    case ACTION_TYPES.RELATIONSHIPS.UPDATE_INTERNAL:
    case ACTION_TYPES.RELATIONSHIPS.UPDATE_REQUEST:
    case ACTION_TYPES.RELATIONSHIPS.UPDATE_SUCCESS:
    case ACTION_TYPES.RELATIONSHIPS.UPDATE_FAILURE:
      return relationshipMethods.updateRelationship(newState, action)
    case ACTION_TYPES.SET_LAYOUT_MODE:
      return methods.setLayoutMode(action, state, newState)
    case UPDATE_LOCATION:
      path = action.payload.pathname
      if (action.payload.query.terms && prevTerms !== action.payload.query.terms) {
        newState = methods.clearSearchResults(state, newState, action)
        prevTerms = action.payload.query.terms
        return newState
      }
      return state
    default:
      return state
  }
  const { response } = action.payload
  if (!response) { return state }
  // parse the linked part of the response into the state
  methods.parseLinked(response.linked, newState)
  // parse main part of response into the state
  // and update the paging information
  methods.updateResult(response, newState, action)
  hasLoadedFirstStream = true
  return newState
}

// only used for testing where results get stored
export function setPath(newPath) {
  path = newPath
}

export { json, methods, commentMethods, postMethods, relationshipMethods }

<commit_msg>Don’t allow the user load to clobber the results.<commit_after>/* eslint-disable max-len */
/* eslint-disable no-param-reassign */
import { UPDATE_LOCATION } from 'react-router-redux'
import uniq from 'lodash.uniq'
import * as ACTION_TYPES from '../constants/action_types'
import * as MAPPING_TYPES from '../constants/mapping_types'
import commentMethods from './experience_updates/comments'
import postMethods from './experience_updates/posts'
import relationshipMethods from './experience_updates/relationships'

// adding methods and accessing them from this object
// allows the unit tests to stub methods in this module
const methods = {}
let path = '/'
let prevTerms = null
let hasLoadedFirstStream = false

function mergeModel(state, type, params) {
  if (params.id) {
    const newType = { ...state[type] }
    newType[params.id] = { ...newType[params.id], ...params }
    state[type] = newType
  }
}
methods.mergeModel = (state, type, params) =>
  mergeModel(state, type, params)

function addModels(state, type, data) {
  // add state['modelType']
  if (!state[type]) { state[type] = {} }
  const ids = []
  if (type === MAPPING_TYPES.CATEGORIES) {
    data[type].map((category, index) => {
      const newType = { ...state[type] }
      const id = index + 1
      newType[id] = category
      state[type] = newType
      ids.push(id)
    })
  } else if (data[type] && data[type].length) {
    // add arrays of models to state['modelType']['id']
    data[type].map((model) => {
      methods.mergeModel(state, type, model)
      ids.push(model.id)
    })
  } else if (data[type] && typeof data[type] === 'object') {
    // add single model objects to state['modelType']['id']
    const model = data[type]
    methods.mergeModel(state, type, model)
    ids.push(model.id)
  }
  return ids
}
methods.addModels = (state, type, data) =>
  addModels(state, type, data)

function addNewIdsToResult(state, newState) {
  if (!newState.pages) { newState.pages = {} }
  const result = newState.pages[path]
  if (!result || !result.newIds) { return state }
  result.ids = result.newIds.concat(result.ids)
  delete result.newIds
  return newState
}
methods.addNewIdsToResult = (state, newState) =>
  addNewIdsToResult(state, newState)

function setLayoutMode(action, state, newState) {
  if (!newState.pages) { newState.pages = {} }
  const result = newState.pages[path]
  if (!result || (result && result.mode === action.payload.mode)) { return state }
  result.mode = action.payload.mode
  return newState
}
methods.setLayoutMode = (action, state, newState) =>
  setLayoutMode(action, state, newState)

// parses the 'linked' node of the JSON
// api responses into the json store
function parseLinked(linked, newState) {
  if (!linked) { return }
  for (const linkedType in linked) {
    if ({}.hasOwnProperty.call(linked, linkedType)) {
      methods.addModels(newState, linkedType, linked)
    }
  }
}
methods.parseLinked = (linked, newState) =>
  parseLinked(linked, newState)

// parse main part of request into the state and
// pull out the ids as this is the main payload
function getResult(response, newState, action) {
  const { mappingType, resultFilter } = action.meta
  const ids = methods.addModels(newState, mappingType, response)
  // set the result to the resultFilter if it exists
  const result = (typeof resultFilter === 'function') ? resultFilter(response[mappingType]) : { type: mappingType, ids }
  result.pagination = action.payload.pagination
  return result
}
methods.getResult = (response, newState, action) =>
  getResult(response, newState, action)

// TODO: need to test the existingResult conditional logic!!!!
function updateResult(response, newState, action) {
  if (!newState.pages) { newState.pages = {} }
  const result = methods.getResult(response, newState, action)
  const { resultKey } = action.meta
  // the action payload pathname comes from before the fetch so that
  // we can be sure that the result is being assigned to the proper page
  const pathname = action.payload && action.payload.pathname ? action.payload.pathname : path
  const resultPath = resultKey ? `${pathname}_${resultKey}` : pathname
  const existingResult = newState.pages[resultPath]
  if (existingResult && action.type === ACTION_TYPES.LOAD_NEXT_CONTENT_SUCCESS) {
    existingResult.pagination = result.pagination
    if (existingResult.next) {
      existingResult.next.ids = uniq(existingResult.next.ids.concat(result.ids))
    } else {
      existingResult.next = result
    }
  } else if (existingResult && existingResult.ids[0] !== result.ids[0]) {
    const existingIndex = result.ids.indexOf(existingResult.ids[0])
    // only do this for top level streams, nested ones like lovers/reposters
    // should just update with the new results
    if (hasLoadedFirstStream && !resultKey && existingIndex > 0 && !pathname.match(/\/(find|search)/)) {
      existingResult.newIds = result.ids.slice(0, existingIndex)
    } else {
      // this condition should only happen if there was an existingResult
      // and the new result is more than one page away from the existingResult
      // resetting the result would clear out any of the 'old' pages in next
      // this could break down if the results were random and needed a seed
      // for pagination at which point we would want to check against the seed
      // and reset the result if the previous seed didn't match the new one
      // to avoid duplicate results
      newState.pages[resultPath] = { ...existingResult, ...result }
    }
  } else if (existingResult) {
    // this keeps the pagination correct on a refresh
    // should probably be resetting the results here, but the more button breaks
    newState.pages[resultPath] = { ...result, ...existingResult }
  } else {
    newState.pages[resultPath] = result
  }
}
methods.updateResult = (response, newState, action) =>
  updateResult(response, newState, action)

function clearSearchResults(state, newState, action) {
  if (!newState.pages) return state
  const pathname = action.payload.pathname
  const existingResult = newState.pages[pathname]
  if (existingResult) {
    existingResult.ids = []
    if (existingResult.next) {
      existingResult.next.ids = []
    }
    return newState
  }
  return state
}
methods.clearSearchResults = (state, newState, action) =>
  clearSearchResults(state, newState, action)

export default function json(state = {}, action = { type: '' }) {
  let newState = { ...state }
  // whitelist actions
  switch (action.type) {
    case ACTION_TYPES.ADD_NEW_IDS_TO_RESULT:
      return methods.addNewIdsToResult(state, newState)
    case ACTION_TYPES.COMMENT.DELETE_REQUEST:
    case ACTION_TYPES.COMMENT.DELETE_SUCCESS:
    case ACTION_TYPES.COMMENT.DELETE_FAILURE:
      return commentMethods.deleteComment(state, newState, action)
    case ACTION_TYPES.LOAD_NEXT_CONTENT_SUCCESS:
    case ACTION_TYPES.LOAD_STREAM_SUCCESS:
      // fall through to parse the rest
      break
    case ACTION_TYPES.POST.DELETE_REQUEST:
    case ACTION_TYPES.POST.DELETE_SUCCESS:
    case ACTION_TYPES.POST.DELETE_FAILURE:
      return postMethods.deletePost(state, newState, action)
    case ACTION_TYPES.POST.LOVE_REQUEST:
    case ACTION_TYPES.POST.LOVE_FAILURE:
      return postMethods.updatePostLoves(state, newState, action)
    case ACTION_TYPES.RELATIONSHIPS.BATCH_UPDATE_INTERNAL:
      return relationshipMethods.batchUpdateRelationship(newState, action)
    case ACTION_TYPES.RELATIONSHIPS.UPDATE_INTERNAL:
    case ACTION_TYPES.RELATIONSHIPS.UPDATE_REQUEST:
    case ACTION_TYPES.RELATIONSHIPS.UPDATE_SUCCESS:
    case ACTION_TYPES.RELATIONSHIPS.UPDATE_FAILURE:
      return relationshipMethods.updateRelationship(newState, action)
    case ACTION_TYPES.SET_LAYOUT_MODE:
      return methods.setLayoutMode(action, state, newState)
    case UPDATE_LOCATION:
      path = action.payload.pathname
      if (action.payload.query.terms && prevTerms !== action.payload.query.terms) {
        newState = methods.clearSearchResults(state, newState, action)
        prevTerms = action.payload.query.terms
        return newState
      }
      return state
    default:
      return state
  }
  const { response } = action.payload
  if (!response) { return state }
  // parse the linked part of the response into the state
  methods.parseLinked(response.linked, newState)
  // parse main part of response into the state
  // and update the paging information
  // unless updateResult is false which is used for
  // user details when you want the result to be for
  // posts/following/followers/loves
  if (action.meta.updateResult === false) {
    const { mappingType } = action.meta
    methods.addModels(newState, mappingType, response)
  } else {
    methods.updateResult(response, newState, action)
  }
  hasLoadedFirstStream = true
  return newState
}

// only used for testing where results get stored
export function setPath(newPath) {
  path = newPath
}

export { json, methods, commentMethods, postMethods, relationshipMethods }

<|endoftext|>


<commit_before>var Ripple = require('ripple-lib')
var request = require('request')
var RippleAddress = require('../app/models/ripple_address.js');
var RippleTransaction = require('../app/models/ripple_transaction.js');
var RippleSimpleClient = require('../lib/ripple_simple_client.js');
var sequelize = require("../config/initializers/sequelize.js");
var nconf = require('../config/nconf.js');

var client = new RippleSimpleClient({
  apiUrl: nconf.get('RIPPLE_REST_API')
});

// Proposed!!
/*
client.on('payment:inbound', function(payment) {

});

client.on('payment:outbound', function(payment) {

});

client.listener.start();
*/

sequelize.sync().success(function(){

  getHotWallet(function(wallet){
    address = wallet.address;
    client.address = wallet.address;
    getNextNotification();
    console.log("listening for transactions to ", address);
  });

});

function getNextNotification() {
  client.getNextNotification(function(err, notification){
    if (notification) {
      handlePayment(notification, function(){
        setTimeout(getNextNotification, 2000);
      });
    } else {
      setTimeout(getNextNotification, 2000);
    }
  });
}

function getHotWallet(fn) {
  RippleAddress.find({ where: { type: 'hot' }}).complete(function(err, address) {
    fn(address);
  });
}

function lookupTransaction(transactionHash, fn){
  RippleTransaction.find({ where: {
    transaction_hash: transactionHash
  }}).complete(fn);
}

function handleUnknownPayment(notification, fn) {
  client.getPayment(notification.tx_hash, function(err, payment) {
    if (payment && payment.dst_tag) {
      RippleAddress.find({ where: {
        address: address,
        tag: payment.dst_tag.toString()
      }}).complete(function(err, address){
        if (address) {
          RippleTransaction.create({
            ripple_address_id: address.id,
            to_address: payment.dst_address,
            from_address: payment.src_address,
            from_amount: payment.src_amount.value,
            from_currency: payment.src_amount.currency,
            from_issuer: payment.src_amount.issuer,
            to_address: payment.dst_address,
            to_amount: payment.dst_amount.value,
            to_currency: payment.dst_amount.currency,
            to_issuer: payment.dst_amount.issuer,
            transaction_state: payment.tx_state,
            transaction_hash: payment.tx_hash,
            issuance: false
          }).complete(function(err, transaction) {
            console.log(err);
            fn();
          });
        } else {
          console.log(err);
          fn();
        }
      });
    } else {
      console.log('no destination tag');
      fn();
    }
  });
}

function handleKnownPayment(notification, record, fn) {
  record.transaction_state = notification.tx_result;
  record.save().complete(fn);
}

function handlePayment(notification,fn) {
  if (notification.type == 'payment') {
    lookupTransaction(notification.tx_hash, function(err, transaction) {
      console.log(notification.tx_hash);
      if (transaction) {
        handleKnownPayment(notification, transaction, fn);
      } else {
        handleUnknownPayment(notification, fn);
      }
    });
  } else {
    fn();
  }
}

<commit_msg>[FEATURE] Remove models from incoming listener worker.<commit_after>var Ripple = require('ripple-lib')
var request = require('request')
var nconf = require('../config/nconf.js');

var client = new RippleSimpleClient({
  apiUrl: nconf.get('RIPPLE_REST_API')
});

// Proposed!!
/*
client.listener.on('payment:inbound', function(payment) {
  // create a new ripple transaction
});

client.listener.on('payment:outbound', function(payment) {
  // update an existing ripple transaction
});

client.listener.start();

*/
<|endoftext|>


<commit_before>/*
Copyright 2009, Adam Christian (adam.christian@gmail.com) and Slide, Inc.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/

var _f = windmill.controller.flash;
_f.asserts = {};
_f.waits = {};

//find the swf_locator if its there and return it
var findSWFLocator = function(paramObj){
  for (prop in paramObj){
    if (prop.indexOf("swf") != -1){
      return prop;
    }
  }
  throw ("Could not find a flash locator in the provided object");
};

//find an opt locator if its there and return it
var findOpt = function(paramObj){
  for (prop in paramObj){
    if (prop.indexOf("opt") != -1){
      return prop;
    }
  }
  throw ("Could not find a flash locator in the provided object");
};

//find any of the provided options for a select and return it
var findSWFOptions = function(paramObj){
  var arr = ["index", "label", "text", "data", "value"];

  for (var z=0; z < arr.length; z++){
      var val = paramObj[arr[z]];
      if (val != undefined){
        return arr[z];
      }
  }

  throw "We could not find a suitable option for the select";
};

var validate = function(res){
  if (res && res.message){
    throw res;
  }
  if (res == false){
    throw res;
  }
  return true;
};

_f.click = function (paramObj) {
  var movie = lookupNode(paramObj);
  var prop = findSWFLocator(paramObj);
  var loc = prop.replace("swf_","");

  var params = {};
  params[loc] = paramObj[prop];

  var res = movie['wm_click'](params);
  validate(res);
};

_f.check = function (paramObj) {
  _f.click(paramObj);
};

_f.radio = function (paramObj) {
  _f.click(paramObj);
};

_f.doubleClick = function (paramObj) {
  var movie = lookupNode(paramObj);
  var prop = findSWFLocator(paramObj);
  var loc = prop.replace("swf_","");

  var params = {};
  params[loc] = paramObj[prop];

  var res = movie['wm_click'](params);

  validate(res);
};

_f.type = function (paramObj) {
  var movie = lookupNode(paramObj);
  var prop = findSWFLocator(paramObj);
  var loc = prop.replace("swf_","");

  var params = {};
  params[loc] = paramObj[prop];
  params.text = paramObj.text;

  var res = movie['wm_type'](params);

  validate(res);
};

//breaks when you use a label instead of text
_f.select = function (paramObj) {
  var movie = lookupNode(paramObj);
  var prop = findSWFLocator(paramObj);
  var loc = prop.replace("swf_","");

  var params = {};
  params[loc] = paramObj[prop];

  var val = findSWFOptions(paramObj);
  params[val] = paramObj[val];
  var res = movie['wm_select'](params);
  validate(res);
};

_f.dragDropElemToElem = function (paramObj) {
  var movie = lookupNode(paramObj);
  var prop = findSWFLocator(paramObj);
  var opt = findOpt(paramObj);
  var loc = prop.replace("swf_","");

  var params = {};
  params[loc] = paramObj[prop];
  params[opt] = paramObj[opt];

  var res = movie['wm_dragDropElemToElem'](params);
  validate(res);
};

_f.dragDropToCoords = function (paramObj) {
  var movie = lookupNode(paramObj);
  var prop = findSWFLocator(paramObj);
  var loc = prop.replace("swf_","");

  var params = {};
  params[loc] = paramObj[prop];
  params['coords'] = paramObj['coords'];

  var res = movie['wm_dragDropToCoords'](params);
  validate(res);
};

_f.asserts.assertDisplayObject = function (paramObj){
  var movie = lookupNode(paramObj);
  var prop = findSWFLocator(paramObj);
  var loc = prop.replace("swf_","");

  var params = {};
  params[loc] = paramObj[prop];
  var res = movie['wm_assertDisplayObject'](params);
  validate(res);
};

//breaking
_f.asserts.assertProperty = function (paramObj){
  var movie = lookupNode(paramObj);
  var prop = findSWFLocator(paramObj);
  var loc = prop.replace("swf_","");
  var params = {};
  params[loc] = paramObj[prop];
  params.validator = paramObj.validator;

  var res = movie['wm_assertProperty'](params);
  validate(res);
};

//breaking
_f.asserts.assertText = function (paramObj){
  var movie = lookupNode(paramObj);
  var prop = findSWFLocator(paramObj);
  var loc = prop.replace("swf_","");
  var params = {};
  params[loc] = paramObj[prop];
  params.validator = paramObj.validator;

  var res = movie['wm_assertText'](params);
  validate(res);
};

//breaking
_f.asserts.assertTextIn = function (paramObj){
  var movie = lookupNode(paramObj);
  var prop = findSWFLocator(paramObj);
  var loc = prop.replace("swf_","");
  var params = {};
  params[loc] = paramObj[prop];
  params.validator = paramObj.validator;

  var res = movie['wm_assertTextIn'](params);
  validate(res);
};

_f.waits.forDisplayObject = function (paramObj, obj){
  var movie = lookupNode(paramObj);
  var prop = findSWFLocator(paramObj);
  var loc = prop.replace("swf_","");
  var params = {};
  params[loc] = paramObj[prop];

  windmill.controller.waits.forDisplayObject({'aid': paramObj.aid, 'movie':movie, 'params':params}, obj);
  return true;
};
_f.waits.forFlash = function (paramObj, obj){
  var movie = lookupNode(paramObj);

  windmill.controller.waits.forFlash({'aid': paramObj.aid, 'movie':movie}, obj);
  return true;
};
<commit_msg>Spacing<commit_after>/*
Copyright 2009, Adam Christian (adam.christian@gmail.com) and Slide, Inc.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/

var _f = windmill.controller.flash;
_f.asserts = {};
_f.waits = {};

//find the swf_locator if its there and return it
var findSWFLocator = function(paramObj){
  for (prop in paramObj){
    if (prop.indexOf("swf") != -1){
      return prop;
    }
  }
  throw ("Could not find a flash locator in the provided object");
};

//find an opt locator if its there and return it
var findOpt = function(paramObj){
  for (prop in paramObj){
    if (prop.indexOf("opt") != -1){
      return prop;
    }
  }
  throw ("Could not find a flash locator in the provided object");
};

//find any of the provided options for a select and return it
var findSWFOptions = function(paramObj){
  var arr = ["index", "label", "text", "data", "value"];

  for (var z=0; z < arr.length; z++){
      var val = paramObj[arr[z]];
      if (val != undefined){
        return arr[z];
      }
  }

  throw "We could not find a suitable option for the select";
};

var validate = function(res){
  if (res && res.message){
    throw res;
  }
  if (res == false){
    throw res;
  }
  return true;
};

_f.click = function (paramObj) {
  var movie = lookupNode(paramObj);
  var prop = findSWFLocator(paramObj);
  var loc = prop.replace("swf_","");

  var params = {};
  params[loc] = paramObj[prop];

  var res = movie['wm_click'](params);
  validate(res);
};

_f.check = function (paramObj) {
  _f.click(paramObj);
};

_f.radio = function (paramObj) {
  _f.click(paramObj);
};

_f.doubleClick = function (paramObj) {
  var movie = lookupNode(paramObj);
  var prop = findSWFLocator(paramObj);
  var loc = prop.replace("swf_","");

  var params = {};
  params[loc] = paramObj[prop];

  var res = movie['wm_click'](params);

  validate(res);
};

_f.type = function (paramObj) {
  var movie = lookupNode(paramObj);
  var prop = findSWFLocator(paramObj);
  var loc = prop.replace("swf_","");

  var params = {};
  params[loc] = paramObj[prop];
  params.text = paramObj.text;

  var res = movie['wm_type'](params);

  validate(res);
};

//breaks when you use a label instead of text
_f.select = function (paramObj) {
  var movie = lookupNode(paramObj);
  var prop = findSWFLocator(paramObj);
  var loc = prop.replace("swf_","");

  var params = {};
  params[loc] = paramObj[prop];

  var val = findSWFOptions(paramObj);
  params[val] = paramObj[val];
  var res = movie['wm_select'](params);
  validate(res);
};

_f.dragDropElemToElem = function (paramObj) {
  var movie = lookupNode(paramObj);
  var prop = findSWFLocator(paramObj);
  var opt = findOpt(paramObj);
  var loc = prop.replace("swf_","");

  var params = {};
  params[loc] = paramObj[prop];
  params[opt] = paramObj[opt];

  var res = movie['wm_dragDropElemToElem'](params);
  validate(res);
};

_f.dragDropToCoords = function (paramObj) {
  var movie = lookupNode(paramObj);
  var prop = findSWFLocator(paramObj);
  var loc = prop.replace("swf_","");

  var params = {};
  params[loc] = paramObj[prop];
  params['coords'] = paramObj['coords'];

  var res = movie['wm_dragDropToCoords'](params);
  validate(res);
};

_f.asserts.assertDisplayObject = function (paramObj){
  var movie = lookupNode(paramObj);
  var prop = findSWFLocator(paramObj);
  var loc = prop.replace("swf_","");

  var params = {};
  params[loc] = paramObj[prop];
  var res = movie['wm_assertDisplayObject'](params);
  validate(res);
};

//breaking
_f.asserts.assertProperty = function (paramObj){
  var movie = lookupNode(paramObj);
  var prop = findSWFLocator(paramObj);
  var loc = prop.replace("swf_","");
  var params = {};
  params[loc] = paramObj[prop];
  params.validator = paramObj.validator;

  var res = movie['wm_assertProperty'](params);
  validate(res);
};

//breaking
_f.asserts.assertText = function (paramObj){
  var movie = lookupNode(paramObj);
  var prop = findSWFLocator(paramObj);
  var loc = prop.replace("swf_","");
  var params = {};
  params[loc] = paramObj[prop];
  params.validator = paramObj.validator;

  var res = movie['wm_assertText'](params);
  validate(res);
};

//breaking
_f.asserts.assertTextIn = function (paramObj){
  var movie = lookupNode(paramObj);
  var prop = findSWFLocator(paramObj);
  var loc = prop.replace("swf_","");
  var params = {};
  params[loc] = paramObj[prop];
  params.validator = paramObj.validator;

  var res = movie['wm_assertTextIn'](params);
  validate(res);
};

_f.waits.forDisplayObject = function (paramObj, obj){
  var movie = lookupNode(paramObj);
  var prop = findSWFLocator(paramObj);
  var loc = prop.replace("swf_","");
  var params = {};
  params[loc] = paramObj[prop];

  windmill.controller.waits.forDisplayObject({'aid': paramObj.aid, 'movie':movie, 'params':params}, obj);
  return true;
};

_f.waits.forFlash = function (paramObj, obj){
  var movie = lookupNode(paramObj);

  windmill.controller.waits.forFlash({'aid': paramObj.aid, 'movie':movie}, obj);
  return true;
};
<|endoftext|>


<commit_before>  $(function() {
    if(urlParam('viewer_pane') === '1'){
      console.log('*********************** AJAX MODE ***********************');
      var $pageBody = $('body');
      window.loggedIn = false;
      // Intercept all link clicks
      window.asyncClickHandler = function(e) {
        e.preventDefault();
        // Grab the url from the anchor tag
        var url = $(this).attr('href');
        return window.replacePage(url);
      }

      function rerenderBody(html){
        var body = html.replace(/^[\S\s]*]*?>/i, "").replace(/<\/body[\S\s]*$/i, "");
        $pageBody.html(body);
        window.bindGlobalClickHandler();
        window.searchHandler(jQuery);
        window.packageVersionToggleHandler(jQuery);
        window.scrollTo(0,0);
        MathJax.Hub.Queue(["Typeset",MathJax.Hub])
        return false;
      }

      /************************************************************************************************************************************************
      rebinding and executing trough ajax requests
      ************************************************************************************************************************************************/

      window.bindGlobalClickHandler = function(){
        $('a:not(.js-external)').unbind('click').bind('click', window.asyncClickHandler);
        $('#js-examples').unbind('click').bind('click',window.runExamples);
        $('#js-install').unbind('click').bind('click',window.installpackage);
        $('#js-hideviewer').unbind('click').bind('click',window.hideViewer);
        $('#js-makedefault').unbind('click').bind('click',window.setDefault);
        $( "form" ).submit(function( event ) {
            event.preventDefault();
            var action = $("form")[0].action;
            var type = "GET";
            if (typeof $("form")[1] != 'undefined'){
              action = $("form")[1].action;
              type = "POST";
            }
            var dataToWrite= $(this).serialize();
            $.ajax({
              type: type,
              url: action,
              data: dataToWrite,
              contentType:"application/x-www-form-urlencoded",
              crossDomain:true,
              xhrFields: {
                withCredentials: true
              }
            }).then(function(html,textData,xhr){
              if(action.indexOf("/login")>-1 && !window.loggedIn){
                window.loggedIn=true;
                _rStudioRequest('/rpc/console_input','console_input',urlParam("RS_SHARED_SECRET"),urlParam("Rstudio_port"),
                  ["write('"+dataToWrite+"', file = paste0(.libPaths()[1],'/Rdocumentation/config/creds.txt')) \n Rdocumentation::login()"])
                .then(rerenderBody(html));
              }
              else{
                rerenderBody(html);
              }
            });
        });
      };

      // Helper function to grab new HTML
      // and replace the content
      window.replacePage = function(url) {
        console.log("replacing " + url);
        if(url.indexOf('#')>=0){
          url = url.substring(url.indexOf('#'),url.length);
          document.getElementById(url).scrollIntoView();
        }
        else{
          url = url.replace("../","");
          if(url.charAt(0)!="/"){
            url="/"+url;
          }
          var base = $('base').attr('href');
          if(url.indexOf('?')>-1){
            url = url + '&viewer_pane=1&Rstudio_XS_Secret=' + urlParam("Rstudio_XS_Secret")+"&Rstudio_port=" + urlParam("Rstudio_port");
          }
          else{
            url=url+'?viewer_pane=1&Rstudio_XS_Secret=' + urlParam("Rstudio_XS_Secret")+"&Rstudio_port=" + urlParam("Rstudio_port");
          }
          return $.ajax({
            type: 'GET',
            url : url,
            cache: false,
            dataType: 'html',
            xhrFields: {
              withCredentials: true
            },
            crossDomain:true
          })
          .then(rerenderBody);
        }

      };

            /************************************************************************************************************************************************
      button press functions (running examples, installing packages);
      ************************************************************************************************************************************************/
      window.runExamples=function(e){
        e.preventDefault();
        var package = $(".packageData").data("package-name");
        window.checkPackageVersion(package).then(function(installed){
          if(installed!=false){
            var examples= $('.topic').find('.topic--title').filter(function(i,el){
              return $(this).text()=="Examples";
            }).parent().find('.R').text();
            _rStudioRequest('/rpc/console_input','console_input',urlParam("RS_SHARED_SECRET"),urlParam("Rstudio_port"),["require("+package+")\n"+examples])
          }
        });
        return false;
      };

      window.setDefault=function(e){
        e.preventDefault();
        _rStudioRequest('/rpc/console_input','console_input',urlParam("RS_SHARED_SECRET"),urlParam("Rstudio_port"),["Rdocumentation::makeDefault()"]);
        return false;
      };
      window.hideViewer=function(e){
        e.preventDefault();
        _rStudioRequest('/rpc/console_input','console_input',urlParam("RS_SHARED_SECRET"),urlParam("Rstudio_port"),["Rdocumentation::hideViewer()"]);
        return false;
      };
      /************************************************************************************************************************************************
      checking installation of package and package version
      ************************************************************************************************************************************************/

      window.checkPackageVersion=function(package){
        var installed =true;
        var found=false;
        return _rStudioRequest('/rpc/console_input','console_input',urlParam("RS_SHARED_SECRET"),urlParam("Rstudio_port"),["check_package('"+package+"')"])
        .then(function(){
          return _rStudioRequest('/events/get_events','get_events',urlParam("RS_SHARED_SECRET"),urlParam("Rstudio_port"),[0])
          .then(function(result){
            for(var i=0;i<result.result.length;i++){
              if(typeof result.result[i] != "undefined" && result.result[i].type=="console_output"){
                if(result.result[i].data.indexOf("FALSE\n")>0){
                  installed = false;
                }
                else{
                  installed=result.result[i].data;
                }
                found=true;
              }
            }
            //Rstudio runs the get_events request periodically. It could happen that we accidently missed the response(small chance), so run it again then
            if(!found){
              installed = window.checkPackageVersion(package);
            }
            return installed;
          })
        });
      };

      window.packageVersionControl=function(){
        var versions = $('#packageVersionSelect').find('option');
        if(versions.length>0){
          var packageName = $(".packageData").data("package-name");
          window.checkPackageVersion(packageName).then(function(installed){
            if(installed==false){
              $('.versionCheck').html('<button type="button" id="js-install" class="btn btn-primary js-external">Install</button>');
            }
            else{
              installedVersion=installed.split(/[´`'"’‘]+/)[1];
              installedVersion=installedVersion.replace('-','.');
              var upToDate=true;
              for(var i=0;i<versions.length;i++){
                if($(versions[i]).text().trim()!="@VERSION@"&& _versionCompare($(versions[i]).text().trim(),installedVersion)){
                  $('.versionCheck').html('<button type="button" id="js-install" class="btn btn-primary js-external">Update</button>');
                  upToDate=false
                }
              }
              if(upToDate){

                $('.versionCheck').html('You have the latest version');
              }
            }
            $('#js-install').unbind('click',window.installpackage);
            $('#js-install').bind('click',window.installpackage);
          });
        }
      };

      window.installpackage=function(e){
        e.preventDefault();
        var packageName = $(".packageData").data("package-name");
        var packageSource= $(".packageData").data("type-id");
        _rStudioRequest('/rpc/console_input','console_input',urlParam("RS_SHARED_SECRET"),urlParam("Rstudio_port"),
                  ["install_package('"+packageName+"',"+packageSource+")"])
        return false;
      };

      window.setTab=function(e,ui){
        $('ul.tabs').find('a').each(function(){
          $(this.hash).hide();
        });
        var link = ui.tab[0].innerHTML
        link = link.substring(link.indexOf('#'),link.indexOf('" class'));
        $(link).show();
        e.preventDefault();
      }
      //check the packageversion
      window.packageVersionControl();
      window.bindGlobalClickHandler();
      window.scrollTo(0,0);
    }
  });

_rStudioRequest=function(url,method,shared_secret,port,params){
  var data={}
  data["method"]=method;
  //data["params"]=[$('.R').text()];
  data["params"]=params;
  data["clientId"]='33e600bb-c1b1-46bf-b562-ab5cba070b0e';
  data["clientVersion"]="";
  return $.ajax({
    url: 'http://127.0.0.1:'+port+url,
    headers:
    {
        'Accept':'application/json',
        'Content-Type':'application/json',
        'X-Shared-Secret':shared_secret
    },
    type: 'POST',
    dataType: 'json',
    data: JSON.stringify(data),
    processData: false,
    crossDomain:true,
    xhrFields: {
      withCredentials: true
    }
  });
}
_versionCompare = function (v1, v2) {
    v1parts = v1.split(/[.-]+/);
    v2parts = v2.split(/[.-]+/);
    while (v1parts.length < v2parts.length) v1parts.push("0");
    while (v2parts.length < v1parts.length) v2parts.push("0");
    v1parts = v1parts.map(Number);
    v2parts = v2parts.map(Number);
    for (var i = 0; i < v1parts.length; ++i) {
        if (v2parts.length == i) {
            return true;
        }

        if (v1parts[i] == v2parts[i]) {
            continue;
        }
        else if (v1parts[i] > v2parts[i]) {
            return true;
        }
        else {
            return false;
        }
    }

    if (v1parts.length != v2parts.length) {
        return false;
    }

    return 0;
}
<commit_msg>solved dependencies loading problem<commit_after>  $(function() {
    if(urlParam('viewer_pane') === '1'){
      console.log('*********************** AJAX MODE ***********************');
      var $pageBody = $('body');
      window.loggedIn = false;
      // Intercept all link clicks
      window.asyncClickHandler = function(e) {
        e.preventDefault();
        // Grab the url from the anchor tag
        var url = $(this).attr('href');
        return window.replacePage(url);
      }

      function rerenderBody(html){
        console.log(html);
        var body = html.replace(/^[\S\s]*]*?>/i, "").replace(/<\/body[\S\s]*$/i, "");
        $pageBody.html(body);
        window.bindGlobalClickHandler();
        window.searchHandler(jQuery);
        window.packageVersionToggleHandler(jQuery);
        window.scrollTo(0,0);
        MathJax.Hub.Queue(["Typeset",MathJax.Hub])
        return false;
      }

      /************************************************************************************************************************************************
      rebinding and executing trough ajax requests
      ************************************************************************************************************************************************/

      window.bindGlobalClickHandler = function(){
        $('a:not(.js-external)').unbind('click').bind('click', window.asyncClickHandler);
        $('#js-examples').unbind('click').bind('click',window.runExamples);
        $('#js-install').unbind('click').bind('click',window.installpackage);
        $('#js-hideviewer').unbind('click').bind('click',window.hideViewer);
        $('#js-makedefault').unbind('click').bind('click',window.setDefault);
        $( "form" ).submit(function( event ) {
            event.preventDefault();
            var action = $("form")[0].action;
            var type = "GET";
            if (typeof $("form")[1] != 'undefined'){
              action = $("form")[1].action;
              type = "POST";
            }
            var dataToWrite= $(this).serialize();
            $.ajax({
              type: type,
              url: action,
              data: dataToWrite,
              contentType:"application/x-www-form-urlencoded",
              crossDomain:true,
              xhrFields: {
                withCredentials: true
              }
            }).then(function(html,textData,xhr){
              if(action.indexOf("/login")>-1 && !window.loggedIn){
                window.loggedIn=true;
                _rStudioRequest('/rpc/console_input','console_input',urlParam("RS_SHARED_SECRET"),urlParam("Rstudio_port"),
                  ["write('"+dataToWrite+"', file = paste0(.libPaths()[1],'/Rdocumentation/config/creds.txt')) \n Rdocumentation::login()"])
                .then(rerenderBody(html));
              }
              else{
                rerenderBody(html);
              }
            });
        });
      };

      // Helper function to grab new HTML
      // and replace the content
      window.replacePage = function(url) {
        console.log("replacing " + url);
        if(url.indexOf('#')>=0){
          url = url.substring(url.indexOf('#'),url.length);
          document.getElementById(url).scrollIntoView();
        }
        else{
          url = url.replace("../","");
          if(url.charAt(0)!="/"){
            url="/"+url;
          }
          var base = $('base').attr('href');
          if(url.indexOf('?')>-1){
            url = url + '&viewer_pane=1&Rstudio_XS_Secret=' + urlParam("Rstudio_XS_Secret")+"&Rstudio_port=" + urlParam("Rstudio_port");
          }
          else{
            url=url+'?viewer_pane=1&Rstudio_XS_Secret=' + urlParam("Rstudio_XS_Secret")+"&Rstudio_port=" + urlParam("Rstudio_port");
          }
          return $.ajax({
            url : url,
            type: 'GET',
            dataType:'html',
            cache: false,
            xhrFields: {
              withCredentials: true
            },
            crossDomain:true
          })
          .then(rerenderBody)
          .fail(function(error) {console.log(error.responseJSON) });
        }

      };

            /************************************************************************************************************************************************
      button press functions (running examples, installing packages);
      ************************************************************************************************************************************************/
      window.runExamples=function(e){
        e.preventDefault();
        var package = $(".packageData").data("package-name");
        window.checkPackageVersion(package).then(function(installed){
          if(installed!=false){
            var examples= $('.topic').find('.topic--title').filter(function(i,el){
              return $(this).text()=="Examples";
            }).parent().find('.R').text();
            _rStudioRequest('/rpc/console_input','console_input',urlParam("RS_SHARED_SECRET"),urlParam("Rstudio_port"),["require("+package+")\n"+examples])
          }
        });
        return false;
      };

      window.setDefault=function(e){
        e.preventDefault();
        _rStudioRequest('/rpc/console_input','console_input',urlParam("RS_SHARED_SECRET"),urlParam("Rstudio_port"),["Rdocumentation::makeDefault()"]);
        return false;
      };
      window.hideViewer=function(e){
        e.preventDefault();
        _rStudioRequest('/rpc/console_input','console_input',urlParam("RS_SHARED_SECRET"),urlParam("Rstudio_port"),["Rdocumentation::hideViewer()"]);
        return false;
      };
      /************************************************************************************************************************************************
      checking installation of package and package version
      ************************************************************************************************************************************************/

      window.checkPackageVersion=function(package){
        var installed =true;
        var found=false;
        return _rStudioRequest('/rpc/console_input','console_input',urlParam("RS_SHARED_SECRET"),urlParam("Rstudio_port"),["check_package('"+package+"')"])
        .then(function(){
          return _rStudioRequest('/events/get_events','get_events',urlParam("RS_SHARED_SECRET"),urlParam("Rstudio_port"),[0])
          .then(function(result){
            for(var i=0;i<result.result.length;i++){
              if(typeof result.result[i] != "undefined" && result.result[i].type=="console_output"){
                if(result.result[i].data.indexOf("FALSE\n")>0){
                  installed = false;
                }
                else{
                  installed=result.result[i].data;
                }
                found=true;
              }
            }
            //Rstudio runs the get_events request periodically. It could happen that we accidently missed the response(small chance), so run it again then
            if(!found){
              installed = window.checkPackageVersion(package);
            }
            return installed;
          })
        });
      };

      window.packageVersionControl=function(){
        var versions = $('#packageVersionSelect').find('option');
        if(versions.length>0){
          var packageName = $(".packageData").data("package-name");
          window.checkPackageVersion(packageName).then(function(installed){
            if(installed==false){
              $('.versionCheck').html('<button type="button" id="js-install" class="btn btn-primary js-external">Install</button>');
            }
            else{
              installedVersion=installed.split(/[´`'"’‘]+/)[1];
              installedVersion=installedVersion.replace('-','.');
              var upToDate=true;
              for(var i=0;i<versions.length;i++){
                if($(versions[i]).text().trim()!="@VERSION@"&& _versionCompare($(versions[i]).text().trim(),installedVersion)){
                  $('.versionCheck').html('<button type="button" id="js-install" class="btn btn-primary js-external">Update</button>');
                  upToDate=false
                }
              }
              if(upToDate){

                $('.versionCheck').html('You have the latest version');
              }
            }
            $('#js-install').unbind('click',window.installpackage);
            $('#js-install').bind('click',window.installpackage);
          });
        }
      };

      window.installpackage=function(e){
        e.preventDefault();
        var packageName = $(".packageData").data("package-name");
        var packageSource= $(".packageData").data("type-id");
        _rStudioRequest('/rpc/console_input','console_input',urlParam("RS_SHARED_SECRET"),urlParam("Rstudio_port"),
                  ["install_package('"+packageName+"',"+packageSource+")"])
        return false;
      };

      window.setTab=function(e,ui){
        $('ul.tabs').find('a').each(function(){
          $(this.hash).hide();
        });
        var link = ui.tab[0].innerHTML
        link = link.substring(link.indexOf('#'),link.indexOf('" class'));
        $(link).show();
        e.preventDefault();
      }
      //check the packageversion
      window.packageVersionControl();
      window.bindGlobalClickHandler();
      window.scrollTo(0,0);
    }
  });

_rStudioRequest=function(url,method,shared_secret,port,params){
  var data={}
  data["method"]=method;
  //data["params"]=[$('.R').text()];
  data["params"]=params;
  data["clientId"]='33e600bb-c1b1-46bf-b562-ab5cba070b0e';
  data["clientVersion"]="";
  return $.ajax({
    url: 'http://127.0.0.1:'+port+url,
    headers:
    {
        'Accept':'application/json',
        'Content-Type':'application/json',
        'X-Shared-Secret':shared_secret
    },
    type: 'POST',
    dataType: 'json',
    data: JSON.stringify(data),
    processData: false,
    crossDomain:true,
    xhrFields: {
      withCredentials: true
    }
  });
}
_versionCompare = function (v1, v2) {
    v1parts = v1.split(/[.-]+/);
    v2parts = v2.split(/[.-]+/);
    while (v1parts.length < v2parts.length) v1parts.push("0");
    while (v2parts.length < v1parts.length) v2parts.push("0");
    v1parts = v1parts.map(Number);
    v2parts = v2parts.map(Number);
    for (var i = 0; i < v1parts.length; ++i) {
        if (v2parts.length == i) {
            return true;
        }

        if (v1parts[i] == v2parts[i]) {
            continue;
        }
        else if (v1parts[i] > v2parts[i]) {
            return true;
        }
        else {
            return false;
        }
    }

    if (v1parts.length != v2parts.length) {
        return false;
    }

    return 0;
}
<|endoftext|>


<commit_before>import { mainLizmap } from '../modules/Globals.js';
import { html, render } from 'lit-html';

import { transform, get as getProjection } from 'ol/proj';

export default class MousePosition extends HTMLElement {
    constructor() {
        super();

        this.numDigits = 0;
        this.displayUnit = 'm';
    }

    mainTemplate(lon, lat){
        return html`

                    <input type="number" step="any" class="input-small" placeholder="longitude" .value=${lon}>
                    <input type="number" step="any" class="input-small" placeholder="latitude" .value=${lat}>

                    <select title="${lizDict['mouseposition.select']}" @change=${(event) => { this._displayUnit = event.target.value }}>
                        <option value="m">${lizDict['mouseposition.units.m']}</option>
                        <option value="f">${lizDict['mouseposition.units.f']}</option>
                        <option value="d">${lizDict['mouseposition.units.d']}</option>
                        <option value="dm">${lizDict['mouseposition.units.dm']}</option>
                        <option value="dms">${lizDict['mouseposition.units.dms']}</option>
                    </select>

`;
    }

    set _displayUnit(unit){
        unit === 'm' ? this.numDigits = 0 : this.numDigits = 5;
        this.displayUnit = unit;
    }

    redraw(evt){
        if (evt == null) {
            this.reset();
            return;
        }else{
            const { lon, lat } = mainLizmap.lizmap3.map.getLonLatFromPixel(evt.xy);
            let lonLatToDisplay = [lon, lat];

            // Ex formatOutput() code
            const qgisProjectProjection = getProjection(mainLizmap.qgisProjectProjection);
            if (qgisProjectProjection && qgisProjectProjection.getUnits() === 'm' && this.displayUnit === 'm') {
                lonLatToDisplay = transform(lonLatToDisplay, mainLizmap.projection, mainLizmap.qgisProjectProjection);
            }

            render(this.mainTemplate(lonLatToDisplay[0].toFixed(this.numDigits), lonLatToDisplay[1].toFixed(this.numDigits)), this);
        }
    }

    reset(){

    }

    connectedCallback() {
        // Listen to mousemove event
        mainLizmap.lizmap3.map.events.register('mousemove', this, this.redraw);
    }

    disconnectedCallback() {
        mainLizmap.lizmap3.map.events.unregister('mousemove', this, this.redraw);
    }
}
<commit_msg>Refactor and handle degree unit<commit_after>import { mainLizmap } from '../modules/Globals.js';
import { html, render } from 'lit-html';

import { transform, get as getProjection } from 'ol/proj';

export default class MousePosition extends HTMLElement {
    constructor() {
        super();

        this.numDigits = 0;
        this.displayUnit = 'm';

        this._lastLon;
        this._lastLat;
    }

    // Render positionTemplate apart because values change a lot
    positionTemplate(lon, lat){
        return html`
            <input type="number" step="any" class="input-small" placeholder="longitude" .value=${lon}>
            <input type="number" step="any" class="input-small" placeholder="latitude" .value=${lat}>`;
    }

    mainTemplate(lon, lat){
        return html`

                ${this.positionTemplate(lon, lat)}

                <select title="${lizDict['mouseposition.select']}" @change=${(event) => { this._displayUnit = event.target.value }}>
                    <option value="m">${lizDict['mouseposition.units.m']}</option>
                    <option value="f">${lizDict['mouseposition.units.f']}</option>
                    <option value="d">${lizDict['mouseposition.units.d']}</option>
                    <option value="dm">${lizDict['mouseposition.units.dm']}</option>
                    <option value="dms">${lizDict['mouseposition.units.dms']}</option>
                </select>

`;
    }

    set _displayUnit(unit){
        unit === 'm' ? this.numDigits = 0 : this.numDigits = 5;
        this.displayUnit = unit;

        this.redraw(this._lastLon, this._lastLat);
    }

    // Callback to map's mousemove event
    _mousemove(evt){
        if (evt == null) {
            this.reset();
            return;
        }else{
            const { lon, lat } = mainLizmap.lizmap3.map.getLonLatFromPixel(evt.xy);

            this._lastLon = lon;
            this._lastLat = lat;

            this.redraw(lon, lat);
        }
    }

    redraw(lon, lat){
        let lonLatToDisplay = [lon, lat];

        // Ex formatOutput() code
        const qgisProjectProjection = getProjection(mainLizmap.qgisProjectProjection);

        // Display coordinates in QGIS project projection if in meter and meter chosen
        if (qgisProjectProjection && qgisProjectProjection.getUnits() === 'm' && this.displayUnit === 'm') {
            lonLatToDisplay = transform(lonLatToDisplay, mainLizmap.projection, mainLizmap.qgisProjectProjection);
        }

        if (this.displayUnit.indexOf('d') === 0 && mainLizmap.lizmap3.map.projection.getUnits() !== 'degrees') {
            lonLatToDisplay = transform(lonLatToDisplay, mainLizmap.projection, 'EPSG:4326');
        }

        render(this.positionTemplate(lonLatToDisplay[0].toFixed(this.numDigits),lonLatToDisplay[1].toFixed(this.numDigits)),
            this.querySelector('.mouse-position'));
    }

    reset(){

    }

    connectedCallback() {
        // First render
        render(this.mainTemplate(null, null), this);
        // Listen to mousemove event
        mainLizmap.lizmap3.map.events.register('mousemove', this, this._mousemove);
    }

    disconnectedCallback() {
        mainLizmap.lizmap3.map.events.unregister('mousemove', this, this._mousemove);
    }
}
<|endoftext|>


<commit_before>'use strict';

import { h, Component } from 'preact';
import { bind } from 'decko';
import Pikadayer from './Pikadayer.js';

const defaultPeriod = 'last-7-days';
const padZero = function(n){return n<10? '0'+n:''+n;}

function getNow() {
  let now = new Date()
  let tzOffset = now.getTimezoneOffset()  * 60 * 1000;

  // if we're ahead of UTC, stick to UTC's "now"
  // this is ugly but a sad necessity for now because we store and aggregate statistics using UTC dates (without time data)
  // For those ahead of UTC, "today" will always be empty if they're checking early on in their day
  // see https://github.com/usefathom/fathom/issues/134
  if (tzOffset < 0) {
    now.setTime(now.getTime() + tzOffset )
  }

  return now
}

// today, yesterday, this week, last 7 days, last 30 days
const availablePeriods = {
  'today': {
    label: 'Today',
    start: function() {
      const now = getNow();
      return new Date(now.getFullYear(), now.getMonth(), now.getDate());
    },
    end: function() {
      const now = getNow();
      return new Date(now.getFullYear(), now.getMonth(), now.getDate());
    },
 },
  'last-7-days': {
    label: 'Last 7 days',
    start: function() {
      const now = getNow();
      return new Date(now.getFullYear(), now.getMonth(), now.getDate()-6);
    },
    end: function() {
      const now = getNow();
      return new Date(now.getFullYear(), now.getMonth(), now.getDate());
    },
 },
  'last-30-days': {
    label: 'Last 30 days',
    start: function() {
      const now = getNow();
      return new Date(now.getFullYear(), now.getMonth(), now.getDate()-29);
    },
    end: function() {
      const now = getNow();
      return new Date(now.getFullYear(), now.getMonth(), now.getDate());
    },
 },
  'this-year': {
    label: 'This year',
    start: function() {
      const now = getNow();
      return new Date(now.getFullYear(), 0, 1);
    },
    end: function() {
      const now = getNow();
      return new Date(this.start().getFullYear() + 1, 0, 0);
    },
 },
}

class DatePicker extends Component {
  constructor(props) {
    super(props)

    this.state = {
      period: window.location.hash.substring(2) || window.localStorage.getItem('period') || defaultPeriod,
      before: 0, // UTC timestamp
      after: 0, // UTC timestamp
      startDate: null, // local date object
      endDate: null, // local date object
    }

    this.updateDatesFromPeriod(this.state.period)
    window.addEventListener('keydown', this.handleKeyPress);
  }

  @bind
  updateDatesFromPeriod(period) {
    if(typeof(availablePeriods[period]) !== "object") {
      return;
    }
    let p = availablePeriods[period];
    this.setDateRange(p.start(), p.end(), period);
  }

  @bind
  setDateRange(startDate, endDate, period) {
    // don't update state if start > end. user may be busy picking dates.
    // todo: show error
    if(startDate > endDate) {
      return;
    }

    // include start & end day by forcing time
    startDate.setHours(0, 0, 0);
    endDate.setHours(23, 59, 59);

    // create unix timestamps from local date objects
    let before, after;
    const timezoneOffset = (new Date()).getTimezoneOffset() * 60;
    before = Math.round((+endDate) / 1000) - timezoneOffset;
    after = Math.round((+startDate) / 1000) - timezoneOffset;

    this.setState({
      period: period || '',
      startDate: startDate,
      endDate: endDate,
      before: before,
      after: after,
    });

    // use slight delay for updating rest of application to allow this function to be called again
    if(!this.timeout) {
      this.timeout = window.setTimeout(() => {
        this.props.onChange(this.state);
        this.timeout = null;

        window.localStorage.setItem('period', this.state.period)
        window.history.replaceState(this.state, null, `#!${this.state.period}`)
      }, 2)
    }
  }

  @bind
  setPeriod(e) {
    e.preventDefault();

    let newPeriod = e.target.getAttribute('data-value');
    if( newPeriod === this.state.period) {
      return;
    }

    this.updateDatesFromPeriod(newPeriod);
  }

  dateValue(date) {
    return date.getFullYear() + '-' + padZero(date.getMonth() + 1) + '-' + padZero(date.getDate());
  }

  @bind
  setStartDate(date) {
    this.setDateRange(date, this.state.endDate, '')
  }

  @bind
  setEndDate(date) {
    this.setDateRange(this.state.startDate, date, '')
  }

  @bind
  handleKeyPress(evt) {
    if( ! evt.altKey ) {
      return;
    }

    // TODO: Account for leap years
    let diff = this.state.endDate - this.state.startDate + 1000;
    let newStartDate, newEndDate;

    switch(evt.keyCode) {
      // ALT + left-arrow
      case 37:
        newStartDate = new Date(+this.state.startDate - diff)
        newEndDate = new Date(+this.state.endDate - diff)
        this.setDateRange(newStartDate, newEndDate)
      break;

      // ALT + right-arrow
      case 39:
      newStartDate = new Date(+this.state.startDate + diff)
      newEndDate = new Date(+this.state.endDate + diff)
      this.setDateRange(newStartDate, newEndDate)
      break;
    }
  }

  render(props, state) {
    const links = Object.keys(availablePeriods).map((id) => {
      let p = availablePeriods[id];
      return (

          {p.label}

      );
    });

    return (

        {links}

          <Pikadayer value={this.dateValue(state.startDate)} onSelect={this.setStartDate} />
           to
          <Pikadayer value={this.dateValue(state.endDate)} onSelect={this.setEndDate}  />

    )
  }
}

export default DatePicker
<commit_msg>add actual lib 😅<commit_after>'use strict';

import { h, Component } from 'preact';
import { bind } from 'decko';
import Pikadayer from './Pikadayer.js';
import classNames from 'classnames';

const defaultPeriod = 'last-7-days';
const padZero = function(n){return n<10? '0'+n:''+n;}

function getNow() {
  let now = new Date()
  let tzOffset = now.getTimezoneOffset()  * 60 * 1000;

  // if we're ahead of UTC, stick to UTC's "now"
  // this is ugly but a sad necessity for now because we store and aggregate statistics using UTC dates (without time data)
  // For those ahead of UTC, "today" will always be empty if they're checking early on in their day
  // see https://github.com/usefathom/fathom/issues/134
  if (tzOffset < 0) {
    now.setTime(now.getTime() + tzOffset )
  }

  return now
}

// today, yesterday, this week, last 7 days, last 30 days
const availablePeriods = {
  'today': {
    label: 'Today',
    start: function() {
      const now = getNow();
      return new Date(now.getFullYear(), now.getMonth(), now.getDate());
    },
    end: function() {
      const now = getNow();
      return new Date(now.getFullYear(), now.getMonth(), now.getDate());
    },
 },
  'last-7-days': {
    label: 'Last 7 days',
    start: function() {
      const now = getNow();
      return new Date(now.getFullYear(), now.getMonth(), now.getDate()-6);
    },
    end: function() {
      const now = getNow();
      return new Date(now.getFullYear(), now.getMonth(), now.getDate());
    },
 },
  'last-30-days': {
    label: 'Last 30 days',
    start: function() {
      const now = getNow();
      return new Date(now.getFullYear(), now.getMonth(), now.getDate()-29);
    },
    end: function() {
      const now = getNow();
      return new Date(now.getFullYear(), now.getMonth(), now.getDate());
    },
 },
  'this-year': {
    label: 'This year',
    start: function() {
      const now = getNow();
      return new Date(now.getFullYear(), 0, 1);
    },
    end: function() {
      const now = getNow();
      return new Date(this.start().getFullYear() + 1, 0, 0);
    },
 },
}

class DatePicker extends Component {
  constructor(props) {
    super(props)

    this.state = {
      period: window.location.hash.substring(2) || window.localStorage.getItem('period') || defaultPeriod,
      before: 0, // UTC timestamp
      after: 0, // UTC timestamp
      startDate: null, // local date object
      endDate: null, // local date object
    }

    this.updateDatesFromPeriod(this.state.period)
    window.addEventListener('keydown', this.handleKeyPress);
  }

  @bind
  updateDatesFromPeriod(period) {
    if(typeof(availablePeriods[period]) !== "object") {
      return;
    }
    let p = availablePeriods[period];
    this.setDateRange(p.start(), p.end(), period);
  }

  @bind
  setDateRange(startDate, endDate, period) {
    // don't update state if start > end. user may be busy picking dates.
    // todo: show error
    if(startDate > endDate) {
      return;
    }

    // include start & end day by forcing time
    startDate.setHours(0, 0, 0);
    endDate.setHours(23, 59, 59);

    // create unix timestamps from local date objects
    let before, after;
    const timezoneOffset = (new Date()).getTimezoneOffset() * 60;
    before = Math.round((+endDate) / 1000) - timezoneOffset;
    after = Math.round((+startDate) / 1000) - timezoneOffset;

    this.setState({
      period: period || '',
      startDate: startDate,
      endDate: endDate,
      before: before,
      after: after,
    });

    // use slight delay for updating rest of application to allow this function to be called again
    if(!this.timeout) {
      this.timeout = window.setTimeout(() => {
        this.props.onChange(this.state);
        this.timeout = null;

        window.localStorage.setItem('period', this.state.period)
        window.history.replaceState(this.state, null, `#!${this.state.period}`)
      }, 2)
    }
  }

  @bind
  setPeriod(e) {
    e.preventDefault();

    let newPeriod = e.target.getAttribute('data-value');
    if( newPeriod === this.state.period) {
      return;
    }

    this.updateDatesFromPeriod(newPeriod);
  }

  dateValue(date) {
    return date.getFullYear() + '-' + padZero(date.getMonth() + 1) + '-' + padZero(date.getDate());
  }

  @bind
  setStartDate(date) {
    this.setDateRange(date, this.state.endDate, '')
  }

  @bind
  setEndDate(date) {
    this.setDateRange(this.state.startDate, date, '')
  }

  @bind
  handleKeyPress(evt) {
    if( ! evt.altKey ) {
      return;
    }

    // TODO: Account for leap years
    let diff = this.state.endDate - this.state.startDate + 1000;
    let newStartDate, newEndDate;

    switch(evt.keyCode) {
      // ALT + left-arrow
      case 37:
        newStartDate = new Date(+this.state.startDate - diff)
        newEndDate = new Date(+this.state.endDate - diff)
        this.setDateRange(newStartDate, newEndDate)
      break;

      // ALT + right-arrow
      case 39:
      newStartDate = new Date(+this.state.startDate + diff)
      newEndDate = new Date(+this.state.endDate + diff)
      this.setDateRange(newStartDate, newEndDate)
      break;
    }
  }

  render(props, state) {
    const links = Object.keys(availablePeriods).map((id) => {
      let p = availablePeriods[id];
      return (

          {p.label}

      );
    });

    return (

        {links}

          <Pikadayer value={this.dateValue(state.startDate)} onSelect={this.setStartDate} />
           to
          <Pikadayer value={this.dateValue(state.endDate)} onSelect={this.setEndDate}  />

    )
  }
}

export default DatePicker
<|endoftext|>


<commit_before>
var GOOD = "#0d0";
var BAD = "#ff0000";
var NEUTRAL = "#bbb";

function initMap(config, callback) {

    var map = $K.map('#map-holder');

        var resize = function() {
            var c = $('#map-holder');
            var ratio =  map.viewAB.height / map.viewAB.width;
            c.width( c.height() / ratio );
            if (c.width() > $(window).width()) {
                c.width( $(window).width());
                c.height(ratio * c.width());
            }
            map.resize();
        };

        $(window).resize(resize);

    $.fn.qtip.defaults.style.classes = 'qtip-dark';

    var scale = chroma.scale([BAD, "#ff4500", "#ffa500", "#ffff00", GOOD]);

    var statesLayer = {};

    map.loadCSS('static/css/map.css', function() {
        map.loadMap('static/img/'+ config.name + '.svg', function() {
        	var isPracticeView = config.click != undefined;

            var bgLayer = {
                name: 'bg'
            }

            statesLayer.styles = {
                'fill' : function(d) {
                	var state = config.states && config.states[d.name];
                    return state ? (scale(state.skill).brighten((1-state.certainty)*80).hex()) :'#fff';
                    },
                'stroke-width' : 1
	        }
            if (config.click) {
                clickFn = function(data, path, event) {
                    config.click(data.name);
                }
                statesLayer.click = clickFn
                statesLayer.styles['stroke-width'] = 1.5;
            }
            if (config.showTooltips) {
                statesLayer.tooltips = function(d) {
                	var state = config.states && config.states[d.name];
                    var name = (state ? '' + ' ' + state.name + '' : '
Neprozkoumané území

');
                    var description = state ? '
  Znalost: ' + Math.round(100 * state.skill) + '%
' : "";
                    description += (state ? '
   Jistota: ' + Math.round(100 * state.certainty) + '%
 ' : "");

                    return [name + description, config.states[d.name] ? config.states[d.name].name : ""];
                }
            }
            map.addLayer('states', bgLayer)
            resize();
            map.addLayer('states', statesLayer )

            if (!isPracticeView) {
	            map.addFilter('inner-state-glow', 'glow', {
	                size: 1,
	                strength: 1,
	                color: '#000',
	                opacity: 0.2,
	                inner: true
	            });
	            map.getLayer('states').applyFilter('inner-state-glow');
            }
            map.addFilter('outerglow', 'glow', {
                size: 4,
                color: '#333',
                strength: 2,
                inner: false
            });
            map.getLayer('bg').applyFilter('outerglow');

            resize();
            callback && callback();

        	$('#map-holder').find(".loading-indicator").hide();
        })
    })
    var myMap = {
        map: map,
        highlightState : function(state, color) {
            var color = color || NEUTRAL;
            var layer = map.getLayer('states');
            statePath = layer.getPaths({ name: state })[0];
            if (statePath) {
                statePath.svgPath.attr('fill', color);
            }
        },
        blink : function(state, count) {
            var count = count || 0;
            var that = this
            if (count < 6) {
                color = count % 2 == 0 ? "white" : NEUTRAL;
                that.highlightState(state, color);
                setTimeout(function(){
                    that.blink(state, ++count)
                }, 50)
            }
        },
        clearHighlights : function () {
            var layer = map.getLayer('states');
            layer.style('fill', "#fff");
        },
        updateStates : function(states) {
        	config.states = states;
        	map.getLayer('states').style('fill', statesLayer.styles.fill, 1);
        	map.getLayer('states').tooltips(statesLayer.tooltips);
		}
    }
    return myMap;
}

<commit_msg>map.js refactoring and no bg map layer on mobile<commit_after>
var GOOD = "#0d0";
var BAD = "#ff0000";
var NEUTRAL = "#bbb";
var HOLDER = '#map-holder';

function initMap(config, callback) {

    var map = $K.map(HOLDER);

    var resize = function() {
        var c = $(HOLDER);
        var ratio =  map.viewAB.height / map.viewAB.width;
        c.width( c.height() / ratio );
        if (c.width() > $(window).width()) {
            c.width( $(window).width());
            c.height(ratio * c.width());
        }
        map.resize();
    };

    $(window).resize(resize);

    $.fn.qtip.defaults.style.classes = 'qtip-dark';

    var scale = chroma.scale([BAD, "#ff4500", "#ffa500", "#ffff00", GOOD]);

    var statesLayer = {};

    map.loadCSS('static/css/map.css', function() {
        map.loadMap('static/img/'+ config.name + '.svg', function() {
        	var isPracticeView = config.click != undefined;

            var bgLayer = {
                name: 'bg'
            }

            statesLayer.styles = {
                'fill' : function(d) {
                	var state = config.states && config.states[d.name];
                    return state ? (scale(state.skill).brighten((1-state.certainty)*80).hex()) :'#fff';
                    },
                'stroke-width' : 1
	        }
            if (config.click) {
                clickFn = function(data, path, event) {
                    config.click(data.name);
                }
                statesLayer.click = clickFn
                statesLayer.styles['stroke-width'] = 1.5;
            }
            if (config.showTooltips) {
                statesLayer.tooltips = function(d) {
                	var state = config.states && config.states[d.name];
                    var name = (state ? '' + ' ' + state.name + '' : '
Neprozkoumané území

');
                    var description = state ? '
  Znalost: ' + Math.round(100 * state.skill) + '%
' : "";
                    description += (state ? '
   Jistota: ' + Math.round(100 * state.certainty) + '%
 ' : "");

                    return [name + description, config.states[d.name] ? config.states[d.name].name : ""];
                }
            }

            if (767 < $(window).width()) {
                map.addLayer('states', bgLayer)
                map.addFilter('outerglow', 'glow', {
                    size: 4,
                    color: '#333',
                    strength: 2,
                    inner: false
                });
                map.getLayer('bg').applyFilter('outerglow');
            }

            resize();
            map.addLayer('states', statesLayer )

            if (!isPracticeView) {
	            map.addFilter('inner-state-glow', 'glow', {
	                size: 1,
	                strength: 1,
	                color: '#000',
	                opacity: 0.2,
	                inner: true
	            });
	            map.getLayer('states').applyFilter('inner-state-glow');
            }
            resize();
            callback && callback();

        	$('#map-holder').find(".loading-indicator").hide();
        })
    })
    var myMap = {
        map: map,
        highlightState : function(state, color) {
            var color = color || NEUTRAL;
            var layer = map.getLayer('states');
            statePath = layer.getPaths({ name: state })[0];
            if (statePath) {
                statePath.svgPath.attr('fill', color);
            }
        },
        blink : function(state, count) {
            var count = count || 0;
            var that = this
            if (count < 6) {
                color = count % 2 == 0 ? "white" : NEUTRAL;
                that.highlightState(state, color);
                setTimeout(function(){
                    that.blink(state, ++count)
                }, 50)
            }
        },
        clearHighlights : function () {
            var layer = map.getLayer('states');
            layer.style('fill', "#fff");
        },
        updateStates : function(states) {
        	config.states = states;
        	map.getLayer('states').style('fill', statesLayer.styles.fill, 1);
        	map.getLayer('states').tooltips(statesLayer.tooltips);
		}
    }
    return myMap;
}
<|endoftext|>


<commit_before>  var config = require("./config.js").get;

  // calculate the urlstub
  var urlstub = config.cloudant.server.replace("//","//"+config.cloudant.username+":"+config.cloudant.password+"@") + ":"+config.cloudant.port;

  // start up the nano driver
  var nano = require('nano')(urlstub);

  // connections to databases
  var feeds = nano.db.use('feeds');
  var articles = nano.db.use('articles');

  // create some databases
  nano.db.create('feeds',function(err,body) {

  });
  nano.db.create('articles',function(err,body) {

    // if this worked, then we need to create views too
    if(!err) {

      var views =  [
    		 {
           "_id": "_design/matching",
           "language": "javascript",
           "views": {
    					 "byts":  {
    					   "map": "function(doc) { if(doc.starred) {emit(['starred',doc.pubDateTS],null);} if(doc.read) {emit(['read',doc.pubDateTS],null);} if(!doc.read) {emit(['unread',doc.pubDateTS],null);} }",
    					   "reduce": "_count"
    					 }
           }
        }
    	];

      console.log("Creating views - first time only");
      for(var i in views) {
        articles.insert(views[i],function(err,data) {
          //console.log(err,data);
        });
      }
    }
  });

  module.exports = {
    feeds: feeds,
    articles: articles
  }<commit_msg>better start-up logic<commit_after>  var config = require("./config.js").get;

  // calculate the urlstub
  var urlstub = config.cloudant.server.replace("//","//"+config.cloudant.username+":"+config.cloudant.password+"@") + ":"+config.cloudant.port;

  // start up the nano driver
  var nano = require('nano')(urlstub);

  // connections to databases
  var feeds = nano.db.use('feeds');
  var articles = nano.db.use('articles');

  // async library
  var async = require('async');

  // create the feeds database
  var createFeeds = function(callback) {
    console.log("Checking feeds database");
    // create some databases
    nano.db.create('feeds',function(err,body) {
      callback()
    });
  }

  // create the articles database
  var createArticles = function(callback) {
    console.log("Checking articles database");
    // create some databases
    nano.db.create('articles',function(err,body) {
      callback()
    });
  }

  // create any required views
  var createViews = function(callback) {

    var views =  [
  		 {
         "_id": "_design/matching",
         "language": "javascript",
         "views": {
  					 "byts":  {
  					   "map": "function(doc) {if(doc.starred) {emit(['starred',doc.pubDateTS],null);} if(doc.read) {emit(['read',doc.pubDateTS],null);} if(!doc.read) {emit(['unread',doc.pubDateTS],null);} }",
  					   "reduce": "_count"
  					 }
         }
      }
  	];

    console.log("Checking views");
    for(var i in views) {
      var v = views[i];
      articles.get(v._id,function(err,data) {
        if(!err) {
          var rev = data._rev;
          delete data._rev;
          if(JSON.stringify(data) != JSON.stringify(v)) {
            console.log("view different!");
            v._rev=rev
            articles.insert(v,function(err,data) {
              console.log(err,data);
            });
          }
        }
      })
    }
    callback();
  }

  // create some databases
  async.series( [ createFeeds, createArticles, createViews] );

  module.exports = {
    feeds: feeds,
    articles: articles,
    createViews: createViews
  }<|endoftext|>


<commit_before>/*
Copyright 2018 New Vector Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/**
implements DOM/CSS operations for resizing.
The sizer determines what CSS mechanism is used for sizing items, like flexbox, ...
*/
class Sizer {
    constructor(container, vertical, reverse) {
        this.container = container;
        this.reverse = reverse;
        this.vertical = vertical;
    }

    getItemPercentage(item) {
        /*
        const flexGrow = window.getComputedStyle(item).flexGrow;
        if (flexGrow === "") {
            return null;
        }
        return parseInt(flexGrow) / 1000;
        */
        const style = window.getComputedStyle(item);
        const sizeStr = this.vertical ? style.height : style.width;
        const size = parseInt(sizeStr, 10);
        return size / this.getTotalSize();
    }

    setItemPercentage(item, percent) {
        item.style.flexGrow = Math.round(percent * 1000);
    }

    /**
        @param {Element} item the dom element being resized
        @return {number} how far the edge of the item is from the edge of the container
    */
    getItemOffset(item) {
        const offset = (this.vertical ? item.offsetTop : item.offsetLeft) - this._getOffset();
        if (this.reverse) {
            return this.getTotalSize() - (offset + this.getItemSize(item));
        } else {
            return offset;
        }
    }

    /**
        @param {Element} item the dom element being resized
        @return {number} the width/height of an item in the container
    */
    getItemSize(item) {
        return this.vertical ? item.offsetHeight : item.offsetWidth;
    }

    /** @return {number} the width/height of the container */
    getTotalSize() {
        return this.vertical ? this.container.offsetHeight : this.container.offsetWidth;
    }

    /** @return {number} container offset to offsetParent */
    _getOffset() {
        return this.vertical ? this.container.offsetTop : this.container.offsetLeft;
    }

    setItemSize(item, size) {
        if (this.vertical) {
            item.style.height = `${Math.round(size)}px`;
        } else {
            item.style.width = `${Math.round(size)}px`;
        }
    }

    /**
        @param {MouseEvent} event the mouse event
        @return {number} the distance between the cursor and the edge of the container,
            along the applicable axis (vertical or horizontal)
    */
    offsetFromEvent(event) {
        const pos = this.vertical ? event.pageY : event.pageX;
        if (this.reverse) {
            return (this._getOffset() + this.getTotalSize()) - pos;
        } else {
            return pos - this._getOffset();
        }
    }
}

class FlexSizer extends Sizer {
    setItemSize(item, size) {
        item.style.flexBasis = `${Math.round(size)}px`;
    }
}

module.exports = {Sizer, FlexSizer};
<commit_msg>make manual resizing follow cursor more accurately<commit_after>/*
Copyright 2018 New Vector Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/**
implements DOM/CSS operations for resizing.
The sizer determines what CSS mechanism is used for sizing items, like flexbox, ...
*/
class Sizer {
    constructor(container, vertical, reverse) {
        this.container = container;
        this.reverse = reverse;
        this.vertical = vertical;
    }

    getItemPercentage(item) {
        /*
        const flexGrow = window.getComputedStyle(item).flexGrow;
        if (flexGrow === "") {
            return null;
        }
        return parseInt(flexGrow) / 1000;
        */
        const style = window.getComputedStyle(item);
        const sizeStr = this.vertical ? style.height : style.width;
        const size = parseInt(sizeStr, 10);
        return size / this.getTotalSize();
    }

    setItemPercentage(item, percent) {
        item.style.flexGrow = Math.round(percent * 1000);
    }

    /**
        @param {Element} item the dom element being resized
        @return {number} how far the edge of the item is from the edge of the container
    */
    getItemOffset(item) {
        const offset = (this.vertical ? item.offsetTop : item.offsetLeft) - this._getOffset();
        if (this.reverse) {
            return this.getTotalSize() - (offset + this.getItemSize(item));
        } else {
            return offset;
        }
    }

    /**
        @param {Element} item the dom element being resized
        @return {number} the width/height of an item in the container
    */
    getItemSize(item) {
        return this.vertical ? item.offsetHeight : item.offsetWidth;
    }

    /** @return {number} the width/height of the container */
    getTotalSize() {
        return this.vertical ? this.container.offsetHeight : this.container.offsetWidth;
    }

    /** @return {number} container offset to offsetParent */
    _getOffset() {
        return this.vertical ? this.container.offsetTop : this.container.offsetLeft;
    }

    setItemSize(item, size) {
        if (this.vertical) {
            item.style.height = `${Math.round(size)}px`;
        } else {
            item.style.width = `${Math.round(size)}px`;
        }
    }

    /**
        @param {MouseEvent} event the mouse event
        @return {number} the distance between the cursor and the edge of the container,
            along the applicable axis (vertical or horizontal)
    */
    offsetFromEvent(event) {
        const pos = this.vertical ? event.pageY : event.pageX;
        if (this.reverse) {
            return (this._getOffset() + this.getTotalSize()) - pos;
        } else {
            return pos - this._getOffset();
        }
    }
}

class FlexSizer extends Sizer {
    setItemSize(item, size) {
        item.style.flexGrow = `0`;
        item.style.flexBasis = `${Math.round(size)}px`;
    }
}

module.exports = {Sizer, FlexSizer};
<|endoftext|>