<commit_before>(function(){

    if(typeof Merquery == "undefined" ) {
        Merquery = {};
    }

    Merquery.renderResults = function (response) {
        Merquery.showLoad();
        Merquery.ShowMessage(response);

        Merquery.Util.log(response);

        $('#result').empty();
        $('#breadcrumbs').empty();
        Merquery.BreadCrumbs.displayBreadcrumbs();

        var values = [[]];
        var fields = response.result.schema.fields;
        var data = [];
        var crumbs = Merquery.BreadCrumbs.crumbs;
        rowCount = response.result.totalRows;
        Merquery.SchemaManager.makeSchema(fields);

        if (response.result.rows) {
            $.each(response.result.rows, function (j, row) {
                var thisData = {};
                for (var prop in schema) {
                    if (schema.hasOwnProperty(prop)) {
                        for (var i = 0; i < fields.length; i++) {
                            if (fields[i].name == prop) {
                                thisData[fields[i].name] = row.f[i].v;
                            }
                        }
                    }
                }
                data.push(thisData);
            });
        }

        //Appends table header
        var thTag = $("

");
        var trTag = $("

");
        for(var i=0; i < fields.length; i++) {
            var header = $("	");
            header.append(getDisplayName(schema[fields[i].name].fieldName));
            trTag.append(header);
            thTag.append(trTag);
        }
        $('#result').append(thTag);

        Merquery.Util.log(result);
        Merquery.Util.log("DATA FROM SERVER");
        Merquery.Util.log(data);

        //Appends data to the table
        for(var i=0; i < data.length; i++){
            var test = data[i];
            var row = $("

");
            for (var j = 0; j < fields.length; j++) {
                if(test.hasOwnProperty(fields[j].name)){
                    var column = $("	");
                    var field = $("");
                    var fieldName = fields[j].name;
                    field.attr("href", "javascript:void(0)");
                    //field.data(schema[fieldName], test[fields[j].name]); //field.data("emailmd5", email);
                    field.text(test[fields[j].name]);                //field.text(emailMD5);

                    field.data("queryField", fields[j].name);            //field.data("queryField", "CRM_EmailMD5");
                    field.data("value", test[fields[j].name]);
                    field.data("type", fields[j].type);

                    var fieldValue = field.data("value");
                    var userValues;
                    field.click(function () {
                        userValues = {
                            queryField: $(this).data("queryField"),
                            input: $(this).data("value"),
                            querytype: $(this).data("type")
                        };

                        if (Merquery.BreadCrumbs.checkForDuplicateInputs(userValues)) {
                            crumbs.push(userValues);
                            Merquery.Queries.runQuery(crumbs);
                        }
                    });

                    // switch the commented line to return to old database
                    //if(fields[j].name == "CRM_EmailMD5") {
                    if (fields[j].name == "Demographics_emailmd5") {
                        var queryField = fields[j].name;
                       // var queryValue = test[fields[j].name];
                        var queryValue = $("");
                        queryValue.attr("href", "javascript:void(0)");
                        queryValue.data("value", test[fields[j].name]);
                        queryValue.text(test[fields[j].name]);
                        column.append(field);

                        var myButton = $("<button type = 'button' value = '"+queryValue.data("value")+"'class = 'btn btn-default btn-sm'>" +
                                        "</button>");
                        column.append(myButton);
                        myButton.data("queryfield",fields[j].name);

                        myButton.click(function () {
                            Merquery.Queries.popupQuery($(this).val(), $(this).data("queryfield"));

                        });
                    }else{
                        column.append(field);

                    }
                }
                row.append(column);
            }
            $('#result').append(row);
            Merquery.Paginator.paginate(row);
        }

            //Calls the sort function to add sorting functionality to the table
            initTable("result");
            Merquery.Paginator.initPagination();
            Merquery.Paginator.showResultsCount();
            Merquery.hideLoad();
            Merquery.showNav();

	    //Copies the entire table from result to exportedTable
            var source = document.getElementById('result');
            var destination = document.getElementById('exportedTable');
            var copy = source.cloneNode(true);
            copy.setAttribute('id', 'exportedTable');
            destination.parentNode.replaceChild(copy, destination);
            $('#exportedTable tr').removeAttr('class');
            $('#exportedTable tr').removeAttr('style');
            $('#exportedTable').attr('style', 'display: none;');

    };

    //Left navigation specifications
    $(document).ready(function () {
        $('label.tree-toggle').parent().children('ul.tree').toggle(0);
        $('.tree-toggle').click(function () {
            $(this).parent().children('ul.tree').toggle(200);
        });
        Merquery.hideLoad();

    });
    var getDisplayName =function(fieldName) {
        var name = fieldName.split("_");
        var formatted;
        if(name.length >2){
            formatted = name[1].substr(0,1).toUpperCase() + name[1].substr(1).toLowerCase();
            formatted = formatted.concat(" ", name[2].substr(0,1).toUpperCase()+name[2].substr(1).toLowerCase());
        }
        else{
            formatted = name[1].substr(0,1).toUpperCase() + name[1].substr(1).toLowerCase();
        }
        return formatted;
    }

    var createSchema = function(data) {
        var fields = data.schema.fields;
        var list = {};
        category = {};
        columnNames = {};
        type = {};
        schema = {};
        for(var i=0; i<fields.length; i++) {

        var originalCategoryName = fields[i].name;

        var categoryIndex = originalCategoryName.indexOf("_");
        var categoryName = originalCategoryName.substr(0, categoryIndex);
        var fieldName = originalCategoryName.substr(categoryIndex + 1);

        schema[originalCategoryName] = {
            displayName: getDisplayName(originalCategoryName),
            type: fields[i].type,
            fieldName: originalCategoryName
        };

          if(!category[categoryName]) {
            category[categoryName] = [];
          }
          if(!columnNames[categoryName]) {
             columnNames[categoryName] = [];
          }
          if(!type[categoryName]) {
             type[categoryName] = [];
          }
          category[categoryName].push(schema[originalCategoryName].displayName);
          columnNames[categoryName].push(schema[originalCategoryName].fieldName);
          type[categoryName].push(schema[originalCategoryName].type);
          }
        Merquery.Util.log("category " + category);
        Merquery.Util.log( category);
        var tbodyTag = $("

");
        for(var prop in category) {
            if(category.hasOwnProperty(prop)) {
                var accordionTag= $("

")
                var divider = $("

");
                var labelTag = $("");
                labelTag.append(""+prop+ '
');
                tbodyTag.append(labelTag);

                var databaseCoumns = columnNames[prop];
                var columnHeaders  = category[prop];
                var columnType = type[prop];
                for(var i =0; i< columnHeaders.length; i++){
                    var trTag = $("

");
                    var tdTag = $("	");
                    if(columnHeaders[i] == "Gender"){
                        tdTag.append(columnHeaders[i]);
                        trTag.append(tdTag);
                        var radioTag;
                        var selectTag = $("<select id='genderSelect' class='input-box'></select>");
                        radioTag = $("	");
                        radioTag.attr("id", columnHeaders[i]);
                        for(var k=0; k < gender.values.length; k++){
                           var optionTag = $("<option></option>");
                           optionTag.attr("value", gender.values[k]);
                           optionTag.append(gender.displayName[k]);
                           selectTag.append(optionTag);
                          }
                        radioTag.append(selectTag);
                        trTag.append(radioTag);
                    }else{
                        var preTag = $("	")
                        var inputTag = $("<input class='input-box' type='text'>");
                        inputTag.attr("id", columnHeaders[i]);
                        inputTag.attr("queryfield", databaseCoumns[i]);
                        inputTag.attr("type", columnType[i]);
                        inputTag.attr("onkeypress", "Merquery.handle(event)");
                        preTag.append(inputTag);
                        tdTag.append(columnHeaders[i]);
                        trTag.append(tdTag);
                        trTag.append(preTag);
                    }
                    accordionTag.append(trTag);
                    tbodyTag.append(accordionTag);

                }
                tbodyTag.append(divider);
            }
        }
        $('#navigationBar').append(tbodyTag);
        Merquery.Util.log(navigationBar);
        Merquery.initAccordion();

    }

    var gender = {
        type: 'radio',
        values: ['u','m', 'f','-1'],
        displayName: ['Not Specified','Male', 'Female','Unknown']
    }

    //Create schema functionality
    $(document).ready(function() {
        var getSchema = function() {
            Merquery.Queries.standardQuery("washington", "Demographics_city", 1, createSchema);
        };
        setTimeout(function () {
            Merquery.AuthenticationManager.auth(getSchema);
        }, 4000);

    });

    //Exports the data in the table to an xls file
    $(document).ready(function () {
        $("#export").click(function (e) {
        if(result.firstChild != null){
                $('#exportedTable').removeAttr('style');
                window.open('data:application/vnd.ms-excel,' + encodeURIComponent(exportedTable.innerText));
                $('#exportedTable').attr('style', 'display: none;');
                e.preventDefault();

            }
        });
    });

    //deciding how many results to show
    //http://stackoverflow.com/questions/17127572/bootstrap-dropdown-get-value-of-selected-item
    $(document).on('click', '.dropdown-menu li a', function() {
        selText = $(this).text();
        $('#dLabel').html(selText + '<span class="caret"');
    });

    Merquery.getLimit= function (){
        if (typeof selText == "undefined") {
            selText = 10;
        }
        return selText;
        }

})();

<commit_msg>Updated Export Button Fix<commit_after>(function(){

    if(typeof Merquery == "undefined" ) {
        Merquery = {};
    }

    Merquery.renderResults = function (response) {
        Merquery.showLoad();
        Merquery.ShowMessage(response);

        Merquery.Util.log(response);

        $('#result').empty();
        $('#breadcrumbs').empty();
        Merquery.BreadCrumbs.displayBreadcrumbs();

        var values = [[]];
        var fields = response.result.schema.fields;
        var data = [];
        var crumbs = Merquery.BreadCrumbs.crumbs;
        rowCount = response.result.totalRows;
        Merquery.SchemaManager.makeSchema(fields);

        if (response.result.rows) {
            $.each(response.result.rows, function (j, row) {
                var thisData = {};
                for (var prop in schema) {
                    if (schema.hasOwnProperty(prop)) {
                        for (var i = 0; i < fields.length; i++) {
                            if (fields[i].name == prop) {
                                thisData[fields[i].name] = row.f[i].v;
                            }
                        }
                    }
                }
                data.push(thisData);
            });
        }

        //Appends table header
        var thTag = $("

");
        var trTag = $("

");
        for(var i=0; i < fields.length; i++) {
            var header = $("	");
            header.append(getDisplayName(schema[fields[i].name].fieldName));
            trTag.append(header);
            thTag.append(trTag);
        }
        $('#result').append(thTag);

        Merquery.Util.log(result);
        Merquery.Util.log("DATA FROM SERVER");
        Merquery.Util.log(data);

        //Appends data to the table
        for(var i=0; i < data.length; i++){
            var test = data[i];
            var row = $("

");
            for (var j = 0; j < fields.length; j++) {
                if(test.hasOwnProperty(fields[j].name)){
                    var column = $("	");
                    var field = $("");
                    var fieldName = fields[j].name;
                    field.attr("href", "javascript:void(0)");
                    //field.data(schema[fieldName], test[fields[j].name]); //field.data("emailmd5", email);
                    field.text(test[fields[j].name]);                //field.text(emailMD5);

                    field.data("queryField", fields[j].name);            //field.data("queryField", "CRM_EmailMD5");
                    field.data("value", test[fields[j].name]);
                    field.data("type", fields[j].type);

                    var fieldValue = field.data("value");
                    var userValues;
                    field.click(function () {
                        userValues = {
                            queryField: $(this).data("queryField"),
                            input: $(this).data("value"),
                            querytype: $(this).data("type")
                        };

                        if (Merquery.BreadCrumbs.checkForDuplicateInputs(userValues)) {
                            crumbs.push(userValues);
                            Merquery.Queries.runQuery(crumbs);
                        }
                    });

                    // switch the commented line to return to old database
                    //if(fields[j].name == "CRM_EmailMD5") {
                    if (fields[j].name == "Demographics_emailmd5") {
                        var queryField = fields[j].name;
                       // var queryValue = test[fields[j].name];
                        var queryValue = $("");
                        queryValue.attr("href", "javascript:void(0)");
                        queryValue.data("value", test[fields[j].name]);
                        queryValue.text(test[fields[j].name]);
                        column.append(field);

                        var myButton = $("<button type = 'button' value = '"+queryValue.data("value")+"'class = 'btn btn-default btn-sm'>" +
                                        "</button>");
                        column.append(myButton);
                        myButton.data("queryfield",fields[j].name);

                        myButton.click(function () {
                            Merquery.Queries.popupQuery($(this).val(), $(this).data("queryfield"));

                        });
                    }else{
                        column.append(field);

                    }
                }
                row.append(column);
            }
            $('#result').append(row);
            Merquery.Paginator.paginate(row);
        }

            //Calls the sort function to add sorting functionality to the table
            initTable("result");
            Merquery.Paginator.initPagination();
            Merquery.Paginator.showResultsCount();
            Merquery.hideLoad();
            Merquery.showNav();

	    //Copies the entire table from result to exportedTable
            var source = document.getElementById('result');
            var destination = document.getElementById('exportedTable');
            var copy = source.cloneNode(true);
            copy.setAttribute('id', 'exportedTable');
            destination.parentNode.replaceChild(copy, destination);
            $('#exportedTable tr').removeAttr('class');
            $('#exportedTable tr').removeAttr('style');
            $('#exportedTable').attr('style', 'display: none;');

    };

    //Left navigation specifications
    $(document).ready(function () {
        $('label.tree-toggle').parent().children('ul.tree').toggle(0);
        $('.tree-toggle').click(function () {
            $(this).parent().children('ul.tree').toggle(200);
        });
        Merquery.hideLoad();

    });
    var getDisplayName =function(fieldName) {
        var name = fieldName.split("_");
        var formatted;
        if(name.length >2){
            formatted = name[1].substr(0,1).toUpperCase() + name[1].substr(1).toLowerCase();
            formatted = formatted.concat(" ", name[2].substr(0,1).toUpperCase()+name[2].substr(1).toLowerCase());
        }
        else{
            formatted = name[1].substr(0,1).toUpperCase() + name[1].substr(1).toLowerCase();
        }
        return formatted;
    }

    var createSchema = function(data) {
        var fields = data.schema.fields;
        var list = {};
        category = {};
        columnNames = {};
        type = {};
        schema = {};
        for(var i=0; i<fields.length; i++) {

        var originalCategoryName = fields[i].name;

        var categoryIndex = originalCategoryName.indexOf("_");
        var categoryName = originalCategoryName.substr(0, categoryIndex);
        var fieldName = originalCategoryName.substr(categoryIndex + 1);

        schema[originalCategoryName] = {
            displayName: getDisplayName(originalCategoryName),
            type: fields[i].type,
            fieldName: originalCategoryName
        };

          if(!category[categoryName]) {
            category[categoryName] = [];
          }
          if(!columnNames[categoryName]) {
             columnNames[categoryName] = [];
          }
          if(!type[categoryName]) {
             type[categoryName] = [];
          }
          category[categoryName].push(schema[originalCategoryName].displayName);
          columnNames[categoryName].push(schema[originalCategoryName].fieldName);
          type[categoryName].push(schema[originalCategoryName].type);
          }
        Merquery.Util.log("category " + category);
        Merquery.Util.log( category);
        var tbodyTag = $("

");
        for(var prop in category) {
            if(category.hasOwnProperty(prop)) {
                var accordionTag= $("

")
                var divider = $("

");
                var labelTag = $("");
                labelTag.append(""+prop+ '
');
                tbodyTag.append(labelTag);

                var databaseCoumns = columnNames[prop];
                var columnHeaders  = category[prop];
                var columnType = type[prop];
                for(var i =0; i< columnHeaders.length; i++){
                    var trTag = $("

");
                    var tdTag = $("	");
                    if(columnHeaders[i] == "Gender"){
                        tdTag.append(columnHeaders[i]);
                        trTag.append(tdTag);
                        var radioTag;
                        var selectTag = $("<select id='genderSelect' class='input-box'></select>");
                        radioTag = $("	");
                        radioTag.attr("id", columnHeaders[i]);
                        for(var k=0; k < gender.values.length; k++){
                           var optionTag = $("<option></option>");
                           optionTag.attr("value", gender.values[k]);
                           optionTag.append(gender.displayName[k]);
                           selectTag.append(optionTag);
                          }
                        radioTag.append(selectTag);
                        trTag.append(radioTag);
                    }else{
                        var preTag = $("	")
                        var inputTag = $("<input class='input-box' type='text'>");
                        inputTag.attr("id", columnHeaders[i]);
                        inputTag.attr("queryfield", databaseCoumns[i]);
                        inputTag.attr("type", columnType[i]);
                        inputTag.attr("onkeypress", "Merquery.handle(event)");
                        preTag.append(inputTag);
                        tdTag.append(columnHeaders[i]);
                        trTag.append(tdTag);
                        trTag.append(preTag);
                    }
                    accordionTag.append(trTag);
                    tbodyTag.append(accordionTag);

                }
                tbodyTag.append(divider);
            }
        }
        $('#navigationBar').append(tbodyTag);
        Merquery.Util.log(navigationBar);
        Merquery.initAccordion();

    }

    var gender = {
        type: 'radio',
        values: ['u','m', 'f','-1'],
        displayName: ['Not Specified','Male', 'Female','Unknown']
    }

    //Create schema functionality
    $(document).ready(function() {
        var getSchema = function() {
            Merquery.Queries.standardQuery("washington", "Demographics_city", 1, createSchema);
        };
        setTimeout(function () {
            Merquery.AuthenticationManager.auth(getSchema);
        }, 4000);

    });

    //Exports the data in the table to an xls file
    $(document).ready(function () {
        $("#export").click(function (e) {
        if(result.firstChild != null){
                $('#exportedTable').removeAttr('style');
                //window.open('data:application/vnd.ms-excel,' + encodeURIComponent(exportedTable.innerText));
                var encodedUri = encodeURIComponent(exportedTable.innerText);
                //var encodedUri = encodeURI(exportedTable);
                var uri = 'data:application/vnd.ms-excel,';
                var link = document.createElement("a");
                link.setAttribute("href", uri + encodedUri);
                link.setAttribute("download", "MerQueryData.xls");

                link.click();
                //console.log("in here");
                //tableToExcel(exportedTable, 'W3C Example Table');
                //var result = "data:application/vnd.ms-excel," + encodeURIComponent(exportedTable.innerText);
                //this.href = result;
                //this.download = "my-custom-filename.xls";
                //return true;
                $('#exportedTable').attr('style', 'display: none;');
                //e.preventDefault();

            }
        });
    });

    //deciding how many results to show
    //http://stackoverflow.com/questions/17127572/bootstrap-dropdown-get-value-of-selected-item
    $(document).on('click', '.dropdown-menu li a', function() {
        selText = $(this).text();
        $('#dLabel').html(selText + '<span class="caret"');
    });

    Merquery.getLimit= function (){
        if (typeof selText == "undefined") {
            selText = 10;
        }
        return selText;
        }

})();

<|endoftext|>


<commit_before>'use strict';

angular.module('copayApp.directives')
  .directive('validAddress', ['$rootScope',
    function($rootScope) {

      var bitcore = require('bitcore');
      var Address = bitcore.Address;
      var bignum = bitcore.Bignum;

      return {
        require: 'ngModel',
        link: function(scope, elem, attrs, ctrl) {
          var validator = function(value) {
            var uri = copay.HDPath.parseBitcoinURI(value);

            // Is this a payment protocol URI (BIP-72)?
            if (uri && uri.merchant) {
              scope.wallet.fetchPaymentTx(uri.merchant, function(err, merchantData) {
                var balance = $rootScope.availableBalance;
                var available = +(balance * config.unitToSatoshi).toFixed(0);

                if ((err && err.message === 'No unspent outputs.')
                    || available < +merchantData.total) {
                  ctrl.$setValidity('validAddress', false);
                  return;
                }

                if (err) {
                  if (scope._resetPayPro) scope._resetPayPro();
                  ctrl.$setValidity('validAddress', false);
                  return;
                }

                var expires = new Date(merchantData.pr.pd.expires * 1000);
                var memo = merchantData.pr.pd.memo;
                var payment_url = merchantData.pr.pd.payment_url;
                var total = merchantData.total;

                if (typeof total === 'string') {
                  total = bignum(total, 10).toBuffer({
                    endian: 'little',
                    size: 1
                  });
                }

                total = bignum
                  .fromBuffer(total, {
                    endian: 'little',
                    size: 1
                  })
                  .toString(10);

                // XXX There needs to be a better way to do this:
                total = +total / config.unitToSatoshi;

                // XXX Pretty much all of this code accesses the raw DOM. It's
                // very bad, there's probably a better, more angular-y way to
                // do things here.

                var address = angular.element(
                  document.querySelector('input#address'));

                var amount = angular.element(
                  document.querySelector('input#amount'));
                amount.val(total);
                if (+merchantData.total !== 0) {
                  amount.attr('disabled', true);
                }

                var sendto = angular.element(document
                  .querySelector('div.send-note > p[ng-class]:first-of-type'));
                sendto.html(sendto.html() + '
Server: ' + memo);

                var tamount = angular.element(document
                  .querySelector('div.send-note > p[ng-class]:nth-of-type(2)'));
                var ca = merchantData.pr.ca
                  || 'Untrusted';
                tamount.attr('class',
                  tamount.attr('class').replace(' hidden', ''))
                tamount.html(total + ' (CA: ' + ca
                  + '. Expires: '
                  + expires.toISOString()
                  + ')');

                var submit = angular.element(
                  document.querySelector('button[type=submit]'));
                submit.attr('disabled', false);

                var sendall = angular.element(
                  document.querySelector('[title="Send all funds"]'));
                sendall.attr('class', sendall.attr('class') + ' hidden');

                // Reset all the changes from the payment protocol weirdness.
                // XXX Bad hook. Find a better more angular-y way of doing this.
                // This will also closure scope every variable above forever.
                if (!scope._resetPayPro) {
                  scope._resetPayPro = function() {
                    var val = address.val();
                    var uri = copay.HDPath.parseBitcoinURI(val || '');
                    if (!uri || !uri.merchant) {
                      if (amount.attr('disabled')) {
                        amount.val('');
                        amount.attr('disabled', false);
                      }
                      sendto.html(sendto.html().replace(/
Server:.*$/, ''));
                      if (!/hidden/.test(tamount.attr('class'))) {
                        tamount.attr(tamount.attr('class') + ' hidden');
                      }
                      if (~tamount.html().indexOf('(CA: ')) {
                        tamount.html('');
                      }
                      if (!submit.attr('disabled')) {
                        submit.attr('disabled', true);
                      }
                      if (/ hidden$/.test(sendall.attr('class'))) {
                        sendall.attr('class',
                          sendall.attr('class').replace(' hidden', ''));
                      }
                    }
                    // TODO: Check paymentRequest expiration,
                    // delete if beyond expiration date.
                  };
                  scope.$watch('address',scope._resetPayPro);
                }

                ctrl.$setValidity('validAddress', true);

                // XXX With PayPro, since amount is already filled in among
                // other field oddities, the form is always invalid. Make it
                // valid.
                scope.sendForm.$valid = true;
                scope.sendForm.$invalid = false;
                scope.sendForm.$pristine = true;

                scope.sendForm.address.$valid = true;
                scope.sendForm.address.$invalid = false;
                scope.sendForm.address.$pristine = true;

                scope.sendForm.amount.$valid = true;
                scope.sendForm.amount.$invalid = false;
                scope.sendForm.amount.$pristine = true;
              });

              ctrl.$setValidity('validAddress', true);

              return 'Merchant: '+ uri.merchant;
            }

            var a = new Address(value);
            ctrl.$setValidity('validAddress', a.isValid() && a.network().name === config.networkName);
            return value;
          };

          ctrl.$parsers.unshift(validator);
          ctrl.$formatters.unshift(validator);
        }
      };
    }
  ])
  .directive('enoughAmount', ['$rootScope',
    function($rootScope) {
      var bitcore = require('bitcore');
      var feeSat = Number(bitcore.TransactionBuilder.FEE_PER_1000B_SAT);
      return {
        require: 'ngModel',
        link: function(scope, element, attrs, ctrl) {
          var val = function(value) {
            var availableBalanceNum = Number(($rootScope.availableBalance * config.unitToSatoshi).toFixed(0));
            var vNum = Number((value * config.unitToSatoshi).toFixed(0)) + feeSat;
            if (typeof vNum == "number" && vNum > 0) {
              if (availableBalanceNum < vNum) {
                ctrl.$setValidity('enoughAmount', false);
                scope.notEnoughAmount = true;
              } else {
                ctrl.$setValidity('enoughAmount', true);
                scope.notEnoughAmount = null;
              }
            } else {
              scope.notEnoughAmount = null;
            }
            return value;
          }
          ctrl.$parsers.unshift(val);
          ctrl.$formatters.unshift(val);
        }
      };
    }
  ])
  .directive('walletSecret', ['walletFactory',
    function(walletFactory) {
      return {
        require: 'ngModel',
        link: function(scope, elem, attrs, ctrl) {
          var validator = function(value) {
            ctrl.$setValidity('walletSecret', Boolean(walletFactory.decodeSecret(value)));
            return value;
          };

          ctrl.$parsers.unshift(validator);
        }
      };
    }
  ])
  .directive('loading', function() {
    return {
      restrict: 'A',
      link: function($scope, element, attr) {
        var a = element.html();
        var text = attr.loading;
        element.on('click', function() {
          element.html(' ' + text + '...');
        });
        $scope.$watch('loading', function(val) {
          if (!val) {
            element.html(a);
          }
        });
      }
    }
  })
  .directive('ngFileSelect', function() {
    return {
      link: function($scope, el) {
        el.bind('change', function(e) {
          $scope.file = (e.srcElement || e.target).files[0];
          $scope.getFile();
        });
      }
    }
  })
  .directive('avatar', function($rootScope, controllerUtils) {
    return {
      link: function(scope, element, attrs) {
        var peer = JSON.parse(attrs.peer)
        var peerId = peer.peerId;
        var nick = peer.nick;
        element.addClass('video-small');
        var muted = controllerUtils.getVideoMutedStatus(peerId);
        if (true || muted) { // mute everyone for now
          element.attr("muted", true);
        }
      }
    }
  })
  .directive('contact', function() {
    return {
      restrict: 'E',
      link: function(scope, element, attrs) {
        if (!scope.wallet) return;

        var address = attrs.address;
        var contact = scope.wallet.addressBook[address];
        if (contact && !contact.hidden) {
          element.append(contact.label);
          attrs['tooltip'] = attrs.address;
        } else {
          element.append(address);
        }
      }
    };
  })
  .directive('highlightOnChange', function() {
    return {
      restrict: 'A',
      link: function(scope, element, attrs) {
        scope.$watch(attrs.highlightOnChange, function(newValue, oldValue) {
          element.addClass('highlight');
          setTimeout(function() {
            element.removeClass('highlight');
          }, 500);
        });
      }
    }
  })
  .directive('checkStrength', function() {
    return {
      replace: false,
      restrict: 'EACM',
      require: 'ngModel',
      link: function(scope, element, attrs) {

        var MIN_LENGTH = 8;
        var MESSAGES = ['Very Weak', 'Very Weak', 'Weak', 'Medium', 'Strong', 'Very Strong'];
        var COLOR = ['#dd514c', '#dd514c', '#faa732', '#faa732', '#5eb95e', '#5eb95e'];

        function evaluateMeter(password) {
          var passwordStrength = 0;
          var text;
          if (password.length > 0) passwordStrength = 1;
          if (password.length >= MIN_LENGTH) {
            if ((password.match(/[a-z]/)) && (password.match(/[A-Z]/))) {
              passwordStrength++;
            } else {
              text = ', add mixed case';
            }
            if (password.match(/\d+/)) {
              passwordStrength++;
            } else {
              if (!text) text = ', add numerals';
            }
            if (password.match(/.[!,@,#,$,%,^,&,*,?,_,~,-,(,)]/)) {
              passwordStrength++;
            } else {
              if (!text) text = ', add punctuation';
            }
            if (password.length > 12) {
              passwordStrength++;
            } else {
              if (!text) text = ', add characters';
            }
          } else {
            text = ', that\'s short';
          }
          if (!text) text = '';

          return {
            strength: passwordStrength,
            message: MESSAGES[passwordStrength] + text,
            color: COLOR[passwordStrength]
          }
        }

        scope.$watch(attrs.ngModel, function(newValue, oldValue) {
          if (newValue && newValue !== '') {
            var info = evaluateMeter(newValue);
            element.css({
              'border-color': info.color
            });
            scope[attrs.checkStrength] = info.message;
          }
        });
      }
    };
  })
  .directive('openExternal', function() {
    return {
      restrict: 'A',
      link: function(scope, element, attrs) {
        element.bind('click', function() {
          window.open('bitcoin:'+attrs.address, '_blank');
        });
      }
    }
  })
  // From https://gist.github.com/asafge/7430497
  .directive('ngReallyClick', [function() {
      return {
        restrict: 'A',
        link: function(scope, element, attrs) {
          element.bind('click', function() {
            var message = attrs.ngReallyMessage;
            if (message && confirm(message)) {
              scope.$apply(attrs.ngReallyClick);
            }
          });
        }
      }
    }
  ])
  .directive('match', function () {
    return {
      require: 'ngModel',
      restrict: 'A',
      scope: {
          match: '='
      },
      link: function(scope, elem, attrs, ctrl) {
        scope.$watch(function() {
          return (ctrl.$pristine && angular.isUndefined(ctrl.$modelValue)) || scope.match === ctrl.$modelValue;
        }, function(currentValue) {
          ctrl.$setValidity('match', currentValue);
        });
      }
    };
  })
  .directive('clipCopy', function() {
    ZeroClipboard.config({
      moviePath: '/lib/zeroclipboard/dist/ZeroClipboard.swf',
      trustedDomains: ['*'],
      allowScriptAccess: 'always',
      forceHandCursor: true
    });

    return {
      restric: 'A',
      scope: { clipCopy: '=clipCopy' },
      link: function(scope, elm) {
        var client = new ZeroClipboard(elm);

        client.on( 'ready', function(event) {
          client.on( 'copy', function(event) {
            event.clipboardData.setData('text/plain', scope.clipCopy);
          });

          client.on( 'aftercopy', function(event) {
            elm.removeClass('btn-copy').addClass('btn-copied').html('Copied!');
            setTimeout(function() {
              elm.addClass('btn-copy').removeClass('btn-copied').html('');
            }, 1000);
          });
        });

        client.on( 'error', function(event) {
          console.log( 'ZeroClipboard error of type "' + event.name + '": ' + event.message );
          ZeroClipboard.destroy();
        });
      }
    };
  });
<commit_msg>paypro: minor - comment.<commit_after>'use strict';

angular.module('copayApp.directives')
  .directive('validAddress', ['$rootScope',
    function($rootScope) {

      var bitcore = require('bitcore');
      var Address = bitcore.Address;
      var bignum = bitcore.Bignum;

      return {
        require: 'ngModel',
        link: function(scope, elem, attrs, ctrl) {
          var validator = function(value) {
            var uri = copay.HDPath.parseBitcoinURI(value);

            // Is this a payment protocol URI (BIP-72)?
            if (uri && uri.merchant) {
              scope.wallet.fetchPaymentTx(uri.merchant, function(err, merchantData) {
                var balance = $rootScope.availableBalance;
                var available = +(balance * config.unitToSatoshi).toFixed(0);

                if ((err && err.message === 'No unspent outputs.')
                    || available < +merchantData.total) {
                  // TODO: Actually display a notification window here
                  // instead of simply saying the URI is invalid.
                  ctrl.$setValidity('validAddress', false);
                  return;
                }

                if (err) {
                  if (scope._resetPayPro) scope._resetPayPro();
                  ctrl.$setValidity('validAddress', false);
                  return;
                }

                var expires = new Date(merchantData.pr.pd.expires * 1000);
                var memo = merchantData.pr.pd.memo;
                var payment_url = merchantData.pr.pd.payment_url;
                var total = merchantData.total;

                if (typeof total === 'string') {
                  total = bignum(total, 10).toBuffer({
                    endian: 'little',
                    size: 1
                  });
                }

                total = bignum
                  .fromBuffer(total, {
                    endian: 'little',
                    size: 1
                  })
                  .toString(10);

                // XXX There needs to be a better way to do this:
                total = +total / config.unitToSatoshi;

                // XXX Pretty much all of this code accesses the raw DOM. It's
                // very bad, there's probably a better, more angular-y way to
                // do things here.

                var address = angular.element(
                  document.querySelector('input#address'));

                var amount = angular.element(
                  document.querySelector('input#amount'));
                amount.val(total);
                if (+merchantData.total !== 0) {
                  amount.attr('disabled', true);
                }

                var sendto = angular.element(document
                  .querySelector('div.send-note > p[ng-class]:first-of-type'));
                sendto.html(sendto.html() + '
Server: ' + memo);

                var tamount = angular.element(document
                  .querySelector('div.send-note > p[ng-class]:nth-of-type(2)'));
                var ca = merchantData.pr.ca
                  || 'Untrusted';
                tamount.attr('class',
                  tamount.attr('class').replace(' hidden', ''))
                tamount.html(total + ' (CA: ' + ca
                  + '. Expires: '
                  + expires.toISOString()
                  + ')');

                var submit = angular.element(
                  document.querySelector('button[type=submit]'));
                submit.attr('disabled', false);

                var sendall = angular.element(
                  document.querySelector('[title="Send all funds"]'));
                sendall.attr('class', sendall.attr('class') + ' hidden');

                // Reset all the changes from the payment protocol weirdness.
                // XXX Bad hook. Find a better more angular-y way of doing this.
                // This will also closure scope every variable above forever.
                if (!scope._resetPayPro) {
                  scope._resetPayPro = function() {
                    var val = address.val();
                    var uri = copay.HDPath.parseBitcoinURI(val || '');
                    if (!uri || !uri.merchant) {
                      if (amount.attr('disabled')) {
                        amount.val('');
                        amount.attr('disabled', false);
                      }
                      sendto.html(sendto.html().replace(/
Server:.*$/, ''));
                      if (!/hidden/.test(tamount.attr('class'))) {
                        tamount.attr(tamount.attr('class') + ' hidden');
                      }
                      if (~tamount.html().indexOf('(CA: ')) {
                        tamount.html('');
                      }
                      if (!submit.attr('disabled')) {
                        submit.attr('disabled', true);
                      }
                      if (/ hidden$/.test(sendall.attr('class'))) {
                        sendall.attr('class',
                          sendall.attr('class').replace(' hidden', ''));
                      }
                    }
                    // TODO: Check paymentRequest expiration,
                    // delete if beyond expiration date.
                  };
                  scope.$watch('address',scope._resetPayPro);
                }

                ctrl.$setValidity('validAddress', true);

                // XXX With PayPro, since amount is already filled in among
                // other field oddities, the form is always invalid. Make it
                // valid.
                scope.sendForm.$valid = true;
                scope.sendForm.$invalid = false;
                scope.sendForm.$pristine = true;

                scope.sendForm.address.$valid = true;
                scope.sendForm.address.$invalid = false;
                scope.sendForm.address.$pristine = true;

                scope.sendForm.amount.$valid = true;
                scope.sendForm.amount.$invalid = false;
                scope.sendForm.amount.$pristine = true;
              });

              ctrl.$setValidity('validAddress', true);

              return 'Merchant: '+ uri.merchant;
            }

            var a = new Address(value);
            ctrl.$setValidity('validAddress', a.isValid() && a.network().name === config.networkName);
            return value;
          };

          ctrl.$parsers.unshift(validator);
          ctrl.$formatters.unshift(validator);
        }
      };
    }
  ])
  .directive('enoughAmount', ['$rootScope',
    function($rootScope) {
      var bitcore = require('bitcore');
      var feeSat = Number(bitcore.TransactionBuilder.FEE_PER_1000B_SAT);
      return {
        require: 'ngModel',
        link: function(scope, element, attrs, ctrl) {
          var val = function(value) {
            var availableBalanceNum = Number(($rootScope.availableBalance * config.unitToSatoshi).toFixed(0));
            var vNum = Number((value * config.unitToSatoshi).toFixed(0)) + feeSat;
            if (typeof vNum == "number" && vNum > 0) {
              if (availableBalanceNum < vNum) {
                ctrl.$setValidity('enoughAmount', false);
                scope.notEnoughAmount = true;
              } else {
                ctrl.$setValidity('enoughAmount', true);
                scope.notEnoughAmount = null;
              }
            } else {
              scope.notEnoughAmount = null;
            }
            return value;
          }
          ctrl.$parsers.unshift(val);
          ctrl.$formatters.unshift(val);
        }
      };
    }
  ])
  .directive('walletSecret', ['walletFactory',
    function(walletFactory) {
      return {
        require: 'ngModel',
        link: function(scope, elem, attrs, ctrl) {
          var validator = function(value) {
            ctrl.$setValidity('walletSecret', Boolean(walletFactory.decodeSecret(value)));
            return value;
          };

          ctrl.$parsers.unshift(validator);
        }
      };
    }
  ])
  .directive('loading', function() {
    return {
      restrict: 'A',
      link: function($scope, element, attr) {
        var a = element.html();
        var text = attr.loading;
        element.on('click', function() {
          element.html(' ' + text + '...');
        });
        $scope.$watch('loading', function(val) {
          if (!val) {
            element.html(a);
          }
        });
      }
    }
  })
  .directive('ngFileSelect', function() {
    return {
      link: function($scope, el) {
        el.bind('change', function(e) {
          $scope.file = (e.srcElement || e.target).files[0];
          $scope.getFile();
        });
      }
    }
  })
  .directive('avatar', function($rootScope, controllerUtils) {
    return {
      link: function(scope, element, attrs) {
        var peer = JSON.parse(attrs.peer)
        var peerId = peer.peerId;
        var nick = peer.nick;
        element.addClass('video-small');
        var muted = controllerUtils.getVideoMutedStatus(peerId);
        if (true || muted) { // mute everyone for now
          element.attr("muted", true);
        }
      }
    }
  })
  .directive('contact', function() {
    return {
      restrict: 'E',
      link: function(scope, element, attrs) {
        if (!scope.wallet) return;

        var address = attrs.address;
        var contact = scope.wallet.addressBook[address];
        if (contact && !contact.hidden) {
          element.append(contact.label);
          attrs['tooltip'] = attrs.address;
        } else {
          element.append(address);
        }
      }
    };
  })
  .directive('highlightOnChange', function() {
    return {
      restrict: 'A',
      link: function(scope, element, attrs) {
        scope.$watch(attrs.highlightOnChange, function(newValue, oldValue) {
          element.addClass('highlight');
          setTimeout(function() {
            element.removeClass('highlight');
          }, 500);
        });
      }
    }
  })
  .directive('checkStrength', function() {
    return {
      replace: false,
      restrict: 'EACM',
      require: 'ngModel',
      link: function(scope, element, attrs) {

        var MIN_LENGTH = 8;
        var MESSAGES = ['Very Weak', 'Very Weak', 'Weak', 'Medium', 'Strong', 'Very Strong'];
        var COLOR = ['#dd514c', '#dd514c', '#faa732', '#faa732', '#5eb95e', '#5eb95e'];

        function evaluateMeter(password) {
          var passwordStrength = 0;
          var text;
          if (password.length > 0) passwordStrength = 1;
          if (password.length >= MIN_LENGTH) {
            if ((password.match(/[a-z]/)) && (password.match(/[A-Z]/))) {
              passwordStrength++;
            } else {
              text = ', add mixed case';
            }
            if (password.match(/\d+/)) {
              passwordStrength++;
            } else {
              if (!text) text = ', add numerals';
            }
            if (password.match(/.[!,@,#,$,%,^,&,*,?,_,~,-,(,)]/)) {
              passwordStrength++;
            } else {
              if (!text) text = ', add punctuation';
            }
            if (password.length > 12) {
              passwordStrength++;
            } else {
              if (!text) text = ', add characters';
            }
          } else {
            text = ', that\'s short';
          }
          if (!text) text = '';

          return {
            strength: passwordStrength,
            message: MESSAGES[passwordStrength] + text,
            color: COLOR[passwordStrength]
          }
        }

        scope.$watch(attrs.ngModel, function(newValue, oldValue) {
          if (newValue && newValue !== '') {
            var info = evaluateMeter(newValue);
            element.css({
              'border-color': info.color
            });
            scope[attrs.checkStrength] = info.message;
          }
        });
      }
    };
  })
  .directive('openExternal', function() {
    return {
      restrict: 'A',
      link: function(scope, element, attrs) {
        element.bind('click', function() {
          window.open('bitcoin:'+attrs.address, '_blank');
        });
      }
    }
  })
  // From https://gist.github.com/asafge/7430497
  .directive('ngReallyClick', [function() {
      return {
        restrict: 'A',
        link: function(scope, element, attrs) {
          element.bind('click', function() {
            var message = attrs.ngReallyMessage;
            if (message && confirm(message)) {
              scope.$apply(attrs.ngReallyClick);
            }
          });
        }
      }
    }
  ])
  .directive('match', function () {
    return {
      require: 'ngModel',
      restrict: 'A',
      scope: {
          match: '='
      },
      link: function(scope, elem, attrs, ctrl) {
        scope.$watch(function() {
          return (ctrl.$pristine && angular.isUndefined(ctrl.$modelValue)) || scope.match === ctrl.$modelValue;
        }, function(currentValue) {
          ctrl.$setValidity('match', currentValue);
        });
      }
    };
  })
  .directive('clipCopy', function() {
    ZeroClipboard.config({
      moviePath: '/lib/zeroclipboard/dist/ZeroClipboard.swf',
      trustedDomains: ['*'],
      allowScriptAccess: 'always',
      forceHandCursor: true
    });

    return {
      restric: 'A',
      scope: { clipCopy: '=clipCopy' },
      link: function(scope, elm) {
        var client = new ZeroClipboard(elm);

        client.on( 'ready', function(event) {
          client.on( 'copy', function(event) {
            event.clipboardData.setData('text/plain', scope.clipCopy);
          });

          client.on( 'aftercopy', function(event) {
            elm.removeClass('btn-copy').addClass('btn-copied').html('Copied!');
            setTimeout(function() {
              elm.addClass('btn-copy').removeClass('btn-copied').html('');
            }, 1000);
          });
        });

        client.on( 'error', function(event) {
          console.log( 'ZeroClipboard error of type "' + event.name + '": ' + event.message );
          ZeroClipboard.destroy();
        });
      }
    };
  });
<|endoftext|>


<commit_before>/*
 * @copyright Copyright (c) Sematext Group, Inc. - All Rights Reserved
 *
 * @licence logparser-js is free-to-use, proprietary software.
 * THIS IS PROPRIETARY SOURCE CODE OF Sematext Group, Inc. (Sematext)
 * This source code may not be copied, reverse engineered, or altered for any purpose.
 * This source code is to be used exclusively by users and customers of Sematext.
 * Please see the full license (found in LICENSE in this distribution) for details on its license and the licenses of its dependencies.
 */
'use strict'
var yaml = require('js-yaml')
var fs = require('fs')
var moment = require('moment')
var crypto = require('crypto')
var MultiLine = require('./multiLine.js')
var geoip = null
var initJobs = []

function LogParser (fileName, options, readyCallback) {
  this.ready = false
  this.readyCallback = readyCallback
  this.options = options
  this.sources = {}
  this.load(fileName || require('path').join(__dirname, '../patterns.yml'), options)
}
function initGeoIp (err, fileName) {
  if (err) {
    this.cfg.geoIPEnabled = false
    if(this.readyCallback) {
      this.readyCallback()
      this.readyCallback = null
    }
    return
  }
  try {
    fs.statSync(fileName)
    geoip.init(fileName, {indexCache: true, checkForUpdates: true})
    this.cfg.geoIPEnabled = true
    if (this.cfg.globalTransform)
    {
      this.cfg.globalTransform = this.cfg.globalTransform.bind({
        moment: moment,
        geoip: geoip,
        enrichGeoIp: this.enrichGeoIp
      })
    }
  } catch (fsStatError) {
    this.cfg.geoIPEnabled = false
  }
  if(this.readyCallback) {
    this.readyCallback()
    this.readyCallback = null
  }
}
LogParser.prototype = {

  load: function (name, options) {
    try {
      this.cfg = yaml.load(fs.readFileSync(name, 'utf8'))
      if (this.cfg.autohash) {
        console.log('Hashing field content enabled for field names: ' + this.cfg.autohash)
      }
      // console.log(this.cfg)
      this.patterns = this.cfg.patterns
      if (options && options.whitelist) {
        this.whitelist(options.whitelist)
      }
      if (options && options.blacklist) {
        this.blacklist(options.blacklist)
      }
      // inject modules to global transform function

      if (this.cfg.geoIP && !(process.env.GEOIP_DISABLED=='true')) {
        var fileName = (process.env.MAXMIND_DB_DIR || this.cfg.maxmindDbDir) + 'GeoIPCity.dat'
        var cbInitGeoIp = null
        try {
          try {
            fs.statsSync(fileName)
            geoip = require('maxmind')
            initGeoIp.bind(this)(null, fileName)
            cbInitGeoIp = null
          } catch (fsStatsErr) {
            cbInitGeoIp = initGeoIp.bind(this)
          }
          var maxmindUpdate=require('./maxmind-update')
          this.maxmindUpdate =  maxmindUpdate(this.cfg.debug,
            (process.env.MAXMIND_DB_DIR || this.cfg.maxmindDbDir),
            cbInitGeoIp)
        } catch (err) {
          console.log(err.stack)
          if(this.readyCallback) {
            setTimeout (this.readyCallback, 0)
          }
        }
      } else {
        if (this.readyCallback)
          this.readyCallback()
      }
    } catch (e) {
      if (e.reason && e.mark) {
        console.log('Error parsing file: ' + name + ' ' + e.reason + ' line:' + e.mark.line + ' column:' + e.mark.columns)
      } else {
        console.log('Error parsing file: ' + name + ' ' + e)
      }
      this.patterns = []
      process.exit()
    } finally {
      return this.patterns
    }
  },
  whitelist: function (whitelist) {
    this.patterns = this.patterns.filter(function (e) {
      return (e.sourceName && e.sourceName.match(whitelist))
    })
  },
  blacklist: function (blacklist) {
    this.patterns = this.patterns.filter(function (e) {
      return !(e.sourceName && e.sourceName.match(blacklist))
    })
  },
  enrichGeoIp: function (parsedObject, fieldName) {
    if (!this.cfg.geoIPEnabled || !fieldName)
        return null
    if (parsedObject[fieldName]) {
      var location = geoip.getLocation(parsedObject[fieldName])
      if (location) {
        parsedObject['geoip'] = {location: [location.longitude, location.latitude], info: location}
      }
    }
  },
  getPatternsForSource: function (sourceName) {
    if (!sourceName) {
      return this.patterns // try all
    }
    var src = this.sources[sourceName]
    if (src && src.patterns) {
      return this.sources[sourceName].patterns
    }
    var exclude = []
    var include = this.patterns.filter(function (p) {
      if (sourceName && sourceName.match && sourceName.match(p.sourceName)) {
        return true
      } else {
        exclude.push(p)
      }
    })
    var patternLists = include.concat(exclude)
    // console.log('Patterns for source ' + sourceName + ' : ex:' + exclude.length + ' incl:' + include.length)
    if (!src) {
      this.sources[sourceName] = {}
    }
    this.sources[sourceName].patterns = patternLists
    return patternLists
  },
  getMultiLineReader: function (sourceName, parser) {
    if (!sourceName) {
      return this.getMultiLineReader('unknown', parser)
    }
    var src = this.sources[sourceName]
    if (src && src.reader) {
      return this.sources[sourceName].reader
    } else {
      this.sources[sourceName] = {}
      var include = this.patterns.filter(function (p) {
        if (sourceName && sourceName.match && sourceName.match(p.sourceName)) {
          return true
        }
      })
      if (include.length > 0) {
        this.sources[sourceName].reader = new MultiLine(include[0].blockStart, parser)
        return this.sources[sourceName].reader
      } else {
        this.sources[sourceName].reader = new MultiLine(/^\S+/, parser)
        return this.sources[sourceName].reader
      }
    }
  },
  hash: function hash (input) {
    var sha1 = crypto.createHash('sha1')
    sha1.update(input.toString())
    return sha1.digest('hex')
  },
  parseDate: function (strDate, dateFormat) {
    var d = null
    if (dateFormat && strDate) {
      d = moment(String(strDate).trim().replace('  ', ' '), dateFormat.trim(), true) || moment(strDate.trim().replace('  ', ' '), this.cfg.dateFormats, true)
    }
    if (d && d.isValid()) {
      return d.toDate()
    } else {
      // console.log('DATE not matched' + strDate + ' ' + dateFormat)
      return null
    }
  },
  matchPatterns: function (p, parsed, line) {
    var match = line.match(p.regex)
    if (match) {
      parsed._type = p.type
      if (p.fields && (match.length > p.fields.length)) {
        for (var i = 0; i < p.fields.length; i++) {
          var value = match[i + 1]

          // convert to number
          if (!isNaN(value) && value !== '') {
            value = Number(value)
          }
          if (this.cfg.autohash && this.cfg.autohash.test(p.fields[i])) {
            value = this.hash(value)
          }
          var fieldDefinition = p.fields[i].split(':')
          // [0] Field Name
          // [1] Field Type
          if(fieldDefinition[0] == p.geoIP) {
            this.enrichGeoIp(parsed, p.geoIP)
          }
          if (fieldDefinition[1] && (typeof value === 'string') && /number/.test(fieldDefinition[1])) {
            if (!isNaN(value) && value !== '') {
              value = Number(value)
            } else {
              value = 0
            }
          }
          if (fieldDefinition[1] && (typeof value === 'number') && /string/.test(fieldDefinition[1])) {
            value = String(value)
          }
          parsed[fieldDefinition[0]] = value
        }
        if (parsed['ts']) {
          var timestamp = this.parseDate(parsed['ts'], p.dateFormat)
          if (timestamp) {
            parsed['@timestamp'] = timestamp
          }
        }
        if (p.transform) {
          try {
            p.transform(parsed)
          } catch (ex) {
            console.log('Error in' + p.type + '.transform():' + ex)
          }
        }
        this.enrichGeoIp (p, p.geoIP)
        // remove ts field, because Elasticsearch
        // might have problems to index it
        // it could be recognized as string or data
        // depending on its content
        delete parsed.ts
        return 1
      }
    } else {
      return 0
    }
  },
  // optimize performance, by keeping last matched pattern
  // on top if the list,
  // assuming the next line will have the same format
  bubbleUp: function (plist, pos) {
    if (pos === 0) {
      return
    }
    // remove element on pos
    var tmp = plist[0]
    plist[0] = plist[pos]
    plist[pos] = tmp
  },
  parseLine: function (line, source, cbf) {
    var br = this.getMultiLineReader(source, function (data) {
        try {
          this._parseLine(data, source, cbf)
        } catch (err) {
          // console.log('Error parsing logs from ' + source +  ': ' + err + ' originalLine: ' + line)
          cbf(err, data)
        }
    }.bind(this))
    br.add(line)
  },
  globalTransform: function (source, parsed) {
    if (this.cfg.globalTransform) {
      try {
        this.cfg.globalTransform(source, parsed)
      } catch (ex) {
        console.error('Error in gloabalTransform():' + ex)
      }
    }
  },
  _parseLine: function (line, source, cbf) {
    if (line === null || line === '') {
      cbf('empty', null)
    }
    var parsed = {}
    if (this.cfg.originalLine === true)
    {
      parsed.originalLine = line
    }
    parsed['@source'] = source
    // JSON handling
    var trimedLine=line.trim()
    if (/^\[{0,1}\{.*\}\]{0,1}$/.test(trimedLine)) {
      try {
        parsed = JSON.parse(trimedLine)
        if (!(parsed['@timestamp'])) {
          if (parsed.time && parsed.time instanceof Date) {
            parsed['@timestamp'] = parsed.time
          } else if (parsed.t && parsed.t instanceof Date) {
            parsed['@timestamp'] = parsed.t
          } else if (parsed.timestamp && parsed.task_uuid) {
              // python eliot logs
              parsed['@timestamp'] = new Date(parsed.timestamp*1000)
          }else {
            parsed['@timestamp'] = new Date()
          }
        }
        if (!parsed.message && parsed.msg) {
          parsed.message = parsed.msg
        }
        // TODO JSON GeoIP enrichment
        this.globalTransform(source, parsed)
        return cbf(null, parsed)
      } catch (ex) {
        // ignore treat as text
      }
    }
    var patternList = this.getPatternsForSource(source) || this.patterns
    for (var k in patternList) {
      var patterns = patternList[k]
      for (var i = 0; i < patterns.match.length; i++) {
        if (this.matchPatterns(patterns.match[i], parsed, line)) {
          this.bubbleUp(patternList, k)
          if (!parsed._type) {
            parsed._type = patternList[k].type
          }
          if (this.gloabalTransform) {
            this.globalTransform(source, parsed)
          }
          return cbf(null, parsed)
        }
      }
    }
    return cbf('not found', {'@timestamp': new Date(), message: line, '@source': source}
    )
  }
}

module.exports = LogParser
<commit_msg>tuning handling od field types<commit_after>/*
 * @copyright Copyright (c) Sematext Group, Inc. - All Rights Reserved
 *
 * @licence logparser-js is free-to-use, proprietary software.
 * THIS IS PROPRIETARY SOURCE CODE OF Sematext Group, Inc. (Sematext)
 * This source code may not be copied, reverse engineered, or altered for any purpose.
 * This source code is to be used exclusively by users and customers of Sematext.
 * Please see the full license (found in LICENSE in this distribution) for details on its license and the licenses of its dependencies.
 */
'use strict'
var yaml = require('js-yaml')
var fs = require('fs')
var moment = require('moment')
var crypto = require('crypto')
var MultiLine = require('./multiLine.js')
var geoip = null
var initJobs = []

function LogParser (fileName, options, readyCallback) {
  this.ready = false
  this.readyCallback = readyCallback
  this.options = options
  this.sources = {}
  this.load(fileName || require('path').join(__dirname, '../patterns.yml'), options)
}
function initGeoIp (err, fileName) {
  if (err) {
    this.cfg.geoIPEnabled = false
    if(this.readyCallback) {
      this.readyCallback()
      this.readyCallback = null
    }
    return
  }
  try {
    fs.statSync(fileName)
    geoip.init(fileName, {indexCache: true, checkForUpdates: true})
    this.cfg.geoIPEnabled = true
    if (this.cfg.globalTransform)
    {
      this.cfg.globalTransform = this.cfg.globalTransform.bind({
        moment: moment,
        geoip: geoip,
        enrichGeoIp: this.enrichGeoIp
      })
    }
  } catch (fsStatError) {
    this.cfg.geoIPEnabled = false
  }
  if(this.readyCallback) {
    this.readyCallback()
    this.readyCallback = null
  }
}
LogParser.prototype = {

  load: function (name, options) {
    try {
      this.cfg = yaml.load(fs.readFileSync(name, 'utf8'))
      if (this.cfg.autohash) {
        console.log('Hashing field content enabled for field names: ' + this.cfg.autohash)
      }
      // console.log(this.cfg)
      this.patterns = this.cfg.patterns
      if (options && options.whitelist) {
        this.whitelist(options.whitelist)
      }
      if (options && options.blacklist) {
        this.blacklist(options.blacklist)
      }
      // inject modules to global transform function

      if (this.cfg.geoIP && !(process.env.GEOIP_DISABLED=='true')) {
        var fileName = (process.env.MAXMIND_DB_DIR || this.cfg.maxmindDbDir) + 'GeoIPCity.dat'
        var cbInitGeoIp = null
        try {
          try {
            fs.statsSync(fileName)
            geoip = require('maxmind')
            initGeoIp.bind(this)(null, fileName)
            cbInitGeoIp = null
          } catch (fsStatsErr) {
            cbInitGeoIp = initGeoIp.bind(this)
          }
          var maxmindUpdate=require('./maxmind-update')
          this.maxmindUpdate =  maxmindUpdate(this.cfg.debug,
            (process.env.MAXMIND_DB_DIR || this.cfg.maxmindDbDir),
            cbInitGeoIp)
        } catch (err) {
          console.log(err.stack)
          if(this.readyCallback) {
            setTimeout (this.readyCallback, 0)
          }
        }
      } else {
        if (this.readyCallback)
          this.readyCallback()
      }
    } catch (e) {
      if (e.reason && e.mark) {
        console.log('Error parsing file: ' + name + ' ' + e.reason + ' line:' + e.mark.line + ' column:' + e.mark.columns)
      } else {
        console.log('Error parsing file: ' + name + ' ' + e)
      }
      this.patterns = []
      process.exit()
    } finally {
      return this.patterns
    }
  },
  whitelist: function (whitelist) {
    this.patterns = this.patterns.filter(function (e) {
      return (e.sourceName && e.sourceName.match(whitelist))
    })
  },
  blacklist: function (blacklist) {
    this.patterns = this.patterns.filter(function (e) {
      return !(e.sourceName && e.sourceName.match(blacklist))
    })
  },
  enrichGeoIp: function (parsedObject, fieldName) {
    if (!this.cfg.geoIPEnabled || !fieldName)
        return null
    if (parsedObject[fieldName]) {
      var location = geoip.getLocation(parsedObject[fieldName])
      if (location) {
        parsedObject['geoip'] = {location: [location.longitude, location.latitude], info: location}
      }
    }
  },
  getPatternsForSource: function (sourceName) {
    if (!sourceName) {
      return this.patterns // try all
    }
    var src = this.sources[sourceName]
    if (src && src.patterns) {
      return this.sources[sourceName].patterns
    }
    var exclude = []
    var include = this.patterns.filter(function (p) {
      if (sourceName && sourceName.match && sourceName.match(p.sourceName)) {
        return true
      } else {
        exclude.push(p)
      }
    })
    var patternLists = include.concat(exclude)
    // console.log('Patterns for source ' + sourceName + ' : ex:' + exclude.length + ' incl:' + include.length)
    if (!src) {
      this.sources[sourceName] = {}
    }
    this.sources[sourceName].patterns = patternLists
    return patternLists
  },
  getMultiLineReader: function (sourceName, parser) {
    if (!sourceName) {
      return this.getMultiLineReader('unknown', parser)
    }
    var src = this.sources[sourceName]
    if (src && src.reader) {
      return this.sources[sourceName].reader
    } else {
      this.sources[sourceName] = {}
      var include = this.patterns.filter(function (p) {
        if (sourceName && sourceName.match && sourceName.match(p.sourceName)) {
          return true
        }
      })
      if (include.length > 0) {
        this.sources[sourceName].reader = new MultiLine(include[0].blockStart, parser)
        return this.sources[sourceName].reader
      } else {
        this.sources[sourceName].reader = new MultiLine(/^\S+/, parser)
        return this.sources[sourceName].reader
      }
    }
  },
  hash: function hash (input) {
    var sha1 = crypto.createHash('sha1')
    sha1.update(input.toString())
    return sha1.digest('hex')
  },
  parseDate: function (strDate, dateFormat) {
    var d = null
    if (dateFormat && strDate) {
      d = moment(String(strDate).trim().replace('  ', ' '), dateFormat.trim(), true) || moment(strDate.trim().replace('  ', ' '), this.cfg.dateFormats, true)
    }
    if (d && d.isValid()) {
      return d.toDate()
    } else {
      // console.log('DATE not matched' + strDate + ' ' + dateFormat)
      return null
    }
  },
  matchPatterns: function (p, parsed, line) {
    var match = line.match(p.regex)
    if (match) {
      parsed._type = p.type
      if (p.fields && (match.length > p.fields.length)) {
        for (var i = 0; i < p.fields.length; i++) {
          var value = match[i + 1]

          // convert to number
          if (!isNaN(value) && value !== '') {
            value = Number(value)
          }
          if (this.cfg.autohash && this.cfg.autohash.test(p.fields[i])) {
            value = this.hash(value)
          }
          if (!p.fieldDefinition) {
            p.fieldDefinition = {}
          }
          var fieldDefinition =  p.fieldDefinition[i]
          if (!p.fieldDefinition[i]) {
            fieldDefinition = p.fieldDefinition[i] = p.fields[i].split(':')
          }

          // fieldDefinition = p.fields[i].split(':')
          // [0] Field Name
          // [1] Field Type
          if(fieldDefinition[0] == p.geoIP) {
            this.enrichGeoIp(parsed, p.geoIP)
          }
          if (fieldDefinition[1] && (typeof value === 'string') && /number/.test(fieldDefinition[1])) {
            if (!isNaN(value) && value !== '') {
              value = Number(value)
            } else {
              value = 0
            }
          }
          if (fieldDefinition[1] && (typeof value === 'number') && /string/.test(fieldDefinition[1])) {
            value = String(value)
          }
          parsed[fieldDefinition[0]] = value
        }
        if (parsed['ts']) {
          var timestamp = this.parseDate(parsed['ts'], p.dateFormat)
          if (timestamp) {
            parsed['@timestamp'] = timestamp
          }
        }
        if (p.transform) {
          try {
            p.transform(parsed)
          } catch (ex) {
            console.log('Error in' + p.type + '.transform():' + ex)
          }
        }
        this.enrichGeoIp (p, p.geoIP)
        // remove ts field, because Elasticsearch
        // might have problems to index it
        // it could be recognized as string or data
        // depending on its content
        delete parsed.ts
        return 1
      }
    } else {
      return 0
    }
  },
  // optimize performance, by keeping last matched pattern
  // on top if the list,
  // assuming the next line will have the same format
  bubbleUp: function (plist, pos) {
    if (pos === 0) {
      return
    }
    // remove element on pos
    var tmp = plist[0]
    plist[0] = plist[pos]
    plist[pos] = tmp
  },
  parseLine: function (line, source, cbf) {
    var br = this.getMultiLineReader(source, function (data) {
        try {
          this._parseLine(data, source, cbf)
        } catch (err) {
          // console.log('Error parsing logs from ' + source +  ': ' + err + ' originalLine: ' + line)
          cbf(err, data)
        }
    }.bind(this))
    br.add(line)
  },
  globalTransform: function (source, parsed) {
    if (this.cfg.globalTransform) {
      try {
        this.cfg.globalTransform(source, parsed)
      } catch (ex) {
        console.error('Error in gloabalTransform():' + ex)
      }
    }
  },
  _parseLine: function (line, source, cbf) {
    if (line === null || line === '') {
      cbf('empty', null)
    }
    var parsed = {}
    if (this.cfg.originalLine === true)
    {
      parsed.originalLine = line
    }
    parsed['@source'] = source
    // JSON handling
    var trimedLine=line.trim()
    if (/^\[{0,1}\{.*\}\]{0,1}$/.test(trimedLine)) {
      try {
        parsed = JSON.parse(trimedLine)
        if (!(parsed['@timestamp'])) {
          if (parsed.time && parsed.time instanceof Date) {
            parsed['@timestamp'] = parsed.time
          } else if (parsed.t && parsed.t instanceof Date) {
            parsed['@timestamp'] = parsed.t
          } else if (parsed.timestamp && parsed.task_uuid) {
              // python eliot logs
              parsed['@timestamp'] = new Date(parsed.timestamp*1000)
          }else {
            parsed['@timestamp'] = new Date()
          }
        }
        if (!parsed.message && parsed.msg) {
          parsed.message = parsed.msg
        }
        // TODO JSON GeoIP enrichment
        this.globalTransform(source, parsed)
        return cbf(null, parsed)
      } catch (ex) {
        // ignore treat as text
      }
    }
    var patternList = this.getPatternsForSource(source) || this.patterns
    for (var k in patternList) {
      var patterns = patternList[k]
      for (var i = 0; i < patterns.match.length; i++) {
        if (this.matchPatterns(patterns.match[i], parsed, line)) {
          this.bubbleUp(patternList, k)
          if (!parsed._type) {
            parsed._type = patternList[k].type
          }
          if (this.gloabalTransform) {
            this.globalTransform(source, parsed)
          }
          return cbf(null, parsed)
        }
      }
    }
    return cbf('not found', {'@timestamp': new Date(), message: line, '@source': source}
    )
  }
}

module.exports = LogParser
<|endoftext|>


<commit_before>'use strict';
/**
 * This object contains all the handlers to use for this provider
 */

var jsforce = require('jsforce');
var async = require('async');

var config = require('../config/configuration.js');
var retrieve = require('./helpers/retrieve.js');
var upload = require('./helpers/upload.js');

var globalConn = new jsforce.Connection({
  oauth2 : {
    clientId : config.salesforceId,
    clientSecret : config.salesforceSecret,
    redirectUri : config.providerUrl + "/init/callback"
  }
});

var redirectToService = function(callbackUrl, cb) {
  // Redirect user to provider consentment page
  cb(null, globalConn.oauth2.getAuthorizationUrl({ scope : 'api id refresh_token' }), {});
};

var retrieveTokens = function(reqParams, storedParams, cb) {
  var conn = new jsforce.Connection({
    oauth2 : {
      clientId : config.salesforceId,
      clientSecret : config.salesforceSecret,
      redirectUri : config.providerUrl + "/init/callback"
    }
  });

  conn.authorize(reqParams.code, function(err, userInfo) {
    if(err) {
      return cb(err);
    }

    var data = {
      accessToken: conn.accessToken,
      refreshToken: conn.refreshToken,
      instanceUrl: conn.instanceUrl
    };

    console.log(conn);

    conn.sobject("User").retrieve(userInfo.id, function(err, user) {
      if(err) {
        return cb(err);
      }

      cb(null, user.Username, data);
    });
  });
};

var updateAccount = function(serviceData, cursor, queues, cb) {
  var conn = new jsforce.Connection({
    oauth2 : {
      clientId : config.salesforceId,
      clientSecret : config.salesforceSecret,
      redirectUri : config.providerUrl + "/init/callback"
    },
    accessToken: serviceData.accessToken,
    refreshToken: serviceData.refreshToken,
    instanceUrl: serviceData.instanceUrl
  });

  async.waterfall([
    function retrieveContacts(cb) {
      retrieve(conn, cursor, 500, cb);
    },
    function addContactsToQueue(newCursor, contacts, cb) {
      contacts.forEach(function(contact) {
        contact.title = contact.identifier = serviceData.instanceUrl + "/" + contact.Id;

        if(contact.IsDeleted) {
          queues.deletion.push(contact);
        }
        else {
          queues.addition.push(contact);
        }
      });

      serviceData.accessToken = conn.accessToken;
      cb(null, newCursor, serviceData);
    }
  ], cb);
};

var additionQueueWorker = function(job, cb) {
  console.log("UPLOADING", job.task.identifier);
  upload(job.task, job.anyfetchClient, cb);
};

var deletionQueueWorker = function(job, cb) {
  console.log("DELETING", job.task.identifier);
  job.anyfetchClient.deleteDocumentByIdentifier(job.task.identifier, function(err) {
    if(err && err.toString().match(/expected 204 "No Content", got 404 "Not Found"/i)) {
      err = null;
    }

    cb(err);
  });
};

additionQueueWorker.concurrency = config.maxConcurrency;
deletionQueueWorker.concurrency = config.maxConcurrency;

module.exports = {
  connectFunctions: {
    redirectToService: redirectToService,
    retrieveTokens: retrieveTokens
  },
  updateAccount: updateAccount,
  workers: {
    addition: additionQueueWorker,
    deletion: deletionQueueWorker
  },

  config: config
};<commit_msg>Remove console.log<commit_after>'use strict';
/**
 * This object contains all the handlers to use for this provider
 */

var jsforce = require('jsforce');
var async = require('async');

var config = require('../config/configuration.js');
var retrieve = require('./helpers/retrieve.js');
var upload = require('./helpers/upload.js');

var globalConn = new jsforce.Connection({
  oauth2 : {
    clientId : config.salesforceId,
    clientSecret : config.salesforceSecret,
    redirectUri : config.providerUrl + "/init/callback"
  }
});

var redirectToService = function(callbackUrl, cb) {
  // Redirect user to provider consentment page
  cb(null, globalConn.oauth2.getAuthorizationUrl({ scope : 'api id refresh_token' }), {});
};

var retrieveTokens = function(reqParams, storedParams, cb) {
  var conn = new jsforce.Connection({
    oauth2 : {
      clientId : config.salesforceId,
      clientSecret : config.salesforceSecret,
      redirectUri : config.providerUrl + "/init/callback"
    }
  });

  conn.authorize(reqParams.code, function(err, userInfo) {
    if(err) {
      return cb(err);
    }

    var data = {
      accessToken: conn.accessToken,
      refreshToken: conn.refreshToken,
      instanceUrl: conn.instanceUrl
    };

    conn.sobject("User").retrieve(userInfo.id, function(err, user) {
      if(err) {
        return cb(err);
      }

      cb(null, user.Username, data);
    });
  });
};

var updateAccount = function(serviceData, cursor, queues, cb) {
  var conn = new jsforce.Connection({
    oauth2 : {
      clientId : config.salesforceId,
      clientSecret : config.salesforceSecret,
      redirectUri : config.providerUrl + "/init/callback"
    },
    accessToken: serviceData.accessToken,
    refreshToken: serviceData.refreshToken,
    instanceUrl: serviceData.instanceUrl
  });

  async.waterfall([
    function retrieveContacts(cb) {
      retrieve(conn, cursor, 500, cb);
    },
    function addContactsToQueue(newCursor, contacts, cb) {
      contacts.forEach(function(contact) {
        contact.title = contact.identifier = serviceData.instanceUrl + "/" + contact.Id;

        if(contact.IsDeleted) {
          queues.deletion.push(contact);
        }
        else {
          queues.addition.push(contact);
        }
      });

      serviceData.accessToken = conn.accessToken;
      cb(null, newCursor, serviceData);
    }
  ], cb);
};

var additionQueueWorker = function(job, cb) {
  console.log("UPLOADING", job.task.identifier);
  upload(job.task, job.anyfetchClient, cb);
};

var deletionQueueWorker = function(job, cb) {
  console.log("DELETING", job.task.identifier);
  job.anyfetchClient.deleteDocumentByIdentifier(job.task.identifier, function(err) {
    if(err && err.toString().match(/expected 204 "No Content", got 404 "Not Found"/i)) {
      err = null;
    }

    cb(err);
  });
};

additionQueueWorker.concurrency = config.maxConcurrency;
deletionQueueWorker.concurrency = config.maxConcurrency;

module.exports = {
  connectFunctions: {
    redirectToService: redirectToService,
    retrieveTokens: retrieveTokens
  },
  updateAccount: updateAccount,
  workers: {
    addition: additionQueueWorker,
    deletion: deletionQueueWorker
  },

  config: config
};<|endoftext|>


<commit_before>//Das Array in dem alle Layers gespeichert sind.
drawing = [];

//Ein Assoziatives array  'Layer_name'->Layer_index
layers = [];

//Canvas Dimensiones -> Sollte automatisch gehen
canvas_breite = 1000;
canvas_hoehe = 600;

//Standartwerte, werden fr den ersten Frame verwendet, dann autoscale und redraw
view_x = 150;
view_y = canvas_hoehe/2;
view_scale = 12;

//Variablen in denen die Dimension des Modells gespeichert werden
model_min_x = 0;
model_max_x = 0;
model_min_y = 0;
model_max_y = 0;

//Bem ersten Frame soll hinterher die Skala und der Ursprung angepasst werden
auto_scale = true;

function activate_controls(){

	add_layer_auswahl();

	document.getElementById('canvas').addEventListener('DOMMouseScroll', function(e)
		{
			if (e.detail > 0){
				view_scale = view_scale - 2;
				redraw();
			} else {
				view_scale = view_scale+ 2;
				redraw();
			}
			e.preventDefault();
		}, false);

	document.getElementById('canvas').addEventListener('mousewheel', function(e)
		{
			if (e.wheelDelta < 0){
				view_scale = view_scale - 1;
				redraw();
			} else {
				view_scale = view_scale+ 1;
				redraw();
			}
			e.preventDefault();
		}, false);

	document.getElementById('canvas').addEventListener('mousedown', function(e){
			mousemove_x = e.clientX;
			mousemove_y = e.clientY;
			document.getElementById('canvas').addEventListener('mousemove', mousemove, false);
		},false);
	document.getElementById('canvas').addEventListener('mouseup', function(e){
			document.getElementById('canvas').removeEventListener('mousemove', mousemove, false);
		}, false);

	$('.layer_auswahl').change(function(e){
			var layer_id = e.currentTarget.id.substr(6,(e.currentTarget.id.length-1));
			if (layers[layer_id].active == true){
			layers[layer_id].active = false;
			}
			else
			layers[layer_id].active = true;
			redraw();
	});
	if (auto_scale)
	do_auto_scale();
	sprinkler_starten();
}

function mousemove(e){
	view_x = view_x - (mousemove_x - e.clientX);
	view_y = view_y - (mousemove_y - e.clientY);
	mousemove_x = e.clientX;
	mousemove_y = e.clientY;
	redraw();
}

function do_auto_scale(){
	auto_scale = false;
	ctx.beginPath();
	ctx.arc(x(0)-2.5,y(0)-2.5,5,0,(Math.PI/180)*360,true);
	ctx.stroke();
	var breite = model_max_x - model_min_x;
	var scale_nach_breite = (canvas_breite-10)/breite;
	var hoehe = model_max_y - model_min_y;
	var scale_nach_hoehe = (canvas_hoehe-10)/hoehe;
	if (scale_nach_hoehe < scale_nach_breite) {
		view_scale = scale_nach_hoehe;
	} else {
		view_scale = scale_nach_breite;
	}
	view_x = - scale(model_min_x)+5;
	view_y = (- scale(model_min_y))/2 + 5;
	redraw();
}

function redraw(){
	ctx.clearRect(0, 0, 1000, 600);
	//Fr jedes Layer
	//var i = 3;
	//console.log( available_blocks);
	for (var i = 0; drawing.length > i; i++){
		if (layers[i].active){
			for (var a = 0; drawing[i].length > a; a++){
				element_zeichnen(drawing[i][a]);
			}
		}
	}
}

function add_layer_auswahl(){
	var text = ""
	for (var m = 0; m < layers.length;m++){
		text = text + "<input type='checkbox' checked='checked' class='layer_auswahl' id='layer-"+m+"' value='"+layers[m].name+"' />"+layers[m].name+"
";
	}
	$("body").append(text);
}

function draw(){
	redraw();
	activate_controls();
}

function element_zeichnen(element){
	if (element.type == "LINE"){
		draw_line(element);
		return
	}
	if (element.type == "XLINE"){
		draw_line(element);
		return
	}
	if (element.type == "ARC"){
		draw_arc(element);
		return
	}
	if (element.type == "CIRCLE"){
		draw_circle(element);
		return
	}
	if (element.type == "TEXT"){
		draw_text(element);
		return
	}
	if (element.type == "MTEXT"){
		draw_text(element);
		return
	}
	if (element.type == "INSERT"){
		draw_insert(element);
		return
	}

}

function draw_insert(element){
var i = 0;
	//console.log(element.insert_block);
	while (element.insert_block != available_blocks[i].handle.block_name){
		i++;
		if (available_blocks.length == i){
		console.warn("Block nicht gefunden: " + element.insert_block );
		return
		}
	}
	temp_elemente = available_blocks[i].elemente;

	for (var a = 0; a < temp_elemente.length; a++){
		temp_elemente[a].type = temp_elemente[a].entity_typ;
		if ( typeof temp_elemente[a].x_scale == "undefined" )
		temp_elemente[a].x_scale = 1;
		if ( typeof temp_elemente[a].y_scale == "undefined" )
		temp_elemente[a].y_scale = 1;

		if ( typeof temp_elemente[a].org_x1 == "undefined" ) {
			temp_elemente[a].org_x1 = temp_elemente[a].x1;
			}
		//console.log(temp_elemente[a].start_winkel);
		//console.log(winkel_in_rad);
		temp_elemente[a].x1 = element.x1 + rotate_x(temp_elemente[a].org_x1,temp_elemente[a].org_y1,element.start_winkel,temp_elemente[a].x_scale);

		if ( typeof temp_elemente[a].org_x2 == "undefined" ) {
			temp_elemente[a].org_x2 = temp_elemente[a].x2;
			}
		temp_elemente[a].x2 = element.x1 + rotate_x(temp_elemente[a].org_x2,temp_elemente[a].org_y2,element.start_winkel,temp_elemente[a].x_scale);

		if ( typeof temp_elemente[a].org_y1 == "undefined" ) {
			temp_elemente[a].org_y1 = temp_elemente[a].y1;
			}
		temp_elemente[a].y1 = element.y1 + rotate_y(temp_elemente[a].org_x1,temp_elemente[a].org_y1,element.start_winkel,temp_elemente[a].y_scale);

		if ( typeof temp_elemente[a].org_y2 == "undefined" ) {
			temp_elemente[a].org_y2 = temp_elemente[a].y2;
			}
		temp_elemente[a].y2 = element.y1 + rotate_y(temp_elemente[a].org_x2,temp_elemente[a].org_y2,element.start_winkel,temp_elemente[a].y_scale);
		//console.log(temp_elemente[a]);
		// if ((typeof temp_elemente[a].org_start_winkel == "undefined") && (element.start_winkel)){
			// temp_elemente[a].org_start_winkel = temp_elemente[a].start_winkel;
			// temp_elemente[a].start_winkel = temp_elemente[a].start_winkel + element.start_winkel;
		// }
		// if ((typeof temp_elemente[a].org_end_winkel == "undefined") && (element.end_winkel)){
			// temp_elemente[a].org_end_winkel = temp_elemente[a].end_winkel;
			// temp_elemente[a].end_winkel = temp_elemente[a].end_winkel + element.start_winkel;
		// }
		element_zeichnen(temp_elemente[a]);
	}
}

function rotate_x(x_org,y_org,a_deg,s){
	if (!a_deg) return x_org;
	a_rad = (a_deg) * Math.PI / 180;
	return x_org*Math.cos(a_rad) - y_org*Math.sin(a_rad);
}

function rotate_y(x_org,y_org,a_deg,s){
	if (!a_deg) return y_org;
	a_rad = (a_deg) * Math.PI / 180;
	return x_org*Math.sin(a_rad) + y_org*Math.cos(a_rad);
}

function draw_text(element){
	if ((element.attachment_p == 2)||(element.attachment_p == 5)||(element.attachment_p == 8)){
		ctx.textAlign = "center";
	}
	if ((element.attachment_p == 1)||(element.attachment_p == 4)||(element.attachment_p == 7)){
		ctx.textAlign = "left";
	}
	if ((element.attachment_p == 3)||(element.attachment_p == 6)||(element.attachment_p == 9)){
		ctx.textAlign = "right";
	}
	if (element.attachment_p <= 3){
		ctx.textBaseline = "bottom";
	}
	if (element.attachment_p >= 7 ){
		ctx.textBaseline = "top";
	}
	if ((element.attachment_p < 7 ) && (element.attachment_p > 3 )){
		ctx.textBaseline = "middle";
	}
	ctx.font = scale(element.radius) + "px Times New Roman";
	ctx.fillStyle = "Black";
	ctx.fillText(element.text, x(element.x1), y(element.y1));
}

function draw_arc(element){
	ctx.beginPath();
	console.log(element.start_winkel+" bis "+element.end_winkel+" org:"+element.org_start_winkel+" bis "+element.org_end_winkel );
	var clockwise = false; //Aus Header auslesen!
	ctx.arc(x(element.x1),y(element.y1),scale(element.radius),(Math.PI/180)*(180+element.start_winkel),(Math.PI/180)*(180+element.end_winkel),clockwise);
	ctx.stroke();
}

function draw_circle(element){
	element.start_winkel = 0;
	element.end_winkel = 360;
	draw_arc(element);
}

function draw_line(element){
	ctx.beginPath();
	ctx.moveTo(x(element.x1),y(element.y1));
	ctx.lineTo(x(element.x2),y(element.y2));
	ctx.stroke();
}

// function dxf_polyline(daten){
	// while (daten[0][0] != "0"){
		// //Polyline_Daten interpretieren
		// daten.shift();
	// }
	// ctx.beginPath();
	// daten.shift();
	// var vertex_daten = Array();
	// while (daten.length > 0){
		// if (daten[0][0] == "0"){
			// dxf_vertex(vertex_daten);
			// vertex_daten = Array()
		// } else {
			// vertex_daten.push(daten[0])
		// }
		// daten.shift();
	// }
// }

// function dxf_vertex(daten){
	// daten = dxf_group_codes_parse(daten);
	// ctx.lineTo(x(daten['10']),y(daten['20']));
	// ctx.stroke();
// }

function x(wert){
	if (wert < model_min_x) {
		model_min_x = wert;
	};
	if (wert > model_max_x) {
		model_max_x = wert;
	};
	return scale(wert)+view_x;
}

function y(wert){
	if (wert < model_min_y) model_min_y = wert;
	if (wert > model_max_y) model_max_y = wert;
	return  - (scale(wert))+view_y;
}

function scale(wert){
	return wert*view_scale;
}
<commit_msg>Teilweise fix für Arc Probleme(#20) Bei Inserts noch Probleme<commit_after>//Das Array in dem alle Layers gespeichert sind.
drawing = [];

//Ein Assoziatives array  'Layer_name'->Layer_index
layers = [];

//Canvas Dimensiones -> Sollte automatisch gehen
canvas_breite = 1000;
canvas_hoehe = 600;

//Standartwerte, werden fr den ersten Frame verwendet, dann autoscale und redraw
view_x = 150;
view_y = canvas_hoehe/2;
view_scale = 12;

//Variablen in denen die Dimension des Modells gespeichert werden
model_min_x = 0;
model_max_x = 0;
model_min_y = 0;
model_max_y = 0;

//Bem ersten Frame soll hinterher die Skala und der Ursprung angepasst werden
auto_scale = true;

function activate_controls(){

	add_layer_auswahl();

	document.getElementById('canvas').addEventListener('DOMMouseScroll', function(e)
		{
			if (e.detail > 0){
				view_scale = view_scale - 2;
				redraw();
			} else {
				view_scale = view_scale+ 2;
				redraw();
			}
			e.preventDefault();
		}, false);

	document.getElementById('canvas').addEventListener('mousewheel', function(e)
		{
			if (e.wheelDelta < 0){
				view_scale = view_scale - 1;
				redraw();
			} else {
				view_scale = view_scale+ 1;
				redraw();
			}
			e.preventDefault();
		}, false);

	document.getElementById('canvas').addEventListener('mousedown', function(e){
			mousemove_x = e.clientX;
			mousemove_y = e.clientY;
			document.getElementById('canvas').addEventListener('mousemove', mousemove, false);
		},false);
	document.getElementById('canvas').addEventListener('mouseup', function(e){
			document.getElementById('canvas').removeEventListener('mousemove', mousemove, false);
		}, false);

	$('.layer_auswahl').change(function(e){
			var layer_id = e.currentTarget.id.substr(6,(e.currentTarget.id.length-1));
			if (layers[layer_id].active == true){
			layers[layer_id].active = false;
			}
			else
			layers[layer_id].active = true;
			redraw();
	});
	if (auto_scale)
	do_auto_scale();
	sprinkler_starten();
}

function mousemove(e){
	view_x = view_x - (mousemove_x - e.clientX);
	view_y = view_y - (mousemove_y - e.clientY);
	mousemove_x = e.clientX;
	mousemove_y = e.clientY;
	redraw();
}

function do_auto_scale(){
	auto_scale = false;
	ctx.beginPath();
	ctx.arc(x(0)-2.5,y(0)-2.5,5,0,(Math.PI/180)*360,true);
	ctx.stroke();
	var breite = model_max_x - model_min_x;
	var scale_nach_breite = (canvas_breite-10)/breite;
	var hoehe = model_max_y - model_min_y;
	var scale_nach_hoehe = (canvas_hoehe-10)/hoehe;
	if (scale_nach_hoehe < scale_nach_breite) {
		view_scale = scale_nach_hoehe;
	} else {
		view_scale = scale_nach_breite;
	}
	view_x = - scale(model_min_x)+5;
	view_y = (- scale(model_min_y))/2 + 5;
	redraw();
}

function redraw(){
	ctx.clearRect(0, 0, canvas_breite, canvas_hoehe);
	//Fr jedes Layer
	//var i = 3;
	//console.log( available_blocks);
	for (var i = 0; drawing.length > i; i++){
		if (layers[i].active){
			for (var a = 0; drawing[i].length > a; a++){
				element_zeichnen(drawing[i][a]);
			}
		}
	}
}

function add_layer_auswahl(){
	var text = ""
	for (var m = 0; m < layers.length;m++){
		text = text + "<input type='checkbox' checked='checked' class='layer_auswahl' id='layer-"+m+"' value='"+layers[m].name+"' />"+layers[m].name+"
";
	}
	$("body").append(text);
}

function draw(){
	redraw();
	activate_controls();
}

function element_zeichnen(element){
	if (element.type == "LINE"){
		draw_line(element);
		return
	}
	if (element.type == "XLINE"){
		draw_line(element);
		return
	}
	if (element.type == "ARC"){
		draw_arc(element);
		return
	}
	if (element.type == "CIRCLE"){
		draw_circle(element);
		return
	}
	if (element.type == "TEXT"){
		draw_text(element);
		return
	}
	if (element.type == "MTEXT"){
		draw_text(element);
		return
	}
	if (element.type == "INSERT"){
		draw_insert(element);
		return
	}

}

function draw_insert(element){
var i = 0;
	//console.log(element.insert_block);
	while (element.insert_block != available_blocks[i].handle.block_name){
		i++;
		if (available_blocks.length == i){
		console.warn("Block nicht gefunden: " + element.insert_block );
		return
		}
	}
	temp_elemente = available_blocks[i].elemente;

	for (var a = 0; a < temp_elemente.length; a++){
		temp_elemente[a].type = temp_elemente[a].entity_typ;
		if ( typeof temp_elemente[a].x_scale == "undefined" )
		temp_elemente[a].x_scale = 1;
		if ( typeof temp_elemente[a].y_scale == "undefined" )
		temp_elemente[a].y_scale = 1;

		if ( typeof temp_elemente[a].org_x1 == "undefined" ) {
			temp_elemente[a].org_x1 = temp_elemente[a].x1;
			}
		//console.log(temp_elemente[a].start_winkel);
		//console.log(winkel_in_rad);
		temp_elemente[a].x1 = element.x1 + rotate_x(temp_elemente[a].org_x1,temp_elemente[a].org_y1,element.start_winkel,temp_elemente[a].x_scale);

		if ( typeof temp_elemente[a].org_x2 == "undefined" ) {
			temp_elemente[a].org_x2 = temp_elemente[a].x2;
			}
		temp_elemente[a].x2 = element.x1 + rotate_x(temp_elemente[a].org_x2,temp_elemente[a].org_y2,element.start_winkel,temp_elemente[a].x_scale);

		if ( typeof temp_elemente[a].org_y1 == "undefined" ) {
			temp_elemente[a].org_y1 = temp_elemente[a].y1;
			}
		temp_elemente[a].y1 = element.y1 + rotate_y(temp_elemente[a].org_x1,temp_elemente[a].org_y1,element.start_winkel,temp_elemente[a].y_scale);

		if ( typeof temp_elemente[a].org_y2 == "undefined" ) {
			temp_elemente[a].org_y2 = temp_elemente[a].y2;
			}
		temp_elemente[a].y2 = element.y1 + rotate_y(temp_elemente[a].org_x2,temp_elemente[a].org_y2,element.start_winkel,temp_elemente[a].y_scale);

		//Probleme mit Winkeln und Gedrehten oder Gespiegelten Blcken

		//console.log(temp_elemente[a]);
		// if ((typeof temp_elemente[a].org_start_winkel == "undefined") && (element.start_winkel)){
			// temp_elemente[a].org_start_winkel = temp_elemente[a].start_winkel;
			// temp_elemente[a].start_winkel = temp_elemente[a].start_winkel + element.start_winkel;
		// }
		// if ((typeof temp_elemente[a].org_end_winkel == "undefined") && (element.end_winkel)){
			// temp_elemente[a].org_end_winkel = temp_elemente[a].end_winkel;
			// temp_elemente[a].end_winkel = temp_elemente[a].end_winkel + element.start_winkel;
		// }
		element_zeichnen(temp_elemente[a]);
	}
}

function rotate_x(x_org,y_org,a_deg,s){
	if (!a_deg) return x_org;
	a_rad = (a_deg) * Math.PI / 180;
	return x_org*Math.cos(a_rad) - y_org*Math.sin(a_rad);
}

function rotate_y(x_org,y_org,a_deg,s){
	if (!a_deg) return y_org;
	a_rad = (a_deg) * Math.PI / 180;
	return x_org*Math.sin(a_rad) + y_org*Math.cos(a_rad);
}

function draw_text(element){
	if ((element.attachment_p == 2)||(element.attachment_p == 5)||(element.attachment_p == 8)){
		ctx.textAlign = "center";
	}
	if ((element.attachment_p == 1)||(element.attachment_p == 4)||(element.attachment_p == 7)){
		ctx.textAlign = "left";
	}
	if ((element.attachment_p == 3)||(element.attachment_p == 6)||(element.attachment_p == 9)){
		ctx.textAlign = "right";
	}
	if (element.attachment_p <= 3){
		ctx.textBaseline = "bottom";
	}
	if (element.attachment_p >= 7 ){
		ctx.textBaseline = "top";
	}
	if ((element.attachment_p < 7 ) && (element.attachment_p > 3 )){
		ctx.textBaseline = "middle";
	}
	ctx.font = scale(element.radius) + "px Times New Roman";
	ctx.fillStyle = "Black";
	ctx.fillText(element.text, x(element.x1), y(element.y1));
}

function draw_arc(element){
	ctx.beginPath();
	//console.log(element.start_winkel+" bis "+element.end_winkel+" org:"+element.org_start_winkel+" bis "+element.org_end_winkel );
	var anticlockwise = true; //Aus Header auslesen!
	ctx.arc(x(element.x1),y(element.y1),scale(element.radius),(Math.PI/180)*(360-element.start_winkel),(Math.PI/180)*(360-element.end_winkel),anticlockwise);
	ctx.stroke();
}

function draw_circle(element){
	element.start_winkel = 0;
	element.end_winkel = 360;
	draw_arc(element);
}

function draw_line(element){
	ctx.beginPath();
	ctx.moveTo(x(element.x1),y(element.y1));
	ctx.lineTo(x(element.x2),y(element.y2));
	ctx.stroke();
}

// function dxf_polyline(daten){
	// while (daten[0][0] != "0"){
		// //Polyline_Daten interpretieren
		// daten.shift();
	// }
	// ctx.beginPath();
	// daten.shift();
	// var vertex_daten = Array();
	// while (daten.length > 0){
		// if (daten[0][0] == "0"){
			// dxf_vertex(vertex_daten);
			// vertex_daten = Array()
		// } else {
			// vertex_daten.push(daten[0])
		// }
		// daten.shift();
	// }
// }

// function dxf_vertex(daten){
	// daten = dxf_group_codes_parse(daten);
	// ctx.lineTo(x(daten['10']),y(daten['20']));
	// ctx.stroke();
// }

function x(wert){
	if (wert < model_min_x) {
		model_min_x = wert;
	};
	if (wert > model_max_x) {
		model_max_x = wert;
	};
	return scale(wert)+view_x;
}

function y(wert){
	if (wert < model_min_y) model_min_y = wert;
	if (wert > model_max_y) model_max_y = wert;
	return  - (scale(wert))+view_y;
}

function scale(wert){
	return wert*view_scale;
}
<|endoftext|>


<commit_before>$(function () {

    /*******
     * NAV *
     *******/

    $("nav a.nav-current-section").click (function () {
        $("nav ul").toggle ();
        return false;
    });

    /*****************
     * SMOOTH SCROLL *
     *****************/

    $('a.navigate-document').click(function () {
        $('html, body').animate({
            scrollTop: $( $.attr(this, 'href') ).offset().top
        }, {
            duration: 500,
            easing: 'swing'
        });
        return false;
    });
});
<commit_msg>Last useless whitespace removed ftw<commit_after>$(function () {

    /*******
     * NAV *
     *******/

    $("nav a.nav-current-section").click (function () {
        $("nav ul").toggle ();
        return false;
    });

    /*****************
     * SMOOTH SCROLL *
     *****************/

    $('a.navigate-document').click(function () {
        $('html, body').animate({
            scrollTop: $( $.attr(this, 'href') ).offset().top
        }, {
            duration: 500,
            easing: 'swing'
        });
        return false;
    });
});
<|endoftext|>