<commit_before>'use strict';

var unsupported, isaosp;

if (window && window.navigator) {
  var rxaosp = window.navigator.userAgent.match(/Android.*AppleWebKit\/([\d.]+)/);
  isaosp = (rxaosp && rxaosp[1] < 537);
  if (!window.cordova && isaosp)
    unsupported = true;
  if (unsupported) {
    window.location = '#/unsupported';
  }
}

//Setting up route
angular
  .module('copayApp')
  .config(function(historicLogProvider, $provide, $logProvider, $stateProvider, $urlRouterProvider, $compileProvider) {
    $urlRouterProvider.otherwise('/');

    $logProvider.debugEnabled(true);
    $provide.decorator('$log', ['$delegate', 'isDevel',
      function($delegate, isDevel) {
        var historicLog = historicLogProvider.$get();

        ['debug', 'info', 'warn', 'error', 'log'].forEach(function(level) {
          if (isDevel && level == 'error') return;

          var orig = $delegate[level];
          $delegate[level] = function() {
            if (level == 'error')
              console.log(arguments);

            var args = [].slice.call(arguments);
            if (!Array.isArray(args)) args = [args];
            args = args.map(function(v) {
              try {
                if (typeof v == 'undefined') v = 'undefined';
                if (!v) v = 'null';
                if (typeof v == 'object') {
                  if (v.message)
                    v = v.message;
                  else
                    v = JSON.stringify(v);
                }
                // Trim output in mobile
                if (window.cordova) {
                  v = v.toString();
                  if (v.length > 1000) {
                    v = v.substr(0, 997) + '...';
                  }
                }
              } catch (e) {
                console.log('Error at log decorator:', e);
                v = 'undefined';
              }
              return v;
            });
            try {
              if (window.cordova)
                console.log(args.join(' '));
              historicLog.add(level, args.join(' '));
              orig.apply(null, args);
            } catch (e) {
              console.log('ERROR (at log decorator):', e, args[0]);
            }
          };
        });
        return $delegate;
      }
    ]);

    // whitelist 'chrome-extension:' for chromeApp to work with image URLs processed by Angular
    // link: http://stackoverflow.com/questions/15606751/angular-changes-urls-to-unsafe-in-extension-page?lq=1
    $compileProvider.imgSrcSanitizationWhitelist(/^\s*((https?|ftp|file|blob|chrome-extension):|data:image\/)/);

    $stateProvider
      .state('translators', {
        url: '/translators',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/translators.html'
          }
        }
      })
      .state('disclaimer', {
        url: '/disclaimer',
        needProfile: false,
        views: {
          'main': {
            templateUrl: 'views/disclaimer.html',
          }
        }
      })
      .state('walletHome', {
        url: '/',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/walletHome.html',
          },
        }
      })
      .state('unsupported', {
        url: '/unsupported',
        needProfile: false,
        views: {
          'main': {
            templateUrl: 'views/unsupported.html'
          }
        }
      })
      .state('payment', {
        url: '/uri-payment/:data',
        templateUrl: 'views/paymentUri.html',
        views: {
          'main': {
            templateUrl: 'views/paymentUri.html',
          },
        },
        needProfile: true
      })
      .state('selectWalletForPayment', {
        url: '/selectWalletForPayment',
        controller: 'walletForPaymentController',
        needProfile: true
      })
      .state('join', {
        url: '/join',
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/join.html'
          },
        }
      })
      .state('import', {
        url: '/import',
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/import.html'
          },
        }
      })
      .state('importProfile', {
        url: '/importProfile',
        templateUrl: 'views/importProfile.html',
        needProfile: false
      })
      .state('importLegacy', {
        url: '/importLegacy',
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/importLegacy.html',
          },
        }

      })
      .state('create', {
        url: '/create',
        templateUrl: 'views/create.html',
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/create.html'
          },
        }
      })
      .state('copayers', {
        url: '/copayers',
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/copayers.html'
          },
        }
      })
      .state('preferences', {
        url: '/preferences',
        templateUrl: 'views/preferences.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferences.html',
          },
        }
      })
      .state('preferencesLanguage', {
        url: '/preferencesLanguage',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesLanguage.html'
          },
        }
      })
      .state('preferencesUnit', {
        url: '/preferencesUnit',
        templateUrl: 'views/preferencesUnit.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesUnit.html'
          },
        }
      })
      .state('preferencesFee', {
        url: '/preferencesFee',
        templateUrl: 'views/preferencesFee.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesFee.html'
          },
        }
      })
      .state('uriglidera', {
        url: '/uri-glidera?code',
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/glideraUri.html'
          },
        }
      })
      .state('glidera', {
        url: '/glidera',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/glidera.html'
          },
        }
      })
      .state('buyGlidera', {
        url: '/buy',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/buyGlidera.html'
          },
        }
      })
      .state('sellGlidera', {
        url: '/sell',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/sellGlidera.html'
          },
        }
      })
      .state('preferencesGlidera', {
        url: '/preferencesGlidera',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesGlidera.html'
          },
        }
      })
      .state('preferencesAdvanced', {
        url: '/preferencesAdvanced',
        templateUrl: 'views/preferencesAdvanced.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesAdvanced.html'
          },
        }
      })
      .state('preferencesColor', {
        url: '/preferencesColor',
        templateUrl: 'views/preferencesColor.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesColor.html'
          },
        }
      })
      .state('preferencesAltCurrency', {
        url: '/preferencesAltCurrency',
        templateUrl: 'views/preferencesAltCurrency.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesAltCurrency.html'
          },
        }
      })
      .state('preferencesAlias', {
        url: '/preferencesAlias',
        templateUrl: 'views/preferencesAlias.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesAlias.html'
          },

        }
      })
      .state('preferencesEmail', {
        url: '/preferencesEmail',
        templateUrl: 'views/preferencesEmail.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesEmail.html'
          },

        }
      })
      .state('preferencesBwsUrl', {
        url: '/preferencesBwsUrl',
        templateUrl: 'views/preferencesBwsUrl.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesBwsUrl.html'
          },

        }
      })
      .state('preferencesHistory', {
        url: '/preferencesHistory',
        templateUrl: 'views/preferencesHistory.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesHistory.html'
          },

        }
      })
      .state('deleteWords', {
        url: '/deleteWords',
        templateUrl: 'views/preferencesDeleteWords.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesDeleteWords.html'
          },
        }
      })
      .state('delete', {
        url: '/delete',
        templateUrl: 'views/preferencesDeleteWallet.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesDeleteWallet.html'
          },
        }
      })
      .state('information', {
        url: '/information',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesInformation.html'
          },
        }
      })
      .state('about', {
        url: '/about',
        templateUrl: 'views/preferencesAbout.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesAbout.html'
          },
        }
      })
      .state('logs', {
        url: '/logs',
        templateUrl: 'views/preferencesLogs.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesLogs.html'
          },
        }
      })
      .state('export', {
        url: '/export',
        templateUrl: 'views/export.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/export.html'
          },
        }
      })
      .state('paperWallet', {
        url: '/paperWallet',
        templateUrl: 'views/paperWallet.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/paperWallet.html'
          },
        }
      })
      .state('backup', {
        url: '/backup',
        templateUrl: 'views/backup.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/backup.html'
          },
        }
      })
      .state('preferencesGlobal', {
        url: '/preferencesGlobal',
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesGlobal.html',
          },
        }
      })
      .state('termOfUse', {
        url: '/termOfUse',
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/termOfUse.html',
          },
        }
      })
      .state('warning', {
        url: '/warning',
        controller: 'warningController',
        templateUrl: 'views/warning.html',
        needProfile: false
      })
      .state('add', {
        url: '/add',
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/add.html'
          },
        }
      })
      .state('cordova', {
        url: '/cordova/:status/:fromHome/:fromDisclaimer/:secondBackButtonPress',
        views: {
          'main': {
            controller: function($rootScope, $state, $stateParams, $timeout, go, isCordova) {

              switch ($stateParams.status) {
                case 'resume':
                  $rootScope.$emit('Local/Resume');
                  break;
                case 'backbutton':

                  if ($stateParams.fromDisclaimer == 'true')
                    navigator.app.exitApp();

                  if (isCordova && $stateParams.fromHome == 'true' && !$rootScope.modalOpened) {
                    if ($stateParams.secondBackButtonPress == 'true') {
                      navigator.app.exitApp();
                    } else {
                      window.plugins.toast.showShortBottom('Press again to exit');
                    }
                  } else {
                    $rootScope.$emit('closeModal');
                  }
                  break;
              };
              $timeout(function() {
                $rootScope.$emit('Local/SetTab', 'walletHome', true);
              }, 100);
              go.walletHome();
            }
          }
        },
        needProfile: false
      });
  })
  .run(function($rootScope, $state, $log, uriHandler, isCordova, profileService, $timeout, nodeWebkit, uxLanguage, animationService) {
    FastClick.attach(document.body);

    uxLanguage.init();

    // Register URI handler, not for mobileApp
    if (!isCordova) {
      uriHandler.register();
    }

    if (nodeWebkit.isDefined()) {
      var gui = require('nw.gui');
      var win = gui.Window.get();
      var nativeMenuBar = new gui.Menu({
        type: "menubar"
      });
      try {
        nativeMenuBar.createMacBuiltin("Copay");
      } catch (e) {
        $log.debug('This is not OSX');
      }
      win.menu = nativeMenuBar;
    }

    $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {

      if (!profileService.profile && toState.needProfile) {

        // Give us time to open / create the profile
        event.preventDefault();
        // Try to open local profile
        profileService.loadAndBindProfile(function(err) {
          if (err) {
            if (err.message && err.message.match('NOPROFILE')) {
              $log.debug('No profile... redirecting');
              $state.transitionTo('disclaimer');
            } else if (err.message && err.message.match('NONAGREEDDISCLAIMER')) {
              $log.debug('Display disclaimer... redirecting');
              $state.transitionTo('disclaimer');
            } else {
              throw new Error(err); // TODO
            }
          } else {
            $log.debug('Profile loaded ... Starting UX.');
            $state.transitionTo(toState.name || toState, toParams);
          }
        });
      }

      if (profileService.focusedClient && !profileService.focusedClient.isComplete() && toState.walletShouldBeComplete) {

        $state.transitionTo('copayers');
        event.preventDefault();
      }

      if (!animationService.transitionAnimated(fromState, toState)) {
        event.preventDefault();
        // Time for the backpane to render
        setTimeout(function() {
          $state.transitionTo(toState);
        }, 50);
      }
    });
  });
<commit_msg>Adds translation<commit_after>'use strict';

var unsupported, isaosp;

if (window && window.navigator) {
  var rxaosp = window.navigator.userAgent.match(/Android.*AppleWebKit\/([\d.]+)/);
  isaosp = (rxaosp && rxaosp[1] < 537);
  if (!window.cordova && isaosp)
    unsupported = true;
  if (unsupported) {
    window.location = '#/unsupported';
  }
}

//Setting up route
angular
  .module('copayApp')
  .config(function(historicLogProvider, $provide, $logProvider, $stateProvider, $urlRouterProvider, $compileProvider) {
    $urlRouterProvider.otherwise('/');

    $logProvider.debugEnabled(true);
    $provide.decorator('$log', ['$delegate', 'isDevel',
      function($delegate, isDevel) {
        var historicLog = historicLogProvider.$get();

        ['debug', 'info', 'warn', 'error', 'log'].forEach(function(level) {
          if (isDevel && level == 'error') return;

          var orig = $delegate[level];
          $delegate[level] = function() {
            if (level == 'error')
              console.log(arguments);

            var args = [].slice.call(arguments);
            if (!Array.isArray(args)) args = [args];
            args = args.map(function(v) {
              try {
                if (typeof v == 'undefined') v = 'undefined';
                if (!v) v = 'null';
                if (typeof v == 'object') {
                  if (v.message)
                    v = v.message;
                  else
                    v = JSON.stringify(v);
                }
                // Trim output in mobile
                if (window.cordova) {
                  v = v.toString();
                  if (v.length > 1000) {
                    v = v.substr(0, 997) + '...';
                  }
                }
              } catch (e) {
                console.log('Error at log decorator:', e);
                v = 'undefined';
              }
              return v;
            });
            try {
              if (window.cordova)
                console.log(args.join(' '));
              historicLog.add(level, args.join(' '));
              orig.apply(null, args);
            } catch (e) {
              console.log('ERROR (at log decorator):', e, args[0]);
            }
          };
        });
        return $delegate;
      }
    ]);

    // whitelist 'chrome-extension:' for chromeApp to work with image URLs processed by Angular
    // link: http://stackoverflow.com/questions/15606751/angular-changes-urls-to-unsafe-in-extension-page?lq=1
    $compileProvider.imgSrcSanitizationWhitelist(/^\s*((https?|ftp|file|blob|chrome-extension):|data:image\/)/);

    $stateProvider
      .state('translators', {
        url: '/translators',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/translators.html'
          }
        }
      })
      .state('disclaimer', {
        url: '/disclaimer',
        needProfile: false,
        views: {
          'main': {
            templateUrl: 'views/disclaimer.html',
          }
        }
      })
      .state('walletHome', {
        url: '/',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/walletHome.html',
          },
        }
      })
      .state('unsupported', {
        url: '/unsupported',
        needProfile: false,
        views: {
          'main': {
            templateUrl: 'views/unsupported.html'
          }
        }
      })
      .state('payment', {
        url: '/uri-payment/:data',
        templateUrl: 'views/paymentUri.html',
        views: {
          'main': {
            templateUrl: 'views/paymentUri.html',
          },
        },
        needProfile: true
      })
      .state('selectWalletForPayment', {
        url: '/selectWalletForPayment',
        controller: 'walletForPaymentController',
        needProfile: true
      })
      .state('join', {
        url: '/join',
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/join.html'
          },
        }
      })
      .state('import', {
        url: '/import',
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/import.html'
          },
        }
      })
      .state('importProfile', {
        url: '/importProfile',
        templateUrl: 'views/importProfile.html',
        needProfile: false
      })
      .state('importLegacy', {
        url: '/importLegacy',
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/importLegacy.html',
          },
        }

      })
      .state('create', {
        url: '/create',
        templateUrl: 'views/create.html',
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/create.html'
          },
        }
      })
      .state('copayers', {
        url: '/copayers',
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/copayers.html'
          },
        }
      })
      .state('preferences', {
        url: '/preferences',
        templateUrl: 'views/preferences.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferences.html',
          },
        }
      })
      .state('preferencesLanguage', {
        url: '/preferencesLanguage',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesLanguage.html'
          },
        }
      })
      .state('preferencesUnit', {
        url: '/preferencesUnit',
        templateUrl: 'views/preferencesUnit.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesUnit.html'
          },
        }
      })
      .state('preferencesFee', {
        url: '/preferencesFee',
        templateUrl: 'views/preferencesFee.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesFee.html'
          },
        }
      })
      .state('uriglidera', {
        url: '/uri-glidera?code',
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/glideraUri.html'
          },
        }
      })
      .state('glidera', {
        url: '/glidera',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/glidera.html'
          },
        }
      })
      .state('buyGlidera', {
        url: '/buy',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/buyGlidera.html'
          },
        }
      })
      .state('sellGlidera', {
        url: '/sell',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/sellGlidera.html'
          },
        }
      })
      .state('preferencesGlidera', {
        url: '/preferencesGlidera',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesGlidera.html'
          },
        }
      })
      .state('preferencesAdvanced', {
        url: '/preferencesAdvanced',
        templateUrl: 'views/preferencesAdvanced.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesAdvanced.html'
          },
        }
      })
      .state('preferencesColor', {
        url: '/preferencesColor',
        templateUrl: 'views/preferencesColor.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesColor.html'
          },
        }
      })
      .state('preferencesAltCurrency', {
        url: '/preferencesAltCurrency',
        templateUrl: 'views/preferencesAltCurrency.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesAltCurrency.html'
          },
        }
      })
      .state('preferencesAlias', {
        url: '/preferencesAlias',
        templateUrl: 'views/preferencesAlias.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesAlias.html'
          },

        }
      })
      .state('preferencesEmail', {
        url: '/preferencesEmail',
        templateUrl: 'views/preferencesEmail.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesEmail.html'
          },

        }
      })
      .state('preferencesBwsUrl', {
        url: '/preferencesBwsUrl',
        templateUrl: 'views/preferencesBwsUrl.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesBwsUrl.html'
          },

        }
      })
      .state('preferencesHistory', {
        url: '/preferencesHistory',
        templateUrl: 'views/preferencesHistory.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesHistory.html'
          },

        }
      })
      .state('deleteWords', {
        url: '/deleteWords',
        templateUrl: 'views/preferencesDeleteWords.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesDeleteWords.html'
          },
        }
      })
      .state('delete', {
        url: '/delete',
        templateUrl: 'views/preferencesDeleteWallet.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesDeleteWallet.html'
          },
        }
      })
      .state('information', {
        url: '/information',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesInformation.html'
          },
        }
      })
      .state('about', {
        url: '/about',
        templateUrl: 'views/preferencesAbout.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesAbout.html'
          },
        }
      })
      .state('logs', {
        url: '/logs',
        templateUrl: 'views/preferencesLogs.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesLogs.html'
          },
        }
      })
      .state('export', {
        url: '/export',
        templateUrl: 'views/export.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/export.html'
          },
        }
      })
      .state('paperWallet', {
        url: '/paperWallet',
        templateUrl: 'views/paperWallet.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/paperWallet.html'
          },
        }
      })
      .state('backup', {
        url: '/backup',
        templateUrl: 'views/backup.html',
        walletShouldBeComplete: true,
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/backup.html'
          },
        }
      })
      .state('preferencesGlobal', {
        url: '/preferencesGlobal',
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/preferencesGlobal.html',
          },
        }
      })
      .state('termOfUse', {
        url: '/termOfUse',
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/termOfUse.html',
          },
        }
      })
      .state('warning', {
        url: '/warning',
        controller: 'warningController',
        templateUrl: 'views/warning.html',
        needProfile: false
      })
      .state('add', {
        url: '/add',
        needProfile: true,
        views: {
          'main': {
            templateUrl: 'views/add.html'
          },
        }
      })
      .state('cordova', {
        url: '/cordova/:status/:fromHome/:fromDisclaimer/:secondBackButtonPress',
        views: {
          'main': {
            controller: function($rootScope, $state, $stateParams, $timeout, go, isCordova, gettextCatalog) {

              switch ($stateParams.status) {
                case 'resume':
                  $rootScope.$emit('Local/Resume');
                  break;
                case 'backbutton':

                  if ($stateParams.fromDisclaimer == 'true')
                    navigator.app.exitApp();

                  if (isCordova && $stateParams.fromHome == 'true' && !$rootScope.modalOpened) {
                    if ($stateParams.secondBackButtonPress == 'true') {
                      navigator.app.exitApp();
                    } else {
                      window.plugins.toast.showShortBottom(gettextCatalog.getString('Press again to exit'));
                    }
                  } else {
                    $rootScope.$emit('closeModal');
                  }
                  break;
              };
              $timeout(function() {
                $rootScope.$emit('Local/SetTab', 'walletHome', true);
              }, 100);
              go.walletHome();
            }
          }
        },
        needProfile: false
      });
  })
  .run(function($rootScope, $state, $log, uriHandler, isCordova, profileService, $timeout, nodeWebkit, uxLanguage, animationService) {
    FastClick.attach(document.body);

    uxLanguage.init();

    // Register URI handler, not for mobileApp
    if (!isCordova) {
      uriHandler.register();
    }

    if (nodeWebkit.isDefined()) {
      var gui = require('nw.gui');
      var win = gui.Window.get();
      var nativeMenuBar = new gui.Menu({
        type: "menubar"
      });
      try {
        nativeMenuBar.createMacBuiltin("Copay");
      } catch (e) {
        $log.debug('This is not OSX');
      }
      win.menu = nativeMenuBar;
    }

    $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {

      if (!profileService.profile && toState.needProfile) {

        // Give us time to open / create the profile
        event.preventDefault();
        // Try to open local profile
        profileService.loadAndBindProfile(function(err) {
          if (err) {
            if (err.message && err.message.match('NOPROFILE')) {
              $log.debug('No profile... redirecting');
              $state.transitionTo('disclaimer');
            } else if (err.message && err.message.match('NONAGREEDDISCLAIMER')) {
              $log.debug('Display disclaimer... redirecting');
              $state.transitionTo('disclaimer');
            } else {
              throw new Error(err); // TODO
            }
          } else {
            $log.debug('Profile loaded ... Starting UX.');
            $state.transitionTo(toState.name || toState, toParams);
          }
        });
      }

      if (profileService.focusedClient && !profileService.focusedClient.isComplete() && toState.walletShouldBeComplete) {

        $state.transitionTo('copayers');
        event.preventDefault();
      }

      if (!animationService.transitionAnimated(fromState, toState)) {
        event.preventDefault();
        // Time for the backpane to render
        setTimeout(function() {
          $state.transitionTo(toState);
        }, 50);
      }
    });
  });
<|endoftext|>


<commit_before>class Application extends Model {

    constructor(data) {
        super(data);
        this.databases   = [];
        this.dataSources = [];
        this.pageLinks   = [];
    }

    init() {
        // databases
        for (const name in this.data.databases) {
            this.createDatabase(this.data.databases[name]);
        }

        // dataSources
        for (const name in this.data.dataSources) {
            this.createDataSource(this.data.dataSources[name]);
        }

        // pageLinks
        for (const name in this.data.pageLinks) {
            this.createPageLink(this.data.pageLinks[name]);
        }
    }

    createDatabase(data) {
        const database = new Database(data, this);
        database.init();
        this.databases.push(database);
        return database;
    }
    createDataSource(data) {
        const dataSource = new DataSource(data, this);
        dataSource.init();
        this.dataSources.push(dataSource);
        return dataSource;
    }
    createPageLink(data) {
        const pageLink = new PageLink(data, this);
        pageLink.init();
        this.pageLinks.push(pageLink);
        return pageLink;
    }
    removeDatabase(database) {
        console.log('Application.removeDatabase', database.getName());
        const i = this.databases.indexOf(database);
        if (i === -1) throw new Error('no such database');
        this.databases.splice(i, 1);
    }
    removePageLink(pageLink) {
        console.log('Application.removePageLink', pageLink.getName());
        const i = this.pageLinks.indexOf(pageLink);
        if (i === -1) throw new Error('no such pageLink');
        this.pageLinks.splice(i, 1);
    }
    async setValue(name, value) {
        //console.log(name + ' = ' + value);
        const data = await QForms.doHttpRequest({
            controller: 'Application',
            action    : 'save',
            params    : Helper.encodeObject({
                attr : name,
                value: value
            })
        });
        this.data['@attributes'][name] = value;
        return data;
    }

    async newPageAndPageLinkData(params) {
        params['menu'] = (params['startup'] === 'true') ? 'Pages' : '';
        return await QForms.doHttpRequest({
            controller: 'Page',
            action    : '_new',
            params    : Helper.encodeObject(params)
        });
    }

    async newPage(params) {
        const {page: pageData, pageLink: pageLinkData} = await this.newPageAndPageLinkData(params);
        const pageLink = this.createPageLink(pageLinkData);
        return new Page(pageData, pageLink);
    }

    async newDatabase(params) {
        const data = await QForms.doHttpRequest({
            controller: 'Database',
            action    : '_new',
            params    : Helper.encodeObject(params)
        });
        return this.createDatabase(data);
    }

    async getView(view) {
        return await QForms.doHttpRequest({
            controller: 'Application',
            action    : 'getView',
            params    : Helper.encodeObject({
                app : this.data['@attributes'].name,
                view: view
            })
        });
    }

    async saveView(text, view) {
        return await QForms.doHttpRequest({
            controller: 'Application',
            action    : 'saveView',
            params    : Helper.encodeObject({
                app : this.data['@attributes'].name,
                view: view,
                text: text
            })
        });
    }

    async saveController(text) {
        return await QForms.doHttpRequest({
            controller: 'Application',
            action    : 'saveController',
            params    : Helper.encodeObject({
                app : this.data['@attributes'].name,
                text: text
            })
        });
    }

    async createView() {
        return await QForms.doHttpRequest({
            controller: 'Application',
            action    : 'createView',
            params    : Helper.encodeObject({
                app: this.data['@attributes'].name
            })
        });
    }

    async createController() {
        return await QForms.doHttpRequest({
            controller: 'Application',
            action    : 'createController',
            params    : Helper.encodeObject({
                app: this.data['@attributes'].name
            })
        });
    }

    async newDataSource(params) {
        return await QForms.doHttpRequest({
            controller: 'DataSource',
            action    : '_new',
            params    : Helper.encodeObject(params)
        });
    }

}
<commit_msg>removeDataSource<commit_after>class Application extends Model {

    constructor(data) {
        super(data);
        this.databases   = [];
        this.dataSources = [];
        this.pageLinks   = [];
    }

    init() {
        // databases
        for (const name in this.data.databases) {
            this.createDatabase(this.data.databases[name]);
        }

        // dataSources
        for (const name in this.data.dataSources) {
            this.createDataSource(this.data.dataSources[name]);
        }

        // pageLinks
        for (const name in this.data.pageLinks) {
            this.createPageLink(this.data.pageLinks[name]);
        }
    }

    createDatabase(data) {
        const database = new Database(data, this);
        database.init();
        this.databases.push(database);
        return database;
    }
    createDataSource(data) {
        const dataSource = new DataSource(data, this);
        dataSource.init();
        this.dataSources.push(dataSource);
        return dataSource;
    }
    createPageLink(data) {
        const pageLink = new PageLink(data, this);
        pageLink.init();
        this.pageLinks.push(pageLink);
        return pageLink;
    }
    removeDatabase(database) {
        console.log('Application.removeDatabase', database.getName());
        const i = this.databases.indexOf(database);
        if (i === -1) throw new Error('no such database');
        this.databases.splice(i, 1);
    }
    removeDataSource(dataSource) {
        console.log('Application.removeDataSource', dataSource.getName());
        const i = this.dataSources.indexOf(dataSource);
        if (i === -1) throw new Error('no such dataSource');
        this.dataSources.splice(i, 1);
    }
    removePageLink(pageLink) {
        console.log('Application.removePageLink', pageLink.getName());
        const i = this.pageLinks.indexOf(pageLink);
        if (i === -1) throw new Error('no such pageLink');
        this.pageLinks.splice(i, 1);
    }
    async setValue(name, value) {
        //console.log(name + ' = ' + value);
        const data = await QForms.doHttpRequest({
            controller: 'Application',
            action    : 'save',
            params    : Helper.encodeObject({
                attr : name,
                value: value
            })
        });
        this.data['@attributes'][name] = value;
        return data;
    }

    async newPageAndPageLinkData(params) {
        params['menu'] = (params['startup'] === 'true') ? 'Pages' : '';
        return await QForms.doHttpRequest({
            controller: 'Page',
            action    : '_new',
            params    : Helper.encodeObject(params)
        });
    }

    async newPage(params) {
        const {page: pageData, pageLink: pageLinkData} = await this.newPageAndPageLinkData(params);
        const pageLink = this.createPageLink(pageLinkData);
        return new Page(pageData, pageLink);
    }

    async newDatabase(params) {
        const data = await QForms.doHttpRequest({
            controller: 'Database',
            action    : '_new',
            params    : Helper.encodeObject(params)
        });
        return this.createDatabase(data);
    }

    async getView(view) {
        return await QForms.doHttpRequest({
            controller: 'Application',
            action    : 'getView',
            params    : Helper.encodeObject({
                app : this.data['@attributes'].name,
                view: view
            })
        });
    }

    async saveView(text, view) {
        return await QForms.doHttpRequest({
            controller: 'Application',
            action    : 'saveView',
            params    : Helper.encodeObject({
                app : this.data['@attributes'].name,
                view: view,
                text: text
            })
        });
    }

    async saveController(text) {
        return await QForms.doHttpRequest({
            controller: 'Application',
            action    : 'saveController',
            params    : Helper.encodeObject({
                app : this.data['@attributes'].name,
                text: text
            })
        });
    }

    async createView() {
        return await QForms.doHttpRequest({
            controller: 'Application',
            action    : 'createView',
            params    : Helper.encodeObject({
                app: this.data['@attributes'].name
            })
        });
    }

    async createController() {
        return await QForms.doHttpRequest({
            controller: 'Application',
            action    : 'createController',
            params    : Helper.encodeObject({
                app: this.data['@attributes'].name
            })
        });
    }

    async newDataSource(params) {
        return await QForms.doHttpRequest({
            controller: 'DataSource',
            action    : '_new',
            params    : Helper.encodeObject(params)
        });
    }

}
<|endoftext|>


<commit_before>// Source: http://youmightnotneedjquery.com/#ready
function ready(fn) {
  'use strict';
  if (document.addEventListener) {
    document.addEventListener('DOMContentLoaded', fn);
  } else {
    document.attachEvent('onreadystatechange', function() {
      if (document.readyState === 'interactive') {
        fn();
      }
    });
  }
}

ready(function() {
  'use strict';

  var nav = document.getElementById('site-navigation'), button, menu;
  button = nav.getElementsByTagName('button')[0];
  menu = nav.getElementsByTagName('ul')[0];

  // Hide the menu if it's empty
  if (! menu.childNodes.length) {
    button.style.display = 'none';
  }

  button.onclick = function() {
    if (button.className.indexOf('toggled-on') !== -1) {
      button.className = button.className.replace(' toggled-on', '');
      menu.className = menu.className.replace(' toggled-on', '');
    } else {
      button.className += ' toggled-on';
      menu.className += ' toggled-on';
    }
  };
});

/* jshint camelcase: false */
window.cookieconsent_options = {
  message: 'Denna bloggen använder cookies för att ge dig en bättre upplevelse.',
  dismiss: 'Jag godkänner',
  learnMore: 'Om cookies på misslisibell.se.',
  link: 'om-cookies/',
  theme: null
};
<commit_msg>Update cookie message<commit_after>// Source: http://youmightnotneedjquery.com/#ready
function ready(fn) {
  'use strict';
  if (document.addEventListener) {
    document.addEventListener('DOMContentLoaded', fn);
  } else {
    document.attachEvent('onreadystatechange', function() {
      if (document.readyState === 'interactive') {
        fn();
      }
    });
  }
}

ready(function() {
  'use strict';

  var nav = document.getElementById('site-navigation'), button, menu;
  button = nav.getElementsByTagName('button')[0];
  menu = nav.getElementsByTagName('ul')[0];

  // Hide the menu if it's empty
  if (! menu.childNodes.length) {
    button.style.display = 'none';
  }

  button.onclick = function() {
    if (button.className.indexOf('toggled-on') !== -1) {
      button.className = button.className.replace(' toggled-on', '');
      menu.className = menu.className.replace(' toggled-on', '');
    } else {
      button.className += ' toggled-on';
      menu.className += ' toggled-on';
    }
  };
});

/* jshint camelcase: false */
window.cookieconsent_options = {
  message: 'Denna bloggen använder cookies för att ge dig en bättre ' +
           'upplevelse. Genom att använda bloggen godkänner du användningen ' +
           'av cookies.',
  dismiss: 'Jag godkänner',
  learnMore: 'Läs mer',
  link: 'om-cookies/',
  theme: null
};
<|endoftext|>


<commit_before>var app = new Vue({
  el: '#app',
  data: {
	crypto_amount: 0,
	cryptoPrices: {},
	currencies: [],
	currentCrypto: "BTC",
	exchangeRates: {
	rates: {}
	},
	fiat: {
		AUD: "$",
		BRL: "R$",
		CAD: "C$",
		CHF: "Fr.",
		CNY: "¥",
		EUR: "€",
		GBP: "£",
		HKD: "HK$",
		IDR: "Rp",
		INR: "₹",
		JPY: "¥",
		KRW: "₩",
		MXN: "M$",
		RUB: "₽",
		USD: "$"
	},
	fiat_amount: 0,
	investment: {
		currentPrice: 0,
		target: 0,
		amount: 0
	},
	settings: {
		currency: "USD",
		darkMode: false,
		numDisplay: 100,
		removeUnmineable: false
	},
	shifts: {},
	state: "calculator",
	stats: {},
	topGains: [],
	topLosses: []
  },
  methods: {
	calculate: function (type) {
		var crypto = $('.ui.dropdown').dropdown('get value')[0] ? $('.ui.dropdown').dropdown('get value')[0].toUpperCase() : "BTC";
		var fiat = $('.ui.dropdown').dropdown('get value')[1] ? $('.ui.dropdown').dropdown('get value')[1].toUpperCase() : "USD";
		var rate = (fiat != "USD" ? this.exchangeRates.rates[fiat] : 1);
		if (type == "fiat") {
			this.crypto_amount = Number($('#crypto-amount')[0].value);
			this.fiat_amount = this.crypto_amount * this.cryptoPrices[crypto] * rate;
		} else {
			this.fiat_amount = Number($('#fiat-amount')[0].value);
			this.crypto_amount = ((this.fiat_amount / this.cryptoPrices[crypto]) * rate).toFixed(8);
		}
	},
	changeState: function (state) {
		this.state = state;
	},
	checkMineable: function () {
		if (!this.settings.removeUnmineable) {return this.currencies};
		return this.currencies.filter(function(currency){
		  return (mineable[currency.symbol] == "m" || mineable[currency.symbol] == "p" || mineable[currency.symbol] == "i" || mineable[currency.symbol] == "s");
		});
	},
	currentInvestmentPrice: function () {
		var crypto = $('.ui.dropdown').dropdown('get value')[2] ? $('.ui.dropdown').dropdown('get value')[2].toUpperCase() : "BTC";
		var fiat = $('.ui.dropdown').dropdown('get value')[3] ? $('.ui.dropdown').dropdown('get value')[3].toUpperCase() : "USD";
		var rate = (fiat != "USD" ? this.exchangeRates.rates[fiat] : 1);

		this.investment.currentPrice = this.cryptoPrices[crypto] * rate;
		return (this.investment.currentPrice * this.investment.amount * rate).toLocaleString();
	},
	format: function (amount) {
		return parseFloat(amount).toLocaleString();
	},
	getImgID: function (name) {
		return cmcid[name];
	},
	getMarketcap: function (currency) {
		return app.format(currency['market_cap_' + app.settings.currency.toLowerCase()]);
	},
	getPrice: function (currency) {
		return app.format(currency['price_' + app.settings.currency.toLowerCase()]);
	},
	mineable: function (symbol) {
		return mineable[symbol];
	},
	updateData: function () {
		var _this = this;

		url = 'https://test.cors.workers.dev/?https://api.coinmarketcap.com/v1/ticker/?limit=' + app.settings.numDisplay;
		if (this.settings.currency != "BTC" && this.settings.currency != "USD") {
			url += "&convert=" + this.settings.currency;
		};

		this.$http.get(url).then(function (response) {
			_this.currencies = response.body;
			var coins = _this.currencies.slice();
			coins.sort(function (a, b) {
				return Number(a.percent_change_24h) - Number(b.percent_change_24h);
			});
			_this.topLosses = [jQuery.extend({}, coins[0]), jQuery.extend({}, coins[1]), jQuery.extend({}, coins[2])];
			coins.sort(function (a, b) {
				return Number(b.percent_change_24h) - Number(a.percent_change_24h);
			});
			_this.topGains = [jQuery.extend({}, coins[0]), jQuery.extend({}, coins[1]), jQuery.extend({}, coins[2])];

			var _iteratorNormalCompletion = true;
			var _didIteratorError = false;
			var _iteratorError = undefined;

			try {
				for (var _iterator = _this.currencies[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
					var currency = _step.value;

					_this.cryptoPrices[currency.symbol] = Number(currency.price_usd);
				}
			} catch (err) {
				_didIteratorError = true;
				_iteratorError = err;
			} finally {
				try {
					if (!_iteratorNormalCompletion && _iterator.return) {
						_iterator.return();
					}
				} finally {
					if (_didIteratorError) {
						throw _iteratorError;
					}
				}
			}

			;

			_this.$http.get('https://shapeshift.io/getcoins').then(function (res) {
				app.shifts = res.body;
				_this.currencies.forEach(function (currency, idx) {
					if (app.shifts[currency.symbol] && app.shifts[currency.symbol].status == "available") {
						// using the 'last_updated' property for canShift
						// something about reactivity, so I'll just use a small hack :)
						app.currencies[idx].last_updated = true;
					} else {
						app.currencies[idx].last_updated = false;
					}
				});
			});
			_this.$http.get('https://api.exchangeratesapi.io/latest?base=USD').then(function (response) {
				_this.exchangeRates = response.body;
				$('#crypto-dropdown').dropdown('setting', 'onChange', function () {
					app.calculate('fiat');
				});
				$('#fiat-dropdown').dropdown('setting', 'onChange', function () {
					app.calculate('crypto');
				});
				$('#investment-crypto').dropdown('setting', 'onChange', function (val) {
					app.currentInvestmentPrice();
				});
				$('#target-fiat').dropdown('setting', 'onChange', function () {
					app.currentInvestmentPrice();
				});
			});
		});
		this.$http.get('https://test.cors.workers.dev/?https://api.coinmarketcap.com/v1/global/').then(function (response) {
			_this.stats = response.body;
		});
	},
	wallet: function (symbol) {
		return wallets[symbol];
	}
  },
  computed: {
	current: function () {
		return this.fiat[this.settings.currency];
	},
	currencyList: function () {
		var list = [];
		var _iteratorNormalCompletion = true;
		var _didIteratorError = false;
		var _iteratorError = undefined;

		try {
				for (var _iterator = this.currencies[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
						var currency = _step.value;

						list.push(currency.symbol);
				}
		} catch (err) {
				_didIteratorError = true;
				_iteratorError = err;
		} finally {
				try {
						if (!_iteratorNormalCompletion && _iterator.return) {
								_iterator.return();
						}
				} finally {
						if (_didIteratorError) {
								throw _iteratorError;
						}
				}
		}

		return list.sort();
	},
	profit: function () {
		return ((Number(this.investment.target) - Number(this.investment.currentPrice)) * this.investment.amount).toFixed(2).toLocaleString();
	},
	rates: function () {
		var c = Object.keys(this.exchangeRates.rates)
		c.push("USD");
		return c.sort();
	}
  }
})

$(document).ready(function() {
	var settings = localStorage.getItem("settings");

	if (settings) {
		app.settings = JSON.parse(settings);
	}

	app.updateData();
	setInterval(app.updateData, 300 * 1000);
});

function showModal(symbol) {
	app.currentCrypto = symbol;
	$('.ui.modal').modal('show');
};

function saveSettings() {
	app.settings.currency = $("#base-currency")[0].value ? $("#base-currency")[0].value : "USD";
	app.settings.darkMode = $("#dark")[0].checked;
	app.settings.numDisplay = $("#num-display")[0].value;
	app.settings.removeUnmineable = $("#unmineable")[0].checked;

	localStorage.setItem("settings", JSON.stringify(app.settings));
	window.location.reload();
};<commit_msg>update urls<commit_after>var app = new Vue({
  el: '#app',
  data: {
	crypto_amount: 0,
	cryptoPrices: {},
	currencies: [],
	currentCrypto: "BTC",
	exchangeRates: {
	rates: {}
	},
	fiat: {
		AUD: "$",
		BRL: "R$",
		CAD: "C$",
		CHF: "Fr.",
		CNY: "¥",
		EUR: "€",
		GBP: "£",
		HKD: "HK$",
		IDR: "Rp",
		INR: "₹",
		JPY: "¥",
		KRW: "₩",
		MXN: "M$",
		RUB: "₽",
		USD: "$"
	},
	fiat_amount: 0,
	investment: {
		currentPrice: 0,
		target: 0,
		amount: 0
	},
	settings: {
		currency: "USD",
		darkMode: false,
		numDisplay: 100,
		removeUnmineable: false
	},
	shifts: {},
	state: "calculator",
	stats: {},
	topGains: [],
	topLosses: []
  },
  methods: {
	calculate: function (type) {
		var crypto = $('.ui.dropdown').dropdown('get value')[0] ? $('.ui.dropdown').dropdown('get value')[0].toUpperCase() : "BTC";
		var fiat = $('.ui.dropdown').dropdown('get value')[1] ? $('.ui.dropdown').dropdown('get value')[1].toUpperCase() : "USD";
		var rate = (fiat != "USD" ? this.exchangeRates.rates[fiat] : 1);
		if (type == "fiat") {
			this.crypto_amount = Number($('#crypto-amount')[0].value);
			this.fiat_amount = this.crypto_amount * this.cryptoPrices[crypto] * rate;
		} else {
			this.fiat_amount = Number($('#fiat-amount')[0].value);
			this.crypto_amount = ((this.fiat_amount / this.cryptoPrices[crypto]) * rate).toFixed(8);
		}
	},
	changeState: function (state) {
		this.state = state;
	},
	checkMineable: function () {
		if (!this.settings.removeUnmineable) {return this.currencies};
		return this.currencies.filter(function(currency){
		  return (mineable[currency.symbol] == "m" || mineable[currency.symbol] == "p" || mineable[currency.symbol] == "i" || mineable[currency.symbol] == "s");
		});
	},
	currentInvestmentPrice: function () {
		var crypto = $('.ui.dropdown').dropdown('get value')[2] ? $('.ui.dropdown').dropdown('get value')[2].toUpperCase() : "BTC";
		var fiat = $('.ui.dropdown').dropdown('get value')[3] ? $('.ui.dropdown').dropdown('get value')[3].toUpperCase() : "USD";
		var rate = (fiat != "USD" ? this.exchangeRates.rates[fiat] : 1);

		this.investment.currentPrice = this.cryptoPrices[crypto] * rate;
		return (this.investment.currentPrice * this.investment.amount * rate).toLocaleString();
	},
	format: function (amount) {
		return parseFloat(amount).toLocaleString();
	},
	getImgID: function (name) {
		return cmcid[name];
	},
	getMarketcap: function (currency) {
		return app.format(currency['market_cap_' + app.settings.currency.toLowerCase()]);
	},
	getPrice: function (currency) {
		return app.format(currency['price_' + app.settings.currency.toLowerCase()]);
	},
	mineable: function (symbol) {
		return mineable[symbol];
	},
	updateData: function () {
		var _this = this;

		url = `https://api.allorigins.win/get?url=${encodeURIComponent('https://api.coinmarketcap.com/v1/ticker/?limit=')}` + app.settings.numDisplay;
		if (this.settings.currency != "BTC" && this.settings.currency != "USD") {
			url += "&convert=" + this.settings.currency;
		};

		this.$http.get(url).then(function (response) {
			_this.currencies = JSON.parse(response.body.contents);
			var coins = _this.currencies.slice();
			coins.sort(function (a, b) {
				return Number(a.percent_change_24h) - Number(b.percent_change_24h);
			});
			_this.topLosses = [jQuery.extend({}, coins[0]), jQuery.extend({}, coins[1]), jQuery.extend({}, coins[2])];
			coins.sort(function (a, b) {
				return Number(b.percent_change_24h) - Number(a.percent_change_24h);
			});
			_this.topGains = [jQuery.extend({}, coins[0]), jQuery.extend({}, coins[1]), jQuery.extend({}, coins[2])];

			var _iteratorNormalCompletion = true;
			var _didIteratorError = false;
			var _iteratorError = undefined;

			try {
				for (var _iterator = _this.currencies[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
					var currency = _step.value;

					_this.cryptoPrices[currency.symbol] = Number(currency.price_usd);
				}
			} catch (err) {
				_didIteratorError = true;
				_iteratorError = err;
			} finally {
				try {
					if (!_iteratorNormalCompletion && _iterator.return) {
						_iterator.return();
					}
				} finally {
					if (_didIteratorError) {
						throw _iteratorError;
					}
				}
			}

			;

			_this.$http.get('https://shapeshift.io/getcoins').then(function (res) {
				app.shifts = res.body;
				_this.currencies.forEach(function (currency, idx) {
					if (app.shifts[currency.symbol] && app.shifts[currency.symbol].status == "available") {
						// using the 'last_updated' property for canShift
						// something about reactivity, so I'll just use a small hack :)
						app.currencies[idx].last_updated = true;
					} else {
						app.currencies[idx].last_updated = false;
					}
				});
			});
			_this.$http.get('https://api.exchangeratesapi.io/latest?base=USD').then(function (response) {
				_this.exchangeRates = response.body;
				$('#crypto-dropdown').dropdown('setting', 'onChange', function () {
					app.calculate('fiat');
				});
				$('#fiat-dropdown').dropdown('setting', 'onChange', function () {
					app.calculate('crypto');
				});
				$('#investment-crypto').dropdown('setting', 'onChange', function (val) {
					app.currentInvestmentPrice();
				});
				$('#target-fiat').dropdown('setting', 'onChange', function () {
					app.currentInvestmentPrice();
				});
			});
		});
		this.$http.get(`https://api.allorigins.win/get?url=${encodeURIComponent('https://api.coinmarketcap.com/v1/global/')}`).then(function (response) {
			_this.stats = JSON.parse(response.body.contents);
		});
	},
	wallet: function (symbol) {
		return wallets[symbol];
	}
  },
  computed: {
	current: function () {
		return this.fiat[this.settings.currency];
	},
	currencyList: function () {
		var list = [];
		var _iteratorNormalCompletion = true;
		var _didIteratorError = false;
		var _iteratorError = undefined;

		try {
				for (var _iterator = this.currencies[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
						var currency = _step.value;

						list.push(currency.symbol);
				}
		} catch (err) {
				_didIteratorError = true;
				_iteratorError = err;
		} finally {
				try {
						if (!_iteratorNormalCompletion && _iterator.return) {
								_iterator.return();
						}
				} finally {
						if (_didIteratorError) {
								throw _iteratorError;
						}
				}
		}

		return list.sort();
	},
	profit: function () {
		return ((Number(this.investment.target) - Number(this.investment.currentPrice)) * this.investment.amount).toFixed(2).toLocaleString();
	},
	rates: function () {
		var c = Object.keys(this.exchangeRates.rates)
		c.push("USD");
		return c.sort();
	}
  }
})

$(document).ready(function() {
	var settings = localStorage.getItem("settings");

	if (settings) {
		app.settings = JSON.parse(settings);
	}

	app.updateData();
	setInterval(app.updateData, 300 * 1000);
});

function showModal(symbol) {
	app.currentCrypto = symbol;
	$('.ui.modal').modal('show');
};

function saveSettings() {
	app.settings.currency = $("#base-currency")[0].value ? $("#base-currency")[0].value : "USD";
	app.settings.darkMode = $("#dark")[0].checked;
	app.settings.numDisplay = $("#num-display")[0].value;
	app.settings.removeUnmineable = $("#unmineable")[0].checked;

	localStorage.setItem("settings", JSON.stringify(app.settings));
	window.location.reload();
};<|endoftext|>


<commit_before>function QueryUI(queryString, userName) {
    "use strict";
    var CommandParser,
        queryToRun = queryString;

    function ICommandParser() {
        var MatchEndOfLineComments = /^\s*(?:\/\/|--).*$/gm,
            MatchOneQuotedString = /'[^']*'/m,
            MatchDoubleQuotes = /\"/g,
            EscapedDoubleQuoteLiteral = '\\"',
            QuotedStringNonceLiteral = "#COMMAND_PARSER_REPLACED_STRING#",
            // Generate fixed-length 5-digit nonce values from 100000 - 999999.
            // That's 900000 strings per statement batch -- that should be enough.
            MatchOneQuotedStringNonce = /#COMMAND_PARSER_REPLACED_STRING#(\d\d\d\d\d\d)/,
            QuotedStringNonceBase = 100000,

            // Stored procedure parameters can be separated by commas or whitespace.
            // Multiple commas like "execute proc a,,b" are merged into one separator because that's easy.
            MatchParameterSeparators = /[\s,]+/g;

        // Avoid false positives for statement grammar inside quoted strings by
        // substituting a nonce for each string.
        function disguiseQuotedStrings(src, stringBankOut) {
            var nonceNum, nextString;

            // Extract quoted strings to keep their content from getting confused with interesting
            // statement syntax.
            nonceNum = QuotedStringNonceBase;
            while (true) {
                nextString = MatchOneQuotedString.exec(src);
                if (nextString === null) {
                    break;
                }
                stringBankOut.push(nextString);
                src = src.replace(nextString, QuotedStringNonceLiteral + nonceNum);
                nonceNum += 1;
            }
            return src;
        }

        // Restore quoted strings by replcaing each nonce with its original quoted string.
        function undisguiseQuotedStrings(src, stringBank) {
            var nextNonce, nonceNum;
            // Clean up by restoring the replaced quoted strings.
            while (true) {
                nextNonce = MatchOneQuotedStringNonce.exec(src);
                if (nextNonce === null) {
                    break;
                }
                nonceNum = parseInt(nextNonce[1], 10);
                src = src.replace(QuotedStringNonceLiteral + nonceNum,
                                  stringBank[nonceNum - QuotedStringNonceBase]);
            }
            return src;
        }

        // break down a multi-statement string into a statement array.
        function parseUserInputMethod(src) {
            var splitStmts, stmt, ii, len,
                stringBank = [],
                statementBank = [];
            // Eliminate line comments permanently.
            src = src.replace(MatchEndOfLineComments, '');

            // Extract quoted strings to keep their content from getting confused with
            // interesting statement syntax. This is required for statement splitting at
            // semicolon boundaries -- semicolons might appear in quoted text.
            src = disguiseQuotedStrings(src, stringBank);

            splitStmts = src.split(';');

            statementBank = [];
            for (ii = 0, len = splitStmts.length; ii < len; ii += 1) {
                stmt = splitStmts[ii].trim();
                if (stmt !== '') {
                    // Clean up by restoring the replaced quoted strings.
                    stmt = undisguiseQuotedStrings(stmt, stringBank);

                    // Prepare double-quotes for HTTP request formatting by \-escaping them.
                    // NOTE: This is NOT a clean up of any mangling done inside this function.
                    // It just needs doing at some point, so why not here?
                    stmt = stmt.replace(MatchDoubleQuotes, EscapedDoubleQuoteLiteral);

                    statementBank.push(stmt);
                }
            }
            return statementBank;
        }

        // break down a multi-parameter proc call into an array of (1) proc name and any parameters.
        function parseProcedureCallParametersMethod(src) {
            // Extract quoted strings to keep their content from getting confused with interesting
            // statement syntax.
            var splitParams, param, ii, len,
                stringBank = [],
                parameterBank = [];
            src = disguiseQuotedStrings(src, stringBank);

            splitParams = src.split(MatchParameterSeparators);

            for (ii = 0, len = splitParams.length; ii < len; ii += 1) {
                param = splitParams[ii].trim();
                if (param !== '') {
                    if (param.toLowerCase() === 'null') {
                        parameterBank.push(null);
                    } else {
                        if (param.indexOf(QuotedStringNonceLiteral) == 0) {
                            // Clean up by restoring the replaced quoted strings.
                            param = undisguiseQuotedStrings(param, stringBank);
                        }
                        parameterBank.push(param);
                    }
                }
            }
            return parameterBank;
        }

        this.parseProcedureCallParameters = parseProcedureCallParametersMethod
        this.parseUserInput = parseUserInputMethod;
    }

    CommandParser = new ICommandParser();

    //TODO: Apply reasonable coding standards to the code below...

    function executeCallback(format, target, id) {
        var Format = format;
        var targetHtml = target.find('#resultHtml');
        var targetCsv = target.find('#resultCsv');
        var targetMonospace = target.find('#resultMonospace');
        var Id = id;
        $(targetHtml).html('');
        $(targetCsv).html('');
        $(targetMonospace).html('');

        function callback(response) {

            var processResponseForAllViews = function() {
                processResponse('HTML', targetHtml, Id + '_html', response);
                processResponse('CSV', targetCsv, Id + '_csv', response);
                processResponse('MONOSPACE', targetMonospace, Id + '_mono', response);
            };

            var handlePortSwitchingOption = function (isPaused) {

                if (isPaused) {
                    //Show error message with an option to allow admin port switching
                    $("#queryDatabasePausedErrorPopupLink").click();
                } else {
                    processResponseForAllViews();
                }
            };

            //Handle the case when Database is paused
            if (response.status == -5 && VoltDbAdminConfig.isAdmin && !SQLQueryRender.useAdminPortCancelled) {

                if (!VoltDbAdminConfig.isDbPaused) {

                    //Refresh cluster state to display latest status.
                    var loadAdminTabPortAndOverviewDetails = function(portAndOverviewValues) {
                        VoltDbAdminConfig.displayPortAndRefreshClusterState(portAndOverviewValues);
                        handlePortSwitchingOption(VoltDbAdminConfig.isDbPaused);
                    };
                    voltDbRenderer.GetSystemInformation(function() {}, loadAdminTabPortAndOverviewDetails, function(data) {});
                } else {
                    handlePortSwitchingOption(true);
                }

            } else {
                processResponseForAllViews();
            }
            SQLQueryRender.useAdminPortCancelled = false;
        }
        this.Callback = callback;
    }

    function executeMethod() {
        var target = $('.queryResult');
        var format = $('#exportType').val();

        var dataSource = $.cookie('connectionkey') == undefined ? '' : $.cookie('connectionkey');
        if (!VoltDBCore.connections.hasOwnProperty(dataSource)) {
            $(target).html('Connect to a datasource first.');
            return;
        }

        var connection = VoltDBCore.connections[dataSource];
        var source = '';
        source = queryToRun;
        source = source.replace(/^\s+|\s+$/g, '');
        if (source == '')
            return;

        $("#runBTn").attr('disabled', 'disabled');
        $("#runBTn").addClass("graphOpacity");

        var statements = CommandParser.parseUserInput(source);
        var start = (new Date()).getTime();
        var connectionQueue = connection.getQueue();
        connectionQueue.Start();
        for (var i = 0; i < statements.length; i++) {
            var id = 'r' + i;
            var callback = new executeCallback(format, target, id);
            if (/^execute /i.test(statements[i]))
                statements[i] = 'exec ' + statements[i].substr(8);
            if (/^exec /i.test(statements[i])) {
                var params = CommandParser.parseProcedureCallParameters(statements[i].substr(5));
                var procedure = params.splice(0, 1)[0];
                connectionQueue.BeginExecute(procedure, params, callback.Callback);
            }
            else
                if (/^explain /i.test(statements[i])) {
                    connectionQueue.BeginExecute('@Explain', statements[i].substr(8).replace(/[\r\n]+/g, " ").replace(/'/g, "''"), callback.Callback);
                }
                else
                    if (/^explainproc /i.test(statements[i])) {
                        connectionQueue.BeginExecute('@ExplainProc', statements[i].substr(12).replace(/[\r\n]+/g, " ").replace(/'/g, "''"), callback.Callback);
                    }
                    else {
                        connectionQueue.BeginExecute('@AdHoc', statements[i].replace(/[\r\n]+/g, " ").replace(/'/g, "''"), callback.Callback);
                    }
        }

        function atEnd(state, success) {
            var totalDuration = (new Date()).getTime() - state;
            if (success) {
                $('#queryResults').removeClass('errorValue');
                $('#queryResults').html('Query Duration: ' + (totalDuration / 1000.0) + 's');
            } else {
                $('#queryResults').addClass('errorValue');
                $('#queryResults').html('Query error | Query Duration: ' + (totalDuration / 1000.0) + 's');
            }
            $("#runBTn").removeAttr('disabled');
            $("#runBTn").removeClass("graphOpacity");
        }
        connectionQueue.End(atEnd, start);
    }

    function processResponse(format, target, id, response) {
        if (response.status == 1) {
            var tables = response.results;
            for (var j = 0; j < tables.length; j++)
                printResult(format, target, id + '_' + j, tables[j]);

        } else {
            // This inline encoder hack is intended to use html's &#nnnn; character encoding to
            // properly escape characters that would otherwise mean something as html
            // -- including angle brackets and such that are commonly used to suggest that the
            // user correct their ddl grammar. Angle-bracketed place-holders were being
            // rendered as invisible meaningless html tags.
            // See http://stackoverflow.com/questions/18749591/encode-html-entities-in-javascript#18750001
            var encodedStatus = response.statusstring.replace(/[\u00A0-\u9999<>\&]/gim,
                function(i) { return '&#'+i.charCodeAt(0)+';'; });
            target.append('Error: ' + encodedStatus + '\r\n');
        }
    }

    function printResult(format, target, id, table) {
        switch (format.toUpperCase()) {
            case 'CSV'.toUpperCase():
                printCSV(target, id, table);
                break;
            case 'MONOSPACE':
                printMonoSpace(target, id, table);
                 break;
            default:
                printGrid(target, id, table);
                break;
        }
    }

    function isUpdateResult(table) {
        return ((table.schema[0].name.length == 0 || table.schema[0].name == "modified_tuples") && table.data.length == 1 && table.schema.length == 1 && table.schema[0].type == 6);
    }

    function applyFormat(val) {
        // Formatting for explain proc.  Only format on objects that have a replace function
        if (null != val && val.replace != null) {
            val = val.replace(/\t/g, '    ');
            val = val.replace(/ /g, ' ');
            val = val.replace(/\n/g, '
');
        }
        return val;
    }

    function lPadZero(v, len) {
        // return a string left padded with zeros to length 'len'
        v = v + "";
        if (v.length < len) {
            v = Array(len - v.length + 1).join("0") + v;
        }
        return v;
    }

    function printGrid(target, id, table) {
        var src = '

';
        if (isUpdateResult(table))
            src += 'modified_tuples	';
        else {
            for (var j = 0; j < table.schema.length; j++)
                src += '' + (table.schema[j].name == "" ? ("Column " + (j + 1)) : table.schema[j].name) + '	';
        }
        src += '

';
        for (var j = 0; j < table.data.length; j++) {
            src += '
';
            for (var k = 0; k < table.data[j].length; k++) {
                var val = table.data[j][k];
                var typ = table.schema[k].type;
                if (typ == 11) {
                    var us = val % 1000;
                    var dt = new Date(val / 1000);
                    val = lPadZero(dt.getUTCFullYear(), 4) + "-"
                        + lPadZero((dt.getUTCMonth()) + 1, 2) + "-"
                        + lPadZero(dt.getUTCDate(), 2) + " "
                        + lPadZero(dt.getUTCHours(), 2) + ":"
                        + lPadZero(dt.getUTCMinutes(), 2) + ":"
                        + lPadZero(dt.getUTCSeconds(), 2) + "."
                        + lPadZero((dt.getUTCMilliseconds()) * 1000 + us, 6);
                    typ = 9;  //code for varchar
                }
                val = applyFormat(val);
                src += '' + val + '	';
            }
            src += '
';
        }
        src += '

';
        $(target).append(src);
        sorttable.makeSortable(document.getElementById('table_'+id));
    }

    function printMonoSpace(target, id, table) {
        if (isUpdateResult(table)) {
            $(target).append('\r\n\r\n(' + table.data[0][0] + ' row(s) affected)\r\n\r\n');
            return;
        }
        var src = '';
        for (var j = 0; j
 0) src += '\t';
            src += table.schema[j].name;
        }
        src += '
\r\n';
        for (var j = 0; j < table.data.length; j++) {
            for (var k = 0; k
 0) src += '\t';
                src += table.data[j][k];
            }
            src += '
\r\n';
        }
        src += '
\r\n(' + j + ' row(s) affected)\r\n\r\n

';
        $(target).append(src);
    }

    function printCSV(target, id, table) {
        if (isUpdateResult(table)) {
            $(target).append('\r\n\r\n(' + table.data[0][0] + ' row(s) affected)\r\n\r\n');
            return;
        }
        var src = '<pr>';
        var colModeData = [];
        for (var j = 0; j
 0) src += ', ';
            src += table.schema[j].name;
        }
        src += '
\r\n';
        for (var j = 0; j < table.data.length; j++) {
            for (var k = 0; k
 0) src += ', ';
                src += table.data[j][k];
            }
            src += '
\r\n';
        }
        src += '
\r\n(' + j + ' row(s) affected)\r\n\r\n</pr>

';
        $(target).append(src);
    }

    this.execute = executeMethod;
}
<commit_msg>invisible diff?<commit_after>function QueryUI(queryString, userName) {
    "use strict";
    var CommandParser,
        queryToRun = queryString;

    function ICommandParser() {
        var MatchEndOfLineComments = /^\s*(?:\/\/|--).*$/gm,
            MatchOneQuotedString = /'[^']*'/m,
            MatchDoubleQuotes = /\"/g,
            EscapedDoubleQuoteLiteral = '\\"',
            QuotedStringNonceLiteral = "#COMMAND_PARSER_REPLACED_STRING#",
            // Generate fixed-length 5-digit nonce values from 100000 - 999999.
            // That's 900000 strings per statement batch -- that should be enough.
            MatchOneQuotedStringNonce = /#COMMAND_PARSER_REPLACED_STRING#(\d\d\d\d\d\d)/,
            QuotedStringNonceBase = 100000,

            // Stored procedure parameters can be separated by commas or whitespace.
            // Multiple commas like "execute proc a,,b" are merged into one separator because that's easy.
            MatchParameterSeparators = /[\s,]+/g;

        // Avoid false positives for statement grammar inside quoted strings by
        // substituting a nonce for each string.
        function disguiseQuotedStrings(src, stringBankOut) {
            var nonceNum, nextString;

            // Extract quoted strings to keep their content from getting confused with interesting
            // statement syntax.
            nonceNum = QuotedStringNonceBase;
            while (true) {
                nextString = MatchOneQuotedString.exec(src);
                if (nextString === null) {
                    break;
                }
                stringBankOut.push(nextString);
                src = src.replace(nextString, QuotedStringNonceLiteral + nonceNum);
                nonceNum += 1;
            }
            return src;
        }

        // Restore quoted strings by replcaing each nonce with its original quoted string.
        function undisguiseQuotedStrings(src, stringBank) {
            var nextNonce, nonceNum;
            // Clean up by restoring the replaced quoted strings.
            while (true) {
                nextNonce = MatchOneQuotedStringNonce.exec(src);
                if (nextNonce === null) {
                    break;
                }
                nonceNum = parseInt(nextNonce[1], 10);
                src = src.replace(QuotedStringNonceLiteral + nonceNum,
                                  stringBank[nonceNum - QuotedStringNonceBase]);
            }
            return src;
        }

        // break down a multi-statement string into a statement array.
        function parseUserInputMethod(src) {
            var splitStmts, stmt, ii, len,
                stringBank = [],
                statementBank = [];
            // Eliminate line comments permanently.
            src = src.replace(MatchEndOfLineComments, '');

            // Extract quoted strings to keep their content from getting confused with
            // interesting statement syntax. This is required for statement splitting at
            // semicolon boundaries -- semicolons might appear in quoted text.
            src = disguiseQuotedStrings(src, stringBank);

            splitStmts = src.split(';');

            statementBank = [];
            for (ii = 0, len = splitStmts.length; ii < len; ii += 1) {
                stmt = splitStmts[ii].trim();
                if (stmt !== '') {
                    // Clean up by restoring the replaced quoted strings.
                    stmt = undisguiseQuotedStrings(stmt, stringBank);

                    // Prepare double-quotes for HTTP request formatting by \-escaping them.
                    // NOTE: This is NOT a clean up of any mangling done inside this function.
                    // It just needs doing at some point, so why not here?
                    stmt = stmt.replace(MatchDoubleQuotes, EscapedDoubleQuoteLiteral);

                    statementBank.push(stmt);
                }
            }
            return statementBank;
        }

        // break down a multi-parameter proc call into an array of (1) proc name and any parameters.
        function parseProcedureCallParametersMethod(src) {
            // Extract quoted strings to keep their content from getting confused with interesting
            // statement syntax.
            var splitParams, param, ii, len,
                stringBank = [],
                parameterBank = [];
            src = disguiseQuotedStrings(src, stringBank);

            splitParams = src.split(MatchParameterSeparators);

            for (ii = 0, len = splitParams.length; ii < len; ii += 1) {
                param = splitParams[ii].trim();
                if (param !== '') {
                    if (param.toLowerCase() === 'null') {
                        parameterBank.push(null);
                    } else {
                        if (param.indexOf(QuotedStringNonceLiteral) == 0) {
                            // Clean up by restoring the replaced quoted strings.
                            param = undisguiseQuotedStrings(param, stringBank);
                        }
                        parameterBank.push(param);
                    }
                }
            }
            return parameterBank;
        }

        this.parseProcedureCallParameters = parseProcedureCallParametersMethod
        this.parseUserInput = parseUserInputMethod;
    }

    CommandParser = new ICommandParser();

    //TODO: Apply reasonable coding standards to the code below...

    function executeCallback(format, target, id) {
        var Format = format;
        var targetHtml = target.find('#resultHtml');
        var targetCsv = target.find('#resultCsv');
        var targetMonospace = target.find('#resultMonospace');
        var Id = id;
        $(targetHtml).html('');
        $(targetCsv).html('');
        $(targetMonospace).html('');

        function callback(response) {

            var processResponseForAllViews = function() {
                processResponse('HTML', targetHtml, Id + '_html', response);
                processResponse('CSV', targetCsv, Id + '_csv', response);
                processResponse('MONOSPACE', targetMonospace, Id + '_mono', response);
            };

            var handlePortSwitchingOption = function (isPaused) {

                if (isPaused) {
                    //Show error message with an option to allow admin port switching
                    $("#queryDatabasePausedErrorPopupLink").click();
                } else {
                    processResponseForAllViews();
                }
            };

            //Handle the case when Database is paused
            if (response.status == -5 && VoltDbAdminConfig.isAdmin && !SQLQueryRender.useAdminPortCancelled) {

                if (!VoltDbAdminConfig.isDbPaused) {

                    //Refresh cluster state to display latest status.
                    var loadAdminTabPortAndOverviewDetails = function(portAndOverviewValues) {
                        VoltDbAdminConfig.displayPortAndRefreshClusterState(portAndOverviewValues);
                        handlePortSwitchingOption(VoltDbAdminConfig.isDbPaused);
                    };
                    voltDbRenderer.GetSystemInformation(function() {}, loadAdminTabPortAndOverviewDetails, function(data) {});
                } else {
                    handlePortSwitchingOption(true);
                }

            } else {
                processResponseForAllViews();
            }
            SQLQueryRender.useAdminPortCancelled = false;
        }
        this.Callback = callback;
    }

    function executeMethod() {
        var target = $('.queryResult');
        var format = $('#exportType').val();

        var dataSource = $.cookie('connectionkey') == undefined ? '' : $.cookie('connectionkey');
        if (!VoltDBCore.connections.hasOwnProperty(dataSource)) {
            $(target).html('Connect to a datasource first.');
            return;
        }

        var connection = VoltDBCore.connections[dataSource];
        var source = '';
        source = queryToRun;
        source = source.replace(/^\s+|\s+$/g, '');
        if (source == '')
            return;

        $("#runBTn").attr('disabled', 'disabled');
        $("#runBTn").addClass("graphOpacity");

        var statements = CommandParser.parseUserInput(source);
        var start = (new Date()).getTime();
        var connectionQueue = connection.getQueue();
        connectionQueue.Start();
        for (var i = 0; i < statements.length; i++) {
            var id = 'r' + i;
            var callback = new executeCallback(format, target, id);
            if (/^execute /i.test(statements[i]))
                statements[i] = 'exec ' + statements[i].substr(8);
            if (/^exec /i.test(statements[i])) {
                var params = CommandParser.parseProcedureCallParameters(statements[i].substr(5));
                var procedure = params.splice(0, 1)[0];
                connectionQueue.BeginExecute(procedure, params, callback.Callback);
            }
            else
                if (/^explain /i.test(statements[i])) {
                    connectionQueue.BeginExecute('@Explain', statements[i].substr(8).replace(/[\r\n]+/g, " ").replace(/'/g, "''"), callback.Callback);
                }
                else
                    if (/^explainproc /i.test(statements[i])) {
                        connectionQueue.BeginExecute('@ExplainProc', statements[i].substr(12).replace(/[\r\n]+/g, " ").replace(/'/g, "''"), callback.Callback);
                    }
                    else {
                        connectionQueue.BeginExecute('@AdHoc', statements[i].replace(/[\r\n]+/g, " ").replace(/'/g, "''"), callback.Callback);
                    }
        }

        function atEnd(state, success) {
            var totalDuration = (new Date()).getTime() - state;
            if (success) {
                $('#queryResults').removeClass('errorValue');
                $('#queryResults').html('Query Duration: ' + (totalDuration / 1000.0) + 's');
            } else {
                $('#queryResults').addClass('errorValue');
                $('#queryResults').html('Query error | Query Duration: ' + (totalDuration / 1000.0) + 's');
            }
            $("#runBTn").removeAttr('disabled');
            $("#runBTn").removeClass("graphOpacity");
        }
        connectionQueue.End(atEnd, start);
    }

    function processResponse(format, target, id, response) {
        if (response.status == 1) {
            var tables = response.results;
            for (var j = 0; j < tables.length; j++)
                printResult(format, target, id + '_' + j, tables[j]);

        } else {
            // This inline encoder hack is intended to use html's &#nnnn; character encoding to
            // properly escape characters that would otherwise mean something as html
            // -- including angle brackets and such that are commonly used to suggest that the
            // user correct their ddl grammar. Angle-bracketed place-holders were being
            // rendered as invisible meaningless html tags.
            // See http://stackoverflow.com/questions/18749591/encode-html-entities-in-javascript#18750001
            var encodedStatus = response.statusstring.replace(/[\u00A0-\u9999<>\&]/gim,
                function(i) { return '&#'+i.charCodeAt(0)+';'; });
            target.append('Error: ' + encodedStatus + '\r\n');
        }
    }

    function printResult(format, target, id, table) {
        switch (format.toUpperCase()) {
            case 'CSV'.toUpperCase():
                printCSV(target, id, table);
                break;
            case 'MONOSPACE':
                printMonoSpace(target, id, table);
                 break;
            default:
                printGrid(target, id, table);
                break;
        }
    }

    function isUpdateResult(table) {
        return ((table.schema[0].name.length == 0 || table.schema[0].name == "modified_tuples") && table.data.length == 1 && table.schema.length == 1 && table.schema[0].type == 6);
    }

    function applyFormat(val) {
        // Formatting for explain proc.  Only format on objects that have a replace function
        if (null != val && val.replace != null) {
            val = val.replace(/\t/g, '    ');
            val = val.replace(/ /g, ' ');
            val = val.replace(/\n/g, '
');
        }
        return val;
    }

    function lPadZero(v, len) {
        // return a string left padded with zeros to length 'len'
        v = v + "";
        if (v.length < len) {
            v = Array(len - v.length + 1).join("0") + v;
        }
        return v;
    }

    function printGrid(target, id, table) {
        var src = '

';
        if (isUpdateResult(table))
            src += 'modified_tuples	';
        else {
            for (var j = 0; j < table.schema.length; j++)
                src += '' + (table.schema[j].name == "" ? ("Column " + (j + 1)) : table.schema[j].name) + '	';
        }
        src += '

';
        for (var j = 0; j < table.data.length; j++) {
            src += '
';
            for (var k = 0; k < table.data[j].length; k++) {
                var val = table.data[j][k];
                var typ = table.schema[k].type;
                if (typ == 11) {
                    var us = val % 1000;
                    var dt = new Date(val / 1000);
                    val = lPadZero(dt.getUTCFullYear(), 4) + "-"
                        + lPadZero((dt.getUTCMonth()) + 1, 2) + "-"
                        + lPadZero(dt.getUTCDate(), 2) + " "
                        + lPadZero(dt.getUTCHours(), 2) + ":"
                        + lPadZero(dt.getUTCMinutes(), 2) + ":"
                        + lPadZero(dt.getUTCSeconds(), 2) + "."
                        + lPadZero((dt.getUTCMilliseconds()) * 1000 + us, 6);
                    typ = 9;  //code for varchar
                }
                val = applyFormat(val);
                src += '' + val + '	';
            }
            src += '
';
        }
        src += '

';
        $(target).append(src);
        sorttable.makeSortable(document.getElementById('table_'+id));
    }

    function printMonoSpace(target, id, table) {
        if (isUpdateResult(table)) {
            $(target).append('\r\n\r\n(' + table.data[0][0] + ' row(s) affected)\r\n\r\n');
            return;
        }
        var src = '';
        for (var j = 0; j
 0) src += '\t';
            src += table.schema[j].name;
        }
        src += '
\r\n';
        for (var j = 0; j < table.data.length; j++) {
            for (var k = 0; k
 0) src += '\t';
                src += table.data[j][k];
            }
            src += '
\r\n';
        }
        src += '
\r\n(' + j + ' row(s) affected)\r\n\r\n

';
        $(target).append(src);
    }

    function printCSV(target, id, table) {
        if (isUpdateResult(table)) {
            $(target).append('\r\n\r\n(' + table.data[0][0] + ' row(s) affected)\r\n\r\n');
            return;
        }
        var src = '<pr>';
        var colModeData = [];
        for (var j = 0; j
 0) src += ', ';
            src += table.schema[j].name;
        }
        src += '
\r\n';
        for (var j = 0; j < table.data.length; j++) {
            for (var k = 0; k
 0) src += ', ';
                src += table.data[j][k];
            }
            src += '
\r\n';
        }
        src += '
\r\n(' + j + ' row(s) affected)\r\n\r\n</pr>

';
        $(target).append(src);
    }

    this.execute = executeMethod;
}
<|endoftext|>