<commit_before>(function($, $TD, TD){
  //
  // Variable: Current highlighted column jQuery object.
  //
  var highlightedColumnEle;

  //
  // Variable: Currently highlighted tweet jQuery object.
  //
  var highlightedTweetEle;

  //
  // Function: Initializes TweetD*ck events. Called after the website app is loaded.
  //
  var initializeTweetDck = function(){
    // Settings button hook
    $("[data-action='settings-menu']").click(function(){
      setTimeout(function(){
        var menu = $(".js-dropdown-content").children("ul").first();
        if (menu.length === 0)return;

        menu.children(".drp-h-divider").last().after([
          '
'+$TD.brandName+' settings
',
          '
'+$TD.brandName+' plugins
',
          '

'
        ].join(""));

        var buttons = menu.children("[data-std]");

        buttons.on("click", "a", function(){
          var action = $(this).attr("data-action");

          if (action === "td-settings"){
            $TD.openSettingsMenu();
          }
          else if (action === "td-plugins"){
            $TD.openPluginsMenu();
          }
        });

        buttons.hover(function(){
          $(this).addClass("is-selected");
        }, function(){
          $(this).removeClass("is-selected");
        });
      }, 0);
    });

    // Notification handling
    $.subscribe("/notifications/new", function(obj){
      for(let index = obj.items.length-1; index >= 0; index--){
        onNewTweet(obj.column, obj.items[index]);
      }
    });

    // Setup video element replacement and fix missing target in user links
    new MutationObserver(function(){
      $("video").each(function(){
        $(this).parent().replaceWith("► Open video in browser");
      });

      $("a[rel='user']").attr("target", "_blank");
    }).observe($(".js-app-columns")[0], {
      childList: true,
      subtree: true
    });

    // Finish init and load plugins
    $TD.loadFontSizeClass(TD.settings.getFontSize());
    $TD.loadNotificationHeadContents(getNotificationHeadContents());

    window.TD_APP_READY = true;

    if (window.TD_PLUGINS){
      window.TD_PLUGINS.onReady();
    }
  };

  //
  // Function: Prepends code at the beginning of a function. If the prepended function returns true, execution of the original function is cancelled.
  //
  var prependToFunction = function(func, extension){
    return function(){
      return extension.apply(this, arguments) === true ? undefined : func.apply(this, arguments);
    };
  };

  //
  // Function: Appends code at the end of a function.
  //
  var appendToFunction = function(func, extension){
    return function(){
      var res = func.apply(this, arguments);
      extension.apply(this, arguments);
      return res;
    };
  };

  //
  // Function: Event callback for a new tweet.
  //
  var onNewTweet = function(column, tweet){
    if (column.model.getHasNotification()){
      var html = $(tweet.render({
        withFooter: false,
        withTweetActions: false,
        withMediaPreview: true,
        isMediaPreviewOff: true,
        isMediaPreviewSmall: false,
        isMediaPreviewLarge: false
      }));

      html.css("border", "0");
      html.find("footer").last().remove(); // apparently withTweetActions breaks for certain tweets, nice

      var url = html.find("time").first().children("a").first().attr("href") || "";

      $TD.onTweetPopup(html.html(), url, tweet.text.length); // TODO column
    }
    else if (column.model.getHasSound()){
      $TD.onTweetSound(); // TODO disable original
    }
  };

  //
  // Function: Retrieves the tags to be put into  for notification HTML code.
  //
  var getNotificationHeadContents = function(){
    var tags = [];

    $(document.head).children("link[rel='stylesheet'],meta[charset],meta[http-equiv]").each(function(){
      tags.push($(this)[0].outerHTML);
    });

    return tags.join("");
  };

  //
  // Block: Observe the app
 element and initialize TweetD*ck whenever possible.
  //
  var app = $("body").children(".js-app");

  new MutationObserver(function(){
    if (window.TD_APP_READY && app.hasClass("is-hidden")){
      window.TD_APP_READY = false;
    }
    else if (!window.TD_APP_READY && !app.hasClass("is-hidden")){
      initializeTweetDck();
    }
  }).observe(app[0], {
    attributes: true,
    attributeFilter: [ "class" ]
  });

  //
  // Block: Hook into settings object to detect when the settings change.
  //
  TD.settings.setFontSize = appendToFunction(TD.settings.setFontSize, function(name){
    $TD.loadFontSizeClass(name);
  });

  TD.settings.setTheme = appendToFunction(TD.settings.setTheme, function(){
    setTimeout(function(){
      $TD.loadNotificationHeadContents(getNotificationHeadContents());
    }, 0);
  });

  //
  // Block: Force popup notification settings.
  //
  TD.controller.notifications.hasNotifications = function(){
    return true;
  };

  TD.controller.notifications.isPermissionGranted = function(){
    return true;
  };

  //
  // Block: Expand shortened links on hover or display tooltip.
  //
  (function(){
    var cutStart = function(str, search){
      return str.startsWith(search) ? str.substr(search.length) : str;
    };

    var prevMouseX = -1, prevMouseY = -1;
    var tooltipTimer, tooltipDisplayed;

    $(document.body).delegate("a[data-full-url]", "mouseenter mouseleave mousemove", function(e){
      var me = $(this);

      if (e.type === "mouseenter"){
        var text = me.text();

        if (text.charCodeAt(text.length-1) !== 8230){ // horizontal ellipsis
          return;
        }

        if ($TD.expandLinksOnHover){
          tooltipTimer = window.setTimeout(function(){
            var expanded = me.attr("data-full-url");
            expanded = cutStart(expanded, "https://");
            expanded = cutStart(expanded, "http://");
            expanded = cutStart(expanded, "www.");

            me.attr("td-prev-text", text);
            me.text(expanded);
          }, 200);
        }
        else{
          tooltipTimer = window.setTimeout(function(){
            $TD.displayTooltip(me.attr("data-full-url"), false);
            tooltipDisplayed = true;
          }, 400);
        }
      }
      else if (e.type === "mouseleave"){
        if ($TD.expandLinksOnHover){
          var prevText = me.attr("td-prev-text");

          if (prevText){
            me.text(prevText);
          }
        }

        window.clearTimeout(tooltipTimer);

        if (tooltipDisplayed){
          tooltipDisplayed = false;
          $TD.displayTooltip(null, false);
        }
      }
      else if (e.type === "mousemove"){
        if (tooltipDisplayed && (prevMouseX !== e.clientX || prevMouseY !== e.clientY)){
          $TD.displayTooltip(me.attr("data-full-url"), false);
          prevMouseX = e.clientX;
          prevMouseY = e.clientY;
        }
      }
    });
  })();

  //
  // Block: Allow bypassing of t.co in context menus.
  //
  $(document.body).delegate("a", "contextmenu", function(){
    $TD.setLastRightClickedLink($(this).attr("data-full-url") || "");
  });

  //
  // Block: Hook into the notification sound effect.
  //
  (function(){
    var soundEle = document.getElementById("update-sound");

    soundEle.play = prependToFunction(soundEle.play, function(){
      return $TD.muteNotifications;
    });
  })();

  /* TODO document.getElementById("update-sound").play = function(){
    $TD.onTweetSound();
  };*/

  //
  // Block: Update highlighted column.
  //
  app.delegate("section", "mouseenter mouseleave", function(e){
    if (e.type === "mouseenter"){
      highlightedColumnEle = $(this);
    }
    else if (e.type === "mouseleave"){
      highlightedColumnEle = null;
    }
  });

  //
  // Block: Copy tweet address and update highlighted tweet.
  //
  (function(){
    var lastTweet = "";

    var updateHighlightedTweet = function(link, embeddedLink){
      if (lastTweet !== link){
        $TD.setLastHighlightedTweet(link, embeddedLink);
        lastTweet = link;
      }
    };

    app.delegate("article.js-stream-item", "mouseenter mouseleave", function(e){
      if (e.type === "mouseenter"){
        highlightedTweetEle = $(this);

        var link = $(this).find("time").first().children("a").first();
        var embedded = $(this).find(".quoted-tweet[data-tweet-id]").first();

        updateHighlightedTweet(link.length > 0 ? link.attr("href") : "", embedded.length > 0 ? embedded.find(".account-link").first().attr("href")+"/status/"+embedded.attr("data-tweet-id") : "");
      }
      else if (e.type === "mouseleave"){
        highlightedTweetEle = null;
        updateHighlightedTweet("", "");
      }
    });
  })();

  //
  // Block: Paste images when tweeting.
  //
  (function(){
    var lastPasteElement;
    var prevScrollTop;

    var getScroller = function(){
      return $(".js-drawer").find(".js-compose-scroller").first().children().first();
    };

    var clickUpload = function(){
      var button = $(".js-add-image-button").first();

      var scroller = getScroller();
      prevScrollTop = scroller.scrollTop();

      scroller.scrollTop(0);
      scroller.scrollTop(button.offset().top); // scrolls the button into view

      var buttonPos = button.children().first().offset(); // finds the camera icon offset
      $TD.clickUploadImage(Math.floor(buttonPos.left), Math.floor(buttonPos.top));
    };

    $(".js-app").delegate(".js-compose-text,.js-reply-tweetbox", "paste", function(){
      lastPasteElement = $(this);
      $TD.tryPasteImage();
    });

    window.TDGF_tryPasteImage = function(){
      if (lastPasteElement){
        var parent = lastPasteElement.parent();

        if (parent.siblings(".js-add-image-button").length === 0){
          var pop = parent.closest(".js-inline-reply,.rpl").find(".js-inline-compose-pop,.js-reply-popout");

          if (pop.length === 0){
            lastPasteElement = null;
            return;
          }

          pop.click();

          var drawer = $(".js-drawer");
          var counter = 0;

          var interval = setInterval(function(){
            if (drawer.offset().left >= 195){
              clickUpload();
              clearInterval(interval);
            }
            else if (++counter >= 10){
              clearInterval(interval);
            }
          }, 51);
        }
        else{
          clickUpload();
        }

        lastPasteElement = null;
      }
    };

    window.TDGF_tryPasteImageFinish = function(){
      setTimeout(function(){
        getScroller().scrollTop(prevScrollTop);
        $(".js-drawer").find(".js-compose-text").first()[0].focus();
      }, 10);
    };
  })();

  //
  // Block: Support for extra mouse buttons.
  //
  window.TDGF_onMouseClickExtra = function(button){
    if (button === 1){ // back button
      var inlineComposer, drawerComposer, modal;

      if ((modal = $("#open-modal")).is(":visible")){
        modal.find("a[rel=dismiss]").click();
      }
      else if ((inlineComposer = $(".js-inline-compose-close")).length === 1){
        inlineComposer.click();
      }
      else if (highlightedColumnEle && highlightedColumnEle.closest(".js-column").is(".is-shifted-1")){
        highlightedColumnEle.find(".js-column-back").first().click();
      }
      else if ((drawerComposer = $(".js-app-content.is-open .js-drawer-close:visible")).length === 1){
        drawerComposer.click();
      }
      else{
        $(".js-column-back").click();
      }
    }
    else if (button === 2){ // forward button
      if (highlightedTweetEle){
        highlightedTweetEle.children().first().click();
      }
    }
  };

  //
  // Block: Fix scheduled tweets not showing up sometimes.
  //
  $(document).on("dataTweetSent", function(e, data){
    if (data.response.state && data.response.state === "scheduled"){
      var column = Object.values(TD.controller.columnManager.getAll()).find(column => column.model.state.type === "scheduled");

      if (column){
        setTimeout(function(){
          column.reloadTweets();
        }, 1000);
      }
    }
  });

  //
  // Block: Inject custom CSS and layout into the page.
  //
  (function(){
    var styleOfficial = document.createElement("style");
    document.head.appendChild(styleOfficial);

    styleOfficial.sheet.insertRule("a[data-full-url] { word-break: break-all; }", 0); // break long urls
    styleOfficial.sheet.insertRule(".column-nav-link .attribution { position: absolute; }", 0); // fix cut off account names
    styleOfficial.sheet.insertRule(".txt-base-smallest .badge-verified:before { height: 13px !important; }", 0); // fix cut off badge icon
    styleOfficial.sheet.insertRule(".keyboard-shortcut-list { vertical-align: top; }", 0); // fix keyboard navigation alignment

    if ($TD.hasCustomBrowserCSS){
      var styleCustom = document.createElement("style");
      styleCustom.innerHTML = $TD.customBrowserCSS;
      document.head.appendChild(styleCustom);
    }
  })();
})($, $TD, TD);
<commit_msg>Rewrite extra mouse button handling and fix skipping 'Back to Tweet'<commit_after>(function($, $TD, TD){
  //
  // Variable: Current highlighted column jQuery object.
  //
  var highlightedColumnEle;

  //
  // Variable: Currently highlighted tweet jQuery object.
  //
  var highlightedTweetEle;

  //
  // Function: Initializes TweetD*ck events. Called after the website app is loaded.
  //
  var initializeTweetDck = function(){
    // Settings button hook
    $("[data-action='settings-menu']").click(function(){
      setTimeout(function(){
        var menu = $(".js-dropdown-content").children("ul").first();
        if (menu.length === 0)return;

        menu.children(".drp-h-divider").last().after([
          '
'+$TD.brandName+' settings
',
          '
'+$TD.brandName+' plugins
',
          '

'
        ].join(""));

        var buttons = menu.children("[data-std]");

        buttons.on("click", "a", function(){
          var action = $(this).attr("data-action");

          if (action === "td-settings"){
            $TD.openSettingsMenu();
          }
          else if (action === "td-plugins"){
            $TD.openPluginsMenu();
          }
        });

        buttons.hover(function(){
          $(this).addClass("is-selected");
        }, function(){
          $(this).removeClass("is-selected");
        });
      }, 0);
    });

    // Notification handling
    $.subscribe("/notifications/new", function(obj){
      for(let index = obj.items.length-1; index >= 0; index--){
        onNewTweet(obj.column, obj.items[index]);
      }
    });

    // Setup video element replacement and fix missing target in user links
    new MutationObserver(function(){
      $("video").each(function(){
        $(this).parent().replaceWith("► Open video in browser");
      });

      $("a[rel='user']").attr("target", "_blank");
    }).observe($(".js-app-columns")[0], {
      childList: true,
      subtree: true
    });

    // Finish init and load plugins
    $TD.loadFontSizeClass(TD.settings.getFontSize());
    $TD.loadNotificationHeadContents(getNotificationHeadContents());

    window.TD_APP_READY = true;

    if (window.TD_PLUGINS){
      window.TD_PLUGINS.onReady();
    }
  };

  //
  // Function: Prepends code at the beginning of a function. If the prepended function returns true, execution of the original function is cancelled.
  //
  var prependToFunction = function(func, extension){
    return function(){
      return extension.apply(this, arguments) === true ? undefined : func.apply(this, arguments);
    };
  };

  //
  // Function: Appends code at the end of a function.
  //
  var appendToFunction = function(func, extension){
    return function(){
      var res = func.apply(this, arguments);
      extension.apply(this, arguments);
      return res;
    };
  };

  //
  // Function: Event callback for a new tweet.
  //
  var onNewTweet = function(column, tweet){
    if (column.model.getHasNotification()){
      var html = $(tweet.render({
        withFooter: false,
        withTweetActions: false,
        withMediaPreview: true,
        isMediaPreviewOff: true,
        isMediaPreviewSmall: false,
        isMediaPreviewLarge: false
      }));

      html.css("border", "0");
      html.find("footer").last().remove(); // apparently withTweetActions breaks for certain tweets, nice

      var url = html.find("time").first().children("a").first().attr("href") || "";

      $TD.onTweetPopup(html.html(), url, tweet.text.length); // TODO column
    }
    else if (column.model.getHasSound()){
      $TD.onTweetSound(); // TODO disable original
    }
  };

  //
  // Function: Retrieves the tags to be put into  for notification HTML code.
  //
  var getNotificationHeadContents = function(){
    var tags = [];

    $(document.head).children("link[rel='stylesheet'],meta[charset],meta[http-equiv]").each(function(){
      tags.push($(this)[0].outerHTML);
    });

    return tags.join("");
  };

  //
  // Block: Observe the app
 element and initialize TweetD*ck whenever possible.
  //
  var app = $("body").children(".js-app");

  new MutationObserver(function(){
    if (window.TD_APP_READY && app.hasClass("is-hidden")){
      window.TD_APP_READY = false;
    }
    else if (!window.TD_APP_READY && !app.hasClass("is-hidden")){
      initializeTweetDck();
    }
  }).observe(app[0], {
    attributes: true,
    attributeFilter: [ "class" ]
  });

  //
  // Block: Hook into settings object to detect when the settings change.
  //
  TD.settings.setFontSize = appendToFunction(TD.settings.setFontSize, function(name){
    $TD.loadFontSizeClass(name);
  });

  TD.settings.setTheme = appendToFunction(TD.settings.setTheme, function(){
    setTimeout(function(){
      $TD.loadNotificationHeadContents(getNotificationHeadContents());
    }, 0);
  });

  //
  // Block: Force popup notification settings.
  //
  TD.controller.notifications.hasNotifications = function(){
    return true;
  };

  TD.controller.notifications.isPermissionGranted = function(){
    return true;
  };

  //
  // Block: Expand shortened links on hover or display tooltip.
  //
  (function(){
    var cutStart = function(str, search){
      return str.startsWith(search) ? str.substr(search.length) : str;
    };

    var prevMouseX = -1, prevMouseY = -1;
    var tooltipTimer, tooltipDisplayed;

    $(document.body).delegate("a[data-full-url]", "mouseenter mouseleave mousemove", function(e){
      var me = $(this);

      if (e.type === "mouseenter"){
        var text = me.text();

        if (text.charCodeAt(text.length-1) !== 8230){ // horizontal ellipsis
          return;
        }

        if ($TD.expandLinksOnHover){
          tooltipTimer = window.setTimeout(function(){
            var expanded = me.attr("data-full-url");
            expanded = cutStart(expanded, "https://");
            expanded = cutStart(expanded, "http://");
            expanded = cutStart(expanded, "www.");

            me.attr("td-prev-text", text);
            me.text(expanded);
          }, 200);
        }
        else{
          tooltipTimer = window.setTimeout(function(){
            $TD.displayTooltip(me.attr("data-full-url"), false);
            tooltipDisplayed = true;
          }, 400);
        }
      }
      else if (e.type === "mouseleave"){
        if ($TD.expandLinksOnHover){
          var prevText = me.attr("td-prev-text");

          if (prevText){
            me.text(prevText);
          }
        }

        window.clearTimeout(tooltipTimer);

        if (tooltipDisplayed){
          tooltipDisplayed = false;
          $TD.displayTooltip(null, false);
        }
      }
      else if (e.type === "mousemove"){
        if (tooltipDisplayed && (prevMouseX !== e.clientX || prevMouseY !== e.clientY)){
          $TD.displayTooltip(me.attr("data-full-url"), false);
          prevMouseX = e.clientX;
          prevMouseY = e.clientY;
        }
      }
    });
  })();

  //
  // Block: Allow bypassing of t.co in context menus.
  //
  $(document.body).delegate("a", "contextmenu", function(){
    $TD.setLastRightClickedLink($(this).attr("data-full-url") || "");
  });

  //
  // Block: Hook into the notification sound effect.
  //
  (function(){
    var soundEle = document.getElementById("update-sound");

    soundEle.play = prependToFunction(soundEle.play, function(){
      return $TD.muteNotifications;
    });
  })();

  /* TODO document.getElementById("update-sound").play = function(){
    $TD.onTweetSound();
  };*/

  //
  // Block: Update highlighted column.
  //
  app.delegate("section", "mouseenter mouseleave", function(e){
    if (e.type === "mouseenter"){
      highlightedColumnEle = $(this);
    }
    else if (e.type === "mouseleave"){
      highlightedColumnEle = null;
    }
  });

  //
  // Block: Copy tweet address and update highlighted tweet.
  //
  (function(){
    var lastTweet = "";

    var updateHighlightedTweet = function(link, embeddedLink){
      if (lastTweet !== link){
        $TD.setLastHighlightedTweet(link, embeddedLink);
        lastTweet = link;
      }
    };

    app.delegate("article.js-stream-item", "mouseenter mouseleave", function(e){
      if (e.type === "mouseenter"){
        highlightedTweetEle = $(this);

        var link = $(this).find("time").first().children("a").first();
        var embedded = $(this).find(".quoted-tweet[data-tweet-id]").first();

        updateHighlightedTweet(link.length > 0 ? link.attr("href") : "", embedded.length > 0 ? embedded.find(".account-link").first().attr("href")+"/status/"+embedded.attr("data-tweet-id") : "");
      }
      else if (e.type === "mouseleave"){
        highlightedTweetEle = null;
        updateHighlightedTweet("", "");
      }
    });
  })();

  //
  // Block: Paste images when tweeting.
  //
  (function(){
    var lastPasteElement;
    var prevScrollTop;

    var getScroller = function(){
      return $(".js-drawer").find(".js-compose-scroller").first().children().first();
    };

    var clickUpload = function(){
      var button = $(".js-add-image-button").first();

      var scroller = getScroller();
      prevScrollTop = scroller.scrollTop();

      scroller.scrollTop(0);
      scroller.scrollTop(button.offset().top); // scrolls the button into view

      var buttonPos = button.children().first().offset(); // finds the camera icon offset
      $TD.clickUploadImage(Math.floor(buttonPos.left), Math.floor(buttonPos.top));
    };

    $(".js-app").delegate(".js-compose-text,.js-reply-tweetbox", "paste", function(){
      lastPasteElement = $(this);
      $TD.tryPasteImage();
    });

    window.TDGF_tryPasteImage = function(){
      if (lastPasteElement){
        var parent = lastPasteElement.parent();

        if (parent.siblings(".js-add-image-button").length === 0){
          var pop = parent.closest(".js-inline-reply,.rpl").find(".js-inline-compose-pop,.js-reply-popout");

          if (pop.length === 0){
            lastPasteElement = null;
            return;
          }

          pop.click();

          var drawer = $(".js-drawer");
          var counter = 0;

          var interval = setInterval(function(){
            if (drawer.offset().left >= 195){
              clickUpload();
              clearInterval(interval);
            }
            else if (++counter >= 10){
              clearInterval(interval);
            }
          }, 51);
        }
        else{
          clickUpload();
        }

        lastPasteElement = null;
      }
    };

    window.TDGF_tryPasteImageFinish = function(){
      setTimeout(function(){
        getScroller().scrollTop(prevScrollTop);
        $(".js-drawer").find(".js-compose-text").first()[0].focus();
      }, 10);
    };
  })();

  //
  // Block: Support for extra mouse buttons.
  //
  (function(){
    var tryClickSelector = function(selector, parent){
      return $(selector, parent).click().length;
    };

    var tryCloseModal = function(){
      var modal = $("#open-modal");
      return modal.is(":visible") && tryClickSelector("a[rel=dismiss]", modal);
    };

    var tryCloseHighlightedColumn = function(){
      if (highlightedColumnEle){
        var column = highlightedColumnEle.closest(".js-column");
        return (column.is(".is-shifted-2") && tryClickSelector(".js-tweet-social-proof-back", column)) || (column.is(".is-shifted-1") && tryClickSelector(".js-column-back", column));
      }
    };

    window.TDGF_onMouseClickExtra = function(button){
      if (button === 1){ // back button
        tryCloseModal() ||
        tryClickSelector(".js-inline-compose-close") ||
        tryCloseHighlightedColumn() ||
        tryClickSelector(".js-app-content.is-open .js-drawer-close:visible") ||
        tryClickSelector(".is-shifted-2 .js-tweet-social-proof-back") ||
        $(".js-column-back").click();
      }
      else if (button === 2){ // forward button
        if (highlightedTweetEle){
          highlightedTweetEle.children().first().click();
        }
      }
    };
  })();

  //
  // Block: Fix scheduled tweets not showing up sometimes.
  //
  $(document).on("dataTweetSent", function(e, data){
    if (data.response.state && data.response.state === "scheduled"){
      var column = Object.values(TD.controller.columnManager.getAll()).find(column => column.model.state.type === "scheduled");

      if (column){
        setTimeout(function(){
          column.reloadTweets();
        }, 1000);
      }
    }
  });

  //
  // Block: Inject custom CSS and layout into the page.
  //
  (function(){
    var styleOfficial = document.createElement("style");
    document.head.appendChild(styleOfficial);

    styleOfficial.sheet.insertRule("a[data-full-url] { word-break: break-all; }", 0); // break long urls
    styleOfficial.sheet.insertRule(".column-nav-link .attribution { position: absolute; }", 0); // fix cut off account names
    styleOfficial.sheet.insertRule(".txt-base-smallest .badge-verified:before { height: 13px !important; }", 0); // fix cut off badge icon
    styleOfficial.sheet.insertRule(".keyboard-shortcut-list { vertical-align: top; }", 0); // fix keyboard navigation alignment

    if ($TD.hasCustomBrowserCSS){
      var styleCustom = document.createElement("style");
      styleCustom.innerHTML = $TD.customBrowserCSS;
      document.head.appendChild(styleCustom);
    }
  })();
})($, $TD, TD);
<|endoftext|>


<commit_before>var path = require('path')
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var CopyWebpackPlugin = require('copy-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')

var env = process.env.NODE_ENV === 'testing'
  ? require('../config/test.env')
  : config.lib_build.env
let rules = utils.styleLoaders({
      sourceMap: false,
      extract: false
});
var webpackConfig = merge(baseWebpackConfig, {
  entry: {
    app: './src/lib/index.js'
  },
  module: {
    rules
  },
  devtool: config.lib_build.productionSourceMap ? '#source-map' : false,
  output: {
    path: config.lib_build.assetsRoot,
    filename: 'index.js',
    chunkFilename: 'index.js',
    library: 'VueAMap',
    libraryTarget: 'umd',
    umdNamedDefine: true
  },
  externals: {
      vue: {
        root: 'Vue',
        commonjs: 'vue',
        commonjs2: 'vue',
        amd: 'vue'
      }
  }
})

module.exports = webpackConfig
<commit_msg>build: fixed webpack lib config<commit_after>var path = require('path')
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var CopyWebpackPlugin = require('copy-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')

var env = process.env.NODE_ENV === 'testing'
  ? require('../config/test.env')
  : config.lib_build.env
let rules = utils.styleLoaders({
      sourceMap: false,
      extract: false
});
var webpackConfig = merge(baseWebpackConfig, {
  module: {
    rules
  },
  devtool: config.lib_build.productionSourceMap ? '#source-map' : false,
  output: {
    path: config.lib_build.assetsRoot,
    filename: 'index.js',
    chunkFilename: 'index.js',
    library: 'VueAMap',
    libraryTarget: 'umd',
    umdNamedDefine: true
  },
  externals: {
      vue: {
        root: 'Vue',
        commonjs: 'vue',
        commonjs2: 'vue',
        amd: 'vue'
      }
  }
})

module.exports = webpackConfig
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import theme from './theme.css';

class LoadingMolecule extends Component {
  static defaultProps = {
    className: '',
    startColor: '#BABABA',
    stopColor: '#DADADA',
    type: 'normal',
  };

  static propTypes = {
    className: PropTypes.string,
    basePath: PropTypes.string.isRequired,
    startColor: PropTypes.string.isRequired,
    stopColor: PropTypes.string.isRequired,
    type: PropTypes.string,
  };

  constructor () {
    super(...arguments);
    this.randomGradientPostFix = Math.random().toString(16).slice(2);
  }

  render () {
    const {
      className,
      basePath,
      startColor,
      stopColor,
      type,
      ...others
    } = this.props;

    const classes = cx(
      theme['loading-molecule'],
      theme[type],
      className
    );

    const gradient1Name = `linearGradient-1-${this.randomGradientPostFix}`;
    const gradient2Name = `linearGradient-2-${this.randomGradientPostFix}`;
    const grandient1Source = `url(${basePath}#${gradient1Name})`;
    const grandient2Source = `url(${basePath}#${gradient2Name})`;

    return (

        <svg className="loader" width="100px" height="56px" version="1.1">
          <defs>
            <linearGradient x1="63.2191022%" y1="50%" x2="21.8036493%" y2="115.713387%" id={gradient1Name}>
              <stop stopColor={startColor} offset="0%" />
              <stop stopColor={stopColor} offset="100%" />
            </linearGradient>
            <linearGradient x1="63.2191002%" y1="50%" x2="63.2191002%" y2="0%" id={gradient2Name}>
              <stop stopColor={startColor} offset="0%" />
              <stop stopColor={stopColor} offset="100%" />
            </linearGradient>
          </defs>
          <g id="Content" stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
            <polyline
              id="left-solid"
              className={theme['left-solid']}
              fill={startColor}
              points="48.1016216 0.241175937 48.1016216 28.1174122 0.0416216216 28.1174122 48.1016216 0.241175937"
            />
            <polyline
              id="right-solid"
              className={theme['right-solid']}
              fill={startColor}
              points="51.7081081 56.0633336 75.747027 42.0745849 51.7081081 0.241175937 51.7081081 56.0633336"
            />
            <polyline
              id="right-gradient"
              className={theme['right-gradient']}
              fill={grandient1Source}
              points="67.7264865 28.1168678 75.747027 42.0745849 99.7772973 28.1168678 67.7264865 28.1168678"
            />
            <polyline
              id="left-gradient"
              className={theme['left-gradient']}
              fill={grandient2Source}
              points="32.0897297 28.1174122 48.1016216 28.1174122 48.0843243 56.0736775 32.0897297 28.1174122"
            />
          </g>
        </svg>

    );
  }
}

export default LoadingMolecule;
<commit_msg>Converted Island to PureComponent<commit_after>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import theme from './theme.css';

class LoadingMolecule extends PureComponent {
  static defaultProps = {
    className: '',
    startColor: '#BABABA',
    stopColor: '#DADADA',
    type: 'normal',
  };

  static propTypes = {
    className: PropTypes.string,
    basePath: PropTypes.string.isRequired,
    startColor: PropTypes.string.isRequired,
    stopColor: PropTypes.string.isRequired,
    type: PropTypes.string,
  };

  constructor () {
    super(...arguments);
    this.randomGradientPostFix = Math.random().toString(16).slice(2);
  }

  render () {
    const {
      className,
      basePath,
      startColor,
      stopColor,
      type,
      ...others
    } = this.props;

    const classes = cx(
      theme['loading-molecule'],
      theme[type],
      className
    );

    const gradient1Name = `linearGradient-1-${this.randomGradientPostFix}`;
    const gradient2Name = `linearGradient-2-${this.randomGradientPostFix}`;
    const grandient1Source = `url(${basePath}#${gradient1Name})`;
    const grandient2Source = `url(${basePath}#${gradient2Name})`;

    return (

        <svg className="loader" width="100px" height="56px" version="1.1">
          <defs>
            <linearGradient x1="63.2191022%" y1="50%" x2="21.8036493%" y2="115.713387%" id={gradient1Name}>
              <stop stopColor={startColor} offset="0%" />
              <stop stopColor={stopColor} offset="100%" />
            </linearGradient>
            <linearGradient x1="63.2191002%" y1="50%" x2="63.2191002%" y2="0%" id={gradient2Name}>
              <stop stopColor={startColor} offset="0%" />
              <stop stopColor={stopColor} offset="100%" />
            </linearGradient>
          </defs>
          <g id="Content" stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
            <polyline
              id="left-solid"
              className={theme['left-solid']}
              fill={startColor}
              points="48.1016216 0.241175937 48.1016216 28.1174122 0.0416216216 28.1174122 48.1016216 0.241175937"
            />
            <polyline
              id="right-solid"
              className={theme['right-solid']}
              fill={startColor}
              points="51.7081081 56.0633336 75.747027 42.0745849 51.7081081 0.241175937 51.7081081 56.0633336"
            />
            <polyline
              id="right-gradient"
              className={theme['right-gradient']}
              fill={grandient1Source}
              points="67.7264865 28.1168678 75.747027 42.0745849 99.7772973 28.1168678 67.7264865 28.1168678"
            />
            <polyline
              id="left-gradient"
              className={theme['left-gradient']}
              fill={grandient2Source}
              points="32.0897297 28.1174122 48.1016216 28.1174122 48.0843243 56.0736775 32.0897297 28.1174122"
            />
          </g>
        </svg>

    );
  }
}

export default LoadingMolecule;
<|endoftext|>


<commit_before>const BinaryPjax         = require('../../base/binary_pjax');
const Client             = require('../../base/client');
const BinarySocket       = require('../../base/socket');
const Currency           = require('../../common/currency');
const FormManager        = require('../../common/form_manager');
const elementTextContent = require('../../../_common/common_functions').elementTextContent;
const getElementById     = require('../../../_common/common_functions').getElementById;
const localize           = require('../../../_common/localize').localize;
const State              = require('../../../_common/storage').State;
const getPropertyValue   = require('../../../_common/utility').getPropertyValue;

const AccountTransfer = (() => {
    const form_id       = 'frm_account_transfer';
    const form_id_hash  = `#${form_id}`;

    const messages = {
        parent : 'client_message',
        error  : 'no_account',
        balance: 'not_enough_balance',
        deposit: 'no_balance',
        limit  : 'limit_reached',
    };

    let el_transfer_from,
        el_transfer_to,
        el_reset_transfer,
        el_transfer_fee,
        el_fee_amount,
        el_fee_minimum,
        el_success_form,
        client_balance,
        client_currency,
        client_loginid,
        withdrawal_limit,
        max_amount,
        transferable_amount,
        transfer_to_currency;

    /**
     * Sort Accounts
     * See : https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore#_sortby-and-_orderby
     * @param accounts
     * @returns {*}
     */
    const sortAccounts = (accounts) => {
        const sortBy = (key) => (a, b) => (a[key] > b[key]) ? 1 : ((b[key] > a[key]) ? -1 : 0);

        return accounts.concat().sort(sortBy('currency'));
    };

    const populateAccounts = (accounts) => {
        client_loginid   = Client.get('loginid');
        el_transfer_from = getElementById('lbl_transfer_from');
        el_transfer_to   = getElementById('transfer_to');

        elementTextContent(el_transfer_from, `${client_loginid} ${client_currency ? `(${client_currency})` : ''}`);

        const fragment_transfer_to = document.createElement('div');

        sortAccounts(accounts).forEach((account) => {
            if (Client.canTransferFunds(account)) {
                const option = document.createElement('option');
                option.setAttribute('data-currency', account.currency);
                option.appendChild(document.createTextNode(`${account.loginid}${account.currency ? ` (${account.currency})` : ''}`));
                fragment_transfer_to.appendChild(option);
            }
        });

        if (!fragment_transfer_to.childElementCount) {
            showError();
            return;
        } else if (fragment_transfer_to.childElementCount === 1) {
            const el_label_transfer_to = document.createElement('p');
            el_label_transfer_to.setAttribute('data-value', fragment_transfer_to.firstChild.textContent);
            el_label_transfer_to.setAttribute('id', el_transfer_to.getAttribute('id'));
            el_label_transfer_to.innerText = fragment_transfer_to.firstChild.textContent;
            el_transfer_to.setVisibility(0);
            el_transfer_to.setAttribute('data-value', fragment_transfer_to.firstChild.textContent);
            el_transfer_to.parentElement.insertBefore(el_label_transfer_to, el_transfer_to);
        } else {
            el_transfer_to.innerHTML = fragment_transfer_to.innerHTML;
        }

        el_transfer_to.onchange = () => {
            setTransferFeeAmount();
        };

        transfer_to_currency = getElementById('amount-add-on');
        transfer_to_currency.textContent = Client.get('currency');

        showForm();

        if (Client.hasCurrencyType('crypto') && Client.hasCurrencyType('fiat')) {
            setTransferFeeAmount();
            elementTextContent(el_fee_minimum, Currency.getMinimumTransferFee(client_currency));
            el_transfer_fee.setVisibility(1);
        } else {
            const to_currency = el_transfer_to.getAttribute('data-currency');
            el_transfer_fee.setVisibility(client_currency !== to_currency);
        }

        // Hide Notes from MF|MLT accounts
        if (/iom|malta/.test(Client.get('landing_company_shortcode'))) {
            el_transfer_fee.setVisibility(0);
        }
    };

    const setTransferFeeAmount = () => {
        elementTextContent(el_fee_amount, Currency.getTransferFee(client_currency, (el_transfer_to.value || el_transfer_to.getAttribute('data-value') || '').match(/\((\w+)\)/)[1]));
    };

    const hasError = (response) => {
        const error = response.error;
        if (error) {
            const el_error = getElementById('error_message').getElementsByTagName('p')[0];
            elementTextContent(el_error, error.message);
            if (el_error.parentNode) {
                el_error.parentNode.setVisibility(1);
            }
            return true;
        }
        return false;
    };

    const showError = () => {
        getElementById(messages.parent).setVisibility(1);
        getElementById(messages.error).setVisibility(1);
    };

    const showForm = () => {
        elementTextContent(document.querySelector(`${form_id_hash} #currency`), client_currency);

        getElementById(form_id).setVisibility(1);

        FormManager.init(form_id_hash, [
            { selector: '#amount', validations: [['req', { hide_asterisk: true }], ['number', { type: 'float', decimals: Currency.getDecimalPlaces(client_currency), min: Currency.getTransferLimits(client_currency, 'min'), max: transferable_amount, format_money: true }]] },

            { request_field: 'transfer_between_accounts', value: 1 },
            { request_field: 'account_from',              value: client_loginid },
            { request_field: 'account_to',                value: () => (el_transfer_to.value || el_transfer_to.getAttribute('data-value') || '').split(' (')[0] },
            { request_field: 'currency',                  value: client_currency },
        ]);

        FormManager.handleSubmit({
            form_selector       : form_id_hash,
            fnc_response_handler: responseHandler,
            enable_button       : true,
        });
    };

    const responseHandler = (response) => {
        if (response.error) {
            const el_error = getElementById('form_error');
            elementTextContent(el_error, response.error.message);
            el_error.setVisibility(1);
            // Auto hide error after 5 seconds.
            setTimeout(() => el_error.setVisibility(0), 5000);
        } else {
            BinarySocket.send({ transfer_between_accounts: 1 }).then(data => populateReceipt(response, data));
        }
    };

    const populateReceipt = (response_submit_success, response) => {
        getElementById(form_id).setVisibility(0);
        response.accounts.forEach((account) => {
            if (account.loginid === client_loginid) {
                elementTextContent(getElementById('transfer_success_from'), localize('From account: '));
                elementTextContent(getElementById('from_loginid'), `${account.loginid} (${account.currency})`);
                getElementById('from_current_balance').innerHTML = Currency.formatMoney(
                    account.currency,
                    account.balance,
                );
            } else if (account.loginid === response_submit_success.client_to_loginid) {
                elementTextContent(getElementById('transfer_success_to'), localize('To account: '));
                elementTextContent(getElementById('to_loginid'), `${account.loginid} (${account.currency})`);
                getElementById('to_current_balance').innerHTML = Currency.formatMoney(
                    account.currency,
                    account.balance,
                );
            }
        });

        el_transfer_fee.setVisibility(0);
        el_success_form.setVisibility(1);
    };

    const onClickReset = () => {
        el_success_form.setVisibility(0);
        getElementById('amount').value = '';
        onLoad();
    };

    const onLoad = () => {
        if (!Client.canTransferFunds()) {
            BinaryPjax.loadPreviousUrl();
            return;
        }

        el_transfer_fee   = getElementById('transfer_fee');
        el_fee_amount     = getElementById('transfer_fee_amount');
        el_fee_minimum    = getElementById('transfer_fee_minimum');
        el_success_form   = getElementById('success_form');
        el_reset_transfer = getElementById('reset_transfer');
        el_reset_transfer.addEventListener('click', onClickReset);

        BinarySocket.wait('balance').then((response) => {
            client_balance   = +getPropertyValue(response, ['balance', 'balance']);
            client_currency  = Client.get('currency');
            const min_amount = Currency.getTransferLimits(client_currency, 'min');
            if (!client_balance || client_balance < +min_amount) {
                getElementById(messages.parent).setVisibility(1);
                if (client_currency) {
                    elementTextContent(getElementById('min_required_amount'), `${client_currency} ${min_amount}`);
                    getElementById(messages.balance).setVisibility(1);
                }
                getElementById(messages.deposit).setVisibility(1);
            } else {
                const req_transfer_between_accounts = BinarySocket.send({ transfer_between_accounts: 1 });
                const req_get_limits                = BinarySocket.send({ get_limits: 1 });

                Promise.all([req_transfer_between_accounts, req_get_limits]).then(() => {
                    const response_transfer = State.get(['response', 'transfer_between_accounts']);
                    const response_limits   = State.get(['response', 'get_limits']);

                    if (hasError(response_transfer)) {
                        return;
                    }
                    const accounts = response_transfer.accounts;
                    if (!accounts || !accounts.length) {
                        showError();
                        return;
                    }
                    if (hasError(response_limits)) {
                        return;
                    }
                    withdrawal_limit = +response_limits.get_limits.remainder;

                    if (withdrawal_limit < +min_amount) {
                        getElementById(messages.limit).setVisibility(1);
                        getElementById(messages.parent).setVisibility(1);
                        return;
                    }
                    max_amount = Currency.getTransferLimits(
                        Client.get('currency'),
                        'max'
                    );
                    transferable_amount = max_amount ?
                        Math.min(max_amount, withdrawal_limit, client_balance) :
                        Math.min(withdrawal_limit, client_balance);

                    getElementById('range_hint_min').textContent = min_amount;
                    getElementById('range_hint_max').textContent = transferable_amount.toFixed(
                        Currency.getDecimalPlaces(
                            Client.get('currency')
                        )
                    );
                    populateHints();
                    populateAccounts(accounts);
                });
            }
        });
    };

    const populateHints = () => {
        getElementById('limit_current_balance').innerHTML  = Currency.formatMoney(
            client_currency,
            client_balance,
        );

        getElementById('limit_max_amount').innerHTML = max_amount ? Currency.formatMoney(
            client_currency,
            max_amount,
        ) : localize('Not announced for this currency.');

        $('#range_hint').accordion({
            heightStyle: 'content',
            collapsible: true,
            active     : true,
        });

        getElementById('range_hint').show();
    };

    const onUnload = () => {
        if (el_reset_transfer) el_reset_transfer.removeEventListener('click', onClickReset);
    };

    return {
        onLoad,
        onUnload,
    };
})();

module.exports = AccountTransfer;
<commit_msg>Use Client Current Balance for FIAT<->FIAT transfer<commit_after>const BinaryPjax         = require('../../base/binary_pjax');
const Client             = require('../../base/client');
const BinarySocket       = require('../../base/socket');
const Currency           = require('../../common/currency');
const FormManager        = require('../../common/form_manager');
const elementTextContent = require('../../../_common/common_functions').elementTextContent;
const getElementById     = require('../../../_common/common_functions').getElementById;
const localize           = require('../../../_common/localize').localize;
const State              = require('../../../_common/storage').State;
const getPropertyValue   = require('../../../_common/utility').getPropertyValue;

const AccountTransfer = (() => {
    const form_id       = 'frm_account_transfer';
    const form_id_hash  = `#${form_id}`;

    const messages = {
        parent : 'client_message',
        error  : 'no_account',
        balance: 'not_enough_balance',
        deposit: 'no_balance',
        limit  : 'limit_reached',
    };

    let el_transfer_from,
        el_transfer_to,
        el_reset_transfer,
        el_transfer_fee,
        el_fee_amount,
        el_fee_minimum,
        el_success_form,
        client_balance,
        client_currency,
        client_loginid,
        withdrawal_limit,
        max_amount,
        transferable_amount,
        to_loginid,
        transfer_to_currency;

    /**
     * Sort Accounts
     * See : https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore#_sortby-and-_orderby
     * @param accounts
     * @returns {*}
     */
    const sortAccounts = (accounts) => {
        const sortBy = (key) => (a, b) => (a[key] > b[key]) ? 1 : ((b[key] > a[key]) ? -1 : 0);

        return accounts.concat().sort(sortBy('currency'));
    };

    const populateAccounts = (accounts) => {
        client_loginid   = Client.get('loginid');
        el_transfer_from = getElementById('lbl_transfer_from');
        el_transfer_to   = getElementById('transfer_to');

        elementTextContent(el_transfer_from, `${client_loginid} ${client_currency ? `(${client_currency})` : ''}`);

        const fragment_transfer_to = document.createElement('div');

        sortAccounts(accounts).forEach((account) => {
            if (Client.canTransferFunds(account)) {
                const option = document.createElement('option');
                option.setAttribute('data-currency', account.currency);
                option.setAttribute('data-loginid', account.loginid);
                option.appendChild(document.createTextNode(`${account.loginid}${account.currency ? ` (${account.currency})` : ''}`));
                fragment_transfer_to.appendChild(option);
            }
        });

        if (!fragment_transfer_to.childElementCount) {
            showError();
            return;
        } else if (fragment_transfer_to.childElementCount === 1) {
            const el_label_transfer_to = document.createElement('p');
            el_label_transfer_to.setAttribute('data-value', fragment_transfer_to.firstChild.textContent);
            el_label_transfer_to.setAttribute('id', el_transfer_to.getAttribute('id'));
            el_label_transfer_to.innerText = fragment_transfer_to.firstChild.textContent;
            to_loginid = fragment_transfer_to.firstChild.getAttribute('data-loginid');
            el_transfer_to.setVisibility(0);
            el_transfer_to.setAttribute('data-value', fragment_transfer_to.firstChild.textContent);
            el_transfer_to.parentElement.insertBefore(el_label_transfer_to, el_transfer_to);
        } else {
            el_transfer_to.innerHTML = fragment_transfer_to.innerHTML;
        }

        el_transfer_to.onchange = () => {
            setTransferFeeAmount();
        };

        transfer_to_currency = getElementById('amount-add-on');
        transfer_to_currency.textContent = Client.get('currency');

        showForm();

        if (Client.hasCurrencyType('crypto') && Client.hasCurrencyType('fiat')) {
            setTransferFeeAmount();
            elementTextContent(el_fee_minimum, Currency.getMinimumTransferFee(client_currency));
            el_transfer_fee.setVisibility(1);
        } else {
            const to_currency = el_transfer_to.getAttribute('data-currency');
            el_transfer_fee.setVisibility(client_currency !== to_currency);
        }

        // Hide Notes from MF|MLT accounts
        if (/iom|malta/.test(Client.get('landing_company_shortcode'))) {
            el_transfer_fee.setVisibility(0);
        }
    };

    const setTransferFeeAmount = () => {
        elementTextContent(el_fee_amount, Currency.getTransferFee(client_currency, (el_transfer_to.value || el_transfer_to.getAttribute('data-value') || '').match(/\((\w+)\)/)[1]));
    };

    const hasError = (response) => {
        const error = response.error;
        if (error) {
            const el_error = getElementById('error_message').getElementsByTagName('p')[0];
            elementTextContent(el_error, error.message);
            if (el_error.parentNode) {
                el_error.parentNode.setVisibility(1);
            }
            return true;
        }
        return false;
    };

    const showError = () => {
        getElementById(messages.parent).setVisibility(1);
        getElementById(messages.error).setVisibility(1);
    };

    const showForm = () => {
        elementTextContent(document.querySelector(`${form_id_hash} #currency`), client_currency);

        getElementById(form_id).setVisibility(1);

        FormManager.init(form_id_hash, [
            { selector: '#amount', validations: [['req', { hide_asterisk: true }], ['number', { type: 'float', decimals: Currency.getDecimalPlaces(client_currency), min: Currency.getTransferLimits(client_currency, 'min'), max: transferable_amount, format_money: true }]] },

            { request_field: 'transfer_between_accounts', value: 1 },
            { request_field: 'account_from',              value: client_loginid },
            { request_field: 'account_to',                value: () => (el_transfer_to.value || el_transfer_to.getAttribute('data-value') || '').split(' (')[0] },
            { request_field: 'currency',                  value: client_currency },
        ]);

        FormManager.handleSubmit({
            form_selector       : form_id_hash,
            fnc_response_handler: responseHandler,
            enable_button       : true,
        });
    };

    const responseHandler = (response) => {
        if (response.error) {
            const el_error = getElementById('form_error');
            elementTextContent(el_error, response.error.message);
            el_error.setVisibility(1);
            // Auto hide error after 5 seconds.
            setTimeout(() => el_error.setVisibility(0), 5000);
        } else {
            BinarySocket.send({ transfer_between_accounts: 1 }).then(data => populateReceipt(response, data));
        }
    };

    const populateReceipt = (response_submit_success, response) => {
        getElementById(form_id).setVisibility(0);
        response.accounts.forEach((account) => {
            if (account.loginid === client_loginid) {
                elementTextContent(getElementById('transfer_success_from'), localize('From account: '));
                elementTextContent(getElementById('from_loginid'), `${account.loginid} (${account.currency})`);
                getElementById('from_current_balance').innerHTML = Currency.formatMoney(
                    account.currency,
                    account.balance,
                );
            } else if (account.loginid === response_submit_success.client_to_loginid) {
                elementTextContent(getElementById('transfer_success_to'), localize('To account: '));
                elementTextContent(getElementById('to_loginid'), `${account.loginid} (${account.currency})`);
                getElementById('to_current_balance').innerHTML = Currency.formatMoney(
                    account.currency,
                    account.balance,
                );
            }
        });

        el_transfer_fee.setVisibility(0);
        el_success_form.setVisibility(1);
    };

    const onClickReset = () => {
        el_success_form.setVisibility(0);
        getElementById('amount').value = '';
        onLoad();
    };

    const onLoad = () => {
        if (!Client.canTransferFunds()) {
            BinaryPjax.loadPreviousUrl();
            return;
        }

        el_transfer_fee   = getElementById('transfer_fee');
        el_fee_amount     = getElementById('transfer_fee_amount');
        el_fee_minimum    = getElementById('transfer_fee_minimum');
        el_success_form   = getElementById('success_form');
        el_reset_transfer = getElementById('reset_transfer');
        el_reset_transfer.addEventListener('click', onClickReset);

        BinarySocket.wait('balance').then((response) => {
            client_balance   = +getPropertyValue(response, ['balance', 'balance']);
            client_currency  = Client.get('currency');
            const min_amount = Currency.getTransferLimits(client_currency, 'min');
            if (!client_balance || client_balance < +min_amount) {
                getElementById(messages.parent).setVisibility(1);
                if (client_currency) {
                    elementTextContent(getElementById('min_required_amount'), `${client_currency} ${min_amount}`);
                    getElementById(messages.balance).setVisibility(1);
                }
                getElementById(messages.deposit).setVisibility(1);
            } else {
                const req_transfer_between_accounts = BinarySocket.send({ transfer_between_accounts: 1 });
                const req_get_limits                = BinarySocket.send({ get_limits: 1 });

                Promise.all([req_transfer_between_accounts, req_get_limits]).then(() => {
                    const response_transfer = State.get(['response', 'transfer_between_accounts']);
                    const response_limits   = State.get(['response', 'get_limits']);

                    if (hasError(response_transfer)) {
                        return;
                    }
                    const accounts = response_transfer.accounts;
                    if (!accounts || !accounts.length) {
                        showError();
                        return;
                    }
                    if (hasError(response_limits)) {
                        return;
                    }
                    withdrawal_limit = +response_limits.get_limits.remainder;

                    if (withdrawal_limit < +min_amount) {
                        getElementById(messages.limit).setVisibility(1);
                        getElementById(messages.parent).setVisibility(1);
                        return;
                    }
                    max_amount = Currency.getTransferLimits(
                        Client.get('currency'),
                        'max'
                    );

                    const from_currency = Client.get('currency');
                    const to_currency = Client.get('currency', to_loginid);
                    if (!Currency.isCryptocurrency(from_currency) && !Currency.isCryptocurrency(to_currency)) {
                        transferable_amount = client_balance;
                    } else {
                        transferable_amount = max_amount ?
                            Math.min(max_amount, withdrawal_limit, client_balance) :
                            Math.min(withdrawal_limit, client_balance);
                    }

                    getElementById('range_hint_min').textContent = min_amount;
                    getElementById('range_hint_max').textContent = transferable_amount.toFixed(
                        Currency.getDecimalPlaces(
                            Client.get('currency')
                        )
                    );
                    populateHints();
                    populateAccounts(accounts);
                });
            }
        });
    };

    const populateHints = () => {
        getElementById('limit_current_balance').innerHTML  = Currency.formatMoney(
            client_currency,
            client_balance,
        );

        getElementById('limit_max_amount').innerHTML = max_amount ? Currency.formatMoney(
            client_currency,
            max_amount,
        ) : localize('Not announced for this currency.');

        $('#range_hint').accordion({
            heightStyle: 'content',
            collapsible: true,
            active     : true,
        });

        getElementById('range_hint').show();
    };

    const onUnload = () => {
        if (el_reset_transfer) el_reset_transfer.removeEventListener('click', onClickReset);
    };

    return {
        onLoad,
        onUnload,
    };
})();

module.exports = AccountTransfer;
<|endoftext|>


<commit_before>/*jslint bitwise: true, eqeqeq: true, immed: true, newcap: true, nomen: true, onevar: true, plusplus: true, regexp: true, undef: true, white: true, indent: 2 */
/*globals include md5 node exports */

process.mixin(require('./postgres-js/md5'));
var bits = require('./postgres-js/bits');
var tcp = require("tcp");
var sys = require("sys");

exports.DEBUG = 0;

// http://www.postgresql.org/docs/8.3/static/protocol-message-formats.html
var formatter = {
  CopyData: function () {
    // TODO: implement
  },
  CopyDone: function () {
    // TODO: implement
  },
  Describe: function (name, type) {
    return (new bits.Encoder('D'))
      .push_raw_string(type)
      .push_cstring(name);
  },
  Execute: function (name, max_rows) {
    return (new bits.Encoder('E'))
      .push_cstring(name)
      .push_int32(max_rows);
  },
  Flush: function () {
    return new bits.Encoder('H');
  },
  FunctionCall: function () {
    // TODO: implement
  },
  Parse: function (name, query, var_types) {
    var builder = (new bits.Encoder('P'))
      .push_cstring(name)
      .push_cstring(query)
      .push_int16(var_types.length);
    var_types.each(function (var_type) {
      stream.push_int32(var_type);
    });
    return builder;
  },
  PasswordMessage: function (password) {
    return (new bits.Encoder('p'))
      .push_cstring(password);
  },
  Query: function (query) {
    return (new bits.Encoder('Q'))
      .push_cstring(query);
  },
  SSLRequest: function () {
    return (new bits.Encoder())
      .push_int32(0x4D2162F);
  },
  StartupMessage: function (options) {
    // Protocol version number 3
    return (new bits.Encoder())
      .push_int32(0x30000)
      .push_hash(options);
  },
  Sync: function () {
    return new bits.Encoder('S');
  },
  Terminate: function () {
    return new bits.Encoder('X');
  }
};

// Parse response streams from the server
function parse_response(code, stream) {
  var input = new bits.Decoder(stream);
  var type, args;
  args = [];
  switch (code) {
  case 'R':
    switch (stream.shift_int32()) {
    case 0:
      type = "AuthenticationOk";
      break;
    case 2:
      type = "AuthenticationKerberosV5";
      break;
    case 3:
      type = "AuthenticationCleartextPassword";
      break;
    case 4:
      type = "AuthenticationCryptPassword";
      args = [stream.shift_raw_string(2)];
      break;
    case 5:
      type = "AuthenticationMD5Password";
      args = [stream.shift_raw_string(4)];
      break;
    case 6:
      type = "AuthenticationSCMCredential";
      break;
    case 7:
      type = "AuthenticationGSS";
      break;
    case 8:
      // TODO: add in AuthenticationGSSContinue
      type = "AuthenticationSSPI";
      break;
    }
    break;
  case 'E':
    type = "ErrorResponse";
    args = [{}];
    stream.shift_multi_cstring().forEach(function (field) {
      args[0][field[0]] = field.substr(1);
    });
    break;
  case 'S':
    type = "ParameterStatus";
    args = [stream.shift_cstring(), stream.shift_cstring()];
    break;
  case 'K':
    type = "BackendKeyData";
    args = [stream.shift_int32(), stream.shift_int32()];
    break;
  case 'Z':
    type = "ReadyForQuery";
    args = [stream.shift_raw_string(1)];
    break;
  case 'T':
    type = "RowDescription";
    var num_fields = stream.shift_int16();
    var row = [];
    for (var i = 0; i < num_fields; i += 1) {
      row.push({
        field: stream.shift_cstring(),
        table_id: stream.shift_int32(),
        column_id: stream.shift_int16(),
        type_id: stream.shift_int32(),
        type_size: stream.shift_int16(),
        type_modifier: stream.shift_int32(),
        format_code: stream.shift_int16()
      });
    }
    args = [row];
    break;
  case 'D':
    type = "DataRow";
    var data = [];
    var num_cols = stream.shift_int16();
    for (i = 0; i < num_cols; i += 1) {
      var size = stream.shift_int32();
      if (size === -1) {
        data.push(null);
      } else {
        data.push(stream.shift_raw_string(size));
      }
    }
    args = [data];
    break;
  case 'C':
    type = "CommandComplete";
    args = [stream.shift_cstring()];
    break;
  }
  if (!type) {
    sys.debug("Unknown response " + code);
  }
  return {type: type, args: args};
}

exports.Connection = function (database, username, password, port) {

  // Default to port 5432
  if (port === undefined) {
    port = 5432;
  }

  var connection = tcp.createConnection(port);
  var events = new process.EventEmitter();
  var query_queue = [];
  var row_description;
  var query_callback;
  var results;
  var readyState = false;
  var closeState = false;

  // Sends a message to the postgres server
  function sendMessage(type, args) {
    var stream = (formatter[type].apply(this, args)).toString();
    if (exports.DEBUG > 0) {
      sys.debug("Sending " + type + ": " + JSON.stringify(args));
      if (exports.DEBUG > 2) {
        sys.debug("->" + JSON.stringify(stream));
      }
    }
    connection.send(stream, "binary");
  }

  // Set up tcp client
  connection.setEncoding("binary");
  connection.addListener("connect", function () {
    sendMessage('StartupMessage', [{user: username, database: database}]);
  });
  connection.addListener("receive", function (data) {
    var input = new bits.Decoder(data);
    if (exports.DEBUG > 2) {
      sys.debug("<-" + JSON.stringify(data));
    }

    while (input.data.length > 0) {
      var code = input.shift_code();
      var len = input.shift_int32();
      var stream = new bits.Decoder(input.shift_raw_string(len - 4));
      if (exports.DEBUG > 1) {
        sys.debug("stream: " + code + " " + JSON.stringify(stream));
      }
      var command = parse_response(code, stream);
      if (command.type) {
        if (exports.DEBUG > 0) {
          sys.debug("Received " + command.type + ": " + JSON.stringify(command.args));
        }
        command.args.unshift(command.type);
        events.emit.apply(events, command.args);
      }
    }
  });
  connection.addListener("eof", function (data) {
    connection.close();
  });
  connection.addListener("disconnect", function (had_error) {
    if (had_error) {
      sys.debug("CONNECTION DIED WITH ERROR");
    }
  });

  // Set up callbacks to automatically do the login
  events.addListener('AuthenticationMD5Password', function (salt) {
    var result = "md5" + md5(md5(password + username) + salt);
    sendMessage('PasswordMessage', [result]);
  });
  events.addListener('AuthenticationCleartextPassword', function () {
    sendMessage('PasswordMessage', [password]);
  });
  events.addListener('ErrorResponse', function (e) {
    if (e.S === 'FATAL') {
      sys.debug(e.S + ": " + e.M);
      connection.close();
    }
  });
  events.addListener('ReadyForQuery', function () {
    if (query_queue.length > 0) {
      var query = query_queue.shift();
      query_callback = query.callback;
      sendMessage('Query', [query.sql]);
      readyState = false;
    } else {
      if (closeState) {
        connection.close();
      } else {
        readyState = true;
      }
    }
  });
  events.addListener("RowDescription", function (data) {
    row_description = data;
    results = [];
  });
  events.addListener("DataRow", function (data) {
    var row = {};
    for (var i = 0, l = data.length; i < l; i += 1) {
      var description = row_description[i];
      var value = data[i];
      if (value !== null) {
        // TODO: investigate to see if these numbers are stable across databases or
        // if we need to dynamically pull them from the pg_types table
        switch (description.type_id) {
        case 16: // bool
          value = value === 't';
          break;
        case 20: // int8
        case 21: // int2
        case 23: // int4
          value = parseInt(value, 10);
          break;
        }
      }
      row[description.field] = value;
    }
    results.push(row);
  });
  events.addListener('CommandComplete', function (data) {
    query_callback.call(this, results);
  });

  this.query = function (sql, callback) {
    query_queue.push({sql: sql, callback: callback});
    if (readyState) {
      events.emit('ReadyForQuery');
    }
  };
  this.close = function () {
    closeState = true;
  };
};

<commit_msg>JSlint fixes for postgres.js and a bug fix or two.<commit_after>/*jslint bitwise: true, eqeqeq: true, immed: true, newcap: true, nomen: true, onevar: true, plusplus: true, regexp: true, undef: true, white: true, indent: 2 */
/*globals include md5 node exports */

process.mixin(require('./postgres-js/md5'));
var bits = require('./postgres-js/bits');
var tcp = require("tcp");
var sys = require("sys");

exports.DEBUG = 0;

// http://www.postgresql.org/docs/8.3/static/protocol-message-formats.html
var formatter = {
  CopyData: function () {
    // TODO: implement
  },
  CopyDone: function () {
    // TODO: implement
  },
  Describe: function (name, type) {
    return (new bits.Encoder('D'))
      .push_raw_string(type)
      .push_cstring(name);
  },
  Execute: function (name, max_rows) {
    return (new bits.Encoder('E'))
      .push_cstring(name)
      .push_int32(max_rows);
  },
  Flush: function () {
    return new bits.Encoder('H');
  },
  FunctionCall: function () {
    // TODO: implement
  },
  Parse: function (name, query, var_types) {
    var builder = (new bits.Encoder('P'))
      .push_cstring(name)
      .push_cstring(query)
      .push_int16(var_types.length);
    var_types.each(function (var_type) {
      builder.push_int32(var_type);
    });
    return builder;
  },
  PasswordMessage: function (password) {
    return (new bits.Encoder('p'))
      .push_cstring(password);
  },
  Query: function (query) {
    return (new bits.Encoder('Q'))
      .push_cstring(query);
  },
  SSLRequest: function () {
    return (new bits.Encoder())
      .push_int32(0x4D2162F);
  },
  StartupMessage: function (options) {
    // Protocol version number 3
    return (new bits.Encoder())
      .push_int32(0x30000)
      .push_hash(options);
  },
  Sync: function () {
    return new bits.Encoder('S');
  },
  Terminate: function () {
    return new bits.Encoder('X');
  }
};

// Parse response streams from the server
function parse_response(code, stream) {
  var input, type, args, num_fields, data, size, i;
  input = new bits.Decoder(stream);
  args = [];
  switch (code) {
  case 'R':
    switch (stream.shift_int32()) {
    case 0:
      type = "AuthenticationOk";
      break;
    case 2:
      type = "AuthenticationKerberosV5";
      break;
    case 3:
      type = "AuthenticationCleartextPassword";
      break;
    case 4:
      type = "AuthenticationCryptPassword";
      args = [stream.shift_raw_string(2)];
      break;
    case 5:
      type = "AuthenticationMD5Password";
      args = [stream.shift_raw_string(4)];
      break;
    case 6:
      type = "AuthenticationSCMCredential";
      break;
    case 7:
      type = "AuthenticationGSS";
      break;
    case 8:
      // TODO: add in AuthenticationGSSContinue
      type = "AuthenticationSSPI";
      break;
    }
    break;
  case 'E':
    type = "ErrorResponse";
    args = [{}];
    stream.shift_multi_cstring().forEach(function (field) {
      args[0][field[0]] = field.substr(1);
    });
    break;
  case 'S':
    type = "ParameterStatus";
    args = [stream.shift_cstring(), stream.shift_cstring()];
    break;
  case 'K':
    type = "BackendKeyData";
    args = [stream.shift_int32(), stream.shift_int32()];
    break;
  case 'Z':
    type = "ReadyForQuery";
    args = [stream.shift_raw_string(1)];
    break;
  case 'T':
    type = "RowDescription";
    num_fields = stream.shift_int16();
    data = [];
    for (i = 0; i < num_fields; i += 1) {
      data.push({
        field: stream.shift_cstring(),
        table_id: stream.shift_int32(),
        column_id: stream.shift_int16(),
        type_id: stream.shift_int32(),
        type_size: stream.shift_int16(),
        type_modifier: stream.shift_int32(),
        format_code: stream.shift_int16()
      });
    }
    args = [data];
    break;
  case 'D':
    type = "DataRow";
    data = [];
    num_fields = stream.shift_int16();
    for (i = 0; i < num_fields; i += 1) {
      size = stream.shift_int32();
      if (size === -1) {
        data.push(null);
      } else {
        data.push(stream.shift_raw_string(size));
      }
    }
    args = [data];
    break;
  case 'C':
    type = "CommandComplete";
    args = [stream.shift_cstring()];
    break;
  }
  if (!type) {
    sys.debug("Unknown response " + code);
  }
  return {type: type, args: args};
}

exports.Connection = function (database, username, password, port) {
  var connection, events, query_queue, row_description, query_callback, results, readyState, closeState;

  // Default to port 5432
  if (port === undefined) {
    port = 5432;
  }

  connection = tcp.createConnection(port);
  events = new process.EventEmitter();
  query_queue = [];
  readyState = false;
  closeState = false;

  // Sends a message to the postgres server
  function sendMessage(type, args) {
    var stream = (formatter[type].apply(this, args)).toString();
    if (exports.DEBUG > 0) {
      sys.debug("Sending " + type + ": " + JSON.stringify(args));
      if (exports.DEBUG > 2) {
        sys.debug("->" + JSON.stringify(stream));
      }
    }
    connection.send(stream, "binary");
  }

  // Set up tcp client
  connection.setEncoding("binary");
  connection.addListener("connect", function () {
    sendMessage('StartupMessage', [{user: username, database: database}]);
  });
  connection.addListener("receive", function (data) {
    var input, code, len, stream, command;
    input = new bits.Decoder(data);
    if (exports.DEBUG > 2) {
      sys.debug("<-" + JSON.stringify(data));
    }

    while (input.data.length > 0) {
      code = input.shift_code();
      len = input.shift_int32();
      stream = new bits.Decoder(input.shift_raw_string(len - 4));
      if (exports.DEBUG > 1) {
        sys.debug("stream: " + code + " " + JSON.stringify(stream));
      }
      command = parse_response(code, stream);
      if (command.type) {
        if (exports.DEBUG > 0) {
          sys.debug("Received " + command.type + ": " + JSON.stringify(command.args));
        }
        command.args.unshift(command.type);
        events.emit.apply(events, command.args);
      }
    }
  });
  connection.addListener("eof", function (data) {
    connection.close();
  });
  connection.addListener("disconnect", function (had_error) {
    if (had_error) {
      sys.debug("CONNECTION DIED WITH ERROR");
    }
  });

  // Set up callbacks to automatically do the login
  events.addListener('AuthenticationMD5Password', function (salt) {
    var result = "md5" + md5(md5(password + username) + salt);
    sendMessage('PasswordMessage', [result]);
  });
  events.addListener('AuthenticationCleartextPassword', function () {
    sendMessage('PasswordMessage', [password]);
  });
  events.addListener('ErrorResponse', function (e) {
    if (e.S === 'FATAL') {
      sys.debug(e.S + ": " + e.M);
      connection.close();
    }
  });
  events.addListener('ReadyForQuery', function () {
    if (query_queue.length > 0) {
      var query = query_queue.shift();
      query_callback = query.callback;
      sendMessage('Query', [query.sql]);
      readyState = false;
    } else {
      if (closeState) {
        connection.close();
      } else {
        readyState = true;
      }
    }
  });
  events.addListener("RowDescription", function (data) {
    row_description = data;
    results = [];
  });
  events.addListener("DataRow", function (data) {
    var row, i, l, description, value;
    row = {};
    l = data.length;
    for (i = 0; i < l; i += 1) {
      description = row_description[i];
      value = data[i];
      if (value !== null) {
        // TODO: investigate to see if these numbers are stable across databases or
        // if we need to dynamically pull them from the pg_types table
        switch (description.type_id) {
        case 16: // bool
          value = value === 't';
          break;
        case 20: // int8
        case 21: // int2
        case 23: // int4
          value = parseInt(value, 10);
          break;
        }
      }
      row[description.field] = value;
    }
    results.push(row);
  });
  events.addListener('CommandComplete', function (data) {
    query_callback.call(this, results);
  });

  this.query = function (sql, callback) {
    query_queue.push({sql: sql, callback: callback});
    if (readyState) {
      events.emit('ReadyForQuery');
    }
  };
  this.close = function () {
    closeState = true;
  };
};

<|endoftext|>


<commit_before>/*©agpl*************************************************************************
*                                                                              *
* This file is part of FRIEND UNIFYING PLATFORM.                               *
* Copyright (c) Friend Software Labs AS. All rights reserved.                  *
*                                                                              *
* Licensed under the Source EULA. Please refer to the copy of the GNU Affero   *
* General Public License, found in the file license_agpl.txt.                  *
*                                                                              *
*****************************************************************************©*/

Application.run = function( msg )
{
	this.sendMessage( { type: 'system', command: 'setsingleinstance', value: true } );

	var v = new View( {
		title: 'Friend Admin',
		width: 1280,
		height: 960
	} );

	var f = new File( 'Progdir:Templates/main.html' );
	f.onLoad = function( data )
	{
		v.setContent( data );
	}
	f.load();

	v.onClose = function()
	{
		Application.quit();
	}

}

<commit_msg>Just a start of the About page.<commit_after>/*©agpl*************************************************************************
*                                                                              *
* This file is part of FRIEND UNIFYING PLATFORM.                               *
* Copyright (c) Friend Software Labs AS. All rights reserved.                  *
*                                                                              *
* Licensed under the Source EULA. Please refer to the copy of the GNU Affero   *
* General Public License, found in the file license_agpl.txt.                  *
*                                                                              *
*****************************************************************************©*/

Application.run = function( msg )
{
	this.sendMessage( { type: 'system', command: 'setsingleinstance', value: true } );

	var v = new View( {
		title: 'Friend Admin',
		width: 1280,
		height: 960
	} );

	this.mainView = v;

	var f = new File( 'Progdir:Templates/main.html' );
	f.onLoad = function( data )
	{
		v.setContent( data );
	}
	f.load();

	v.onClose = function()
	{
		Application.quit();
	}

	v.setMenuItems( [
		{
			name: i18n( 'i18n_file' ),
			items: [
				{
					name: i18n( 'i18n_about' ),
					command: 'about'
				}
			]
		}
	] );

}

// Available functions
messageFunctions = {
	about( msg )
	{
		console.log( msg );
		return Application.mainView.sendMessage( {
			command: 'about'
		} );
	}
};

// Execute on received message
Application.receiveMessage = function( msg )
{
	if( !msg.command ) return;
	if( messageFunctions[ msg.command ] )
	{
		return messageFunctions[ msg.command ]( msg );
	}
	return false;
}

<|endoftext|>


<commit_before>/*
   Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.

   This file is licensed under the Apache License, Version 2.0 (the "License").
   You may not use this file except in compliance with the License. A copy of
   the License is located at

    http://aws.amazon.com/apache2.0/

   This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied. See the License for the
   specific language governing permissions and limitations under the License.

   ABOUT THIS NODE.JS SAMPLE: This sample is part of the SDK for JavaScript Developer Guide topic at
   https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/dynamodb-example-table-read-write.html
*/

// Load the AWS SDK for Node.js
var AWS = require('aws-sdk');
// Set the region
AWS.config.update({region: 'REGION'});

// Create DynamoDB service object
var ddb = new AWS.DynamoDB({apiVersion: '2012-08-10'});

var params = {
  TableName: 'TABLE',
  Key: {
    'KEY_NAME': {N: 'VALUE'}
  }};

ddb.deleteItem(params, function(err, data) {
  if (err) {
    console.log("Error", err);
  } else {
    console.log("Success", data);
  }
});
<commit_msg>Update ddb_deleteitem.js<commit_after>// Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// Licensed under the Apache-2.0 License on an "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND.

// ABOUT THIS NODE.JS SAMPLE: This sample is part of the SDK for JavaScript Developer Guide topic at
// https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/dynamodb-example-table-read-write.html
// Load the AWS SDK for Node.js
var AWS = require('aws-sdk');
// Set the region
AWS.config.update({region: 'REGION'});

// Create DynamoDB service object
var ddb = new AWS.DynamoDB({apiVersion: '2012-08-10'});

var params = {
  TableName: 'TABLE',
  Key: {
    'KEY_NAME': {N: 'VALUE'}
  }};

ddb.deleteItem(params, function(err, data) {
  if (err) {
    console.log("Error", err);
  } else {
    console.log("Success", data);
  }
});
<|endoftext|>


<commit_before>var ApolloLink = require("apollo-link").ApolloLink
var Observable = require("apollo-link").Observable
var printer = require("graphql/language/printer")

function ActionCableLink(options) {
  var cable = options.cable
  var channelName = options.channelName || "GraphqlChannel"
  var actionName = options.actionName || "execute"

  return new ApolloLink(function(operation) {
    return new Observable(function(observer) {
      var channelId = Math.round(Date.now() + Math.random() * 100000).toString(16)

      var subscription = cable.subscriptions.create({
        channel: channelName,
        channelId: channelId
      }, {
        connected: function() {
          this.perform(
            actionName,
            {
              query: operation.query ? printer.print(operation.query) : null,
              variables: operation.variables,
              operationId: operation.operationId,
              operationName: operation.operationName
            }
          )
        },
        received: function(payload) {
          if (payload.result.data) {
            observer.next(payload.result)
          }

          if (!payload.more) {
            this.unsubscribe()
            observer.complete()
          }
        }
      })

      return subscription
    })
  })
}

module.exports = ActionCableLink
<commit_msg>added connection params<commit_after>var ApolloLink = require("apollo-link").ApolloLink
var Observable = require("apollo-link").Observable
var printer = require("graphql/language/printer")

function ActionCableLink(options) {
  var cable = options.cable
  var channelName = options.channelName || "GraphqlChannel"
  var actionName = options.actionName || "execute"
  var connectionParams = options.connectionParams || {}

  return new ApolloLink(function(operation) {
    return new Observable(function(observer) {
      var channelId = Math.round(Date.now() + Math.random() * 100000).toString(16)

      var subscription = cable.subscriptions.create(Object.assign({},{
        channel: channelName,
        channelId: channelId
      }, connectionParams), {
        connected: function() {
          this.perform(
            actionName,
            {
              query: operation.query ? printer.print(operation.query) : null,
              variables: operation.variables,
              operationId: operation.operationId,
              operationName: operation.operationName
            }
          )
        },
        received: function(payload) {
          if (payload.result.data) {
            observer.next(payload.result)
          }

          if (!payload.more) {
            this.unsubscribe()
            observer.complete()
          }
        }
      })

      return subscription
    })
  })
}

module.exports = ActionCableLink
<|endoftext|>


<commit_before>var fs = require('fs')
var async = require('async')
var getAbi = require('node-abi').getAbi
var getTarget = require('node-abi').getTarget
var getTarPath = require('./util').getTarPath
var build = require('./build')
var strip = require('./strip')
var pack = require('./pack')

function prebuild (opts, target, runtime, callback) {
  var pkg = opts.pkg
  var buildLog = opts.buildLog || function () {}
  opts.target = target
  opts.runtime = runtime

  var buildLogMessage = 'Preparing to prebuild ' + pkg.name + '@' + pkg.version + ' for ' + runtime + ' ' + target + ' on ' + opts.platform + '-' + opts.arch + ' using ' + opts.backend
  if (opts.libc && opts.libc.length > 0) buildLogMessage += 'using libc ' + opts.libc
  buildLog(buildLogMessage)
  target = getTarget(target, runtime)
  var abi = getAbi(target, runtime)
  var tarPath = getTarPath(opts, abi)
  fs.stat(tarPath, function (err, st) {
    if (!err && !opts.force) {
      buildLog(tarPath + ' exists, skipping build')
      return callback(null, tarPath)
    }
    var tasks = [
      function (cb) {
        build(opts, target, function (err, filename) {
          if (err) return cb(err)
          cb(null, filename)
        })
      },
      function (filename, cb) {
        buildLog('Packing ' + filename + ' into ' + tarPath)
        pack(filename, tarPath, function (err) {
          if (err) return cb(err)
          buildLog('Prebuild written to ' + tarPath)
          cb(null, tarPath)
        })
      }
    ]

    if (opts.strip) {
      tasks.splice(1, 0, function (filename, cb) {
        buildLog('Stripping debug information from ' + filename)
        strip(filename, function (err) {
          if (err) return cb(err)
          cb(null, filename)
        })
      })
    }

    async.waterfall(tasks, callback)
  })
}

module.exports = prebuild
<commit_msg>comment<commit_after>var fs = require('fs')
var async = require('async')
var getAbi = require('node-abi').getAbi
var getTarget = require('node-abi').getTarget
var getTarPath = require('./util').getTarPath
var build = require('./build')
var strip = require('./strip')
var pack = require('./pack')

function prebuild (opts, target, runtime, callback) {
  var pkg = opts.pkg
  var buildLog = opts.buildLog || function () {}
  opts.target = target
  opts.runtime = runtime

  var buildLogMessage = 'Preparing to prebuild ' + pkg.name + '@' + pkg.version + ' for ' + runtime + ' ' + target + ' on ' + opts.platform + '-' + opts.arch + ' using ' + opts.backend
  if (opts.libc && opts.libc.length > 0) buildLogMessage += 'using libc ' + opts.libc
  buildLog(buildLogMessage)

  // --target can be target or abi
  target = getTarget(target, runtime)
  var abi = getAbi(target, runtime)

  var tarPath = getTarPath(opts, abi)
  fs.stat(tarPath, function (err, st) {
    if (!err && !opts.force) {
      buildLog(tarPath + ' exists, skipping build')
      return callback(null, tarPath)
    }
    var tasks = [
      function (cb) {
        build(opts, target, function (err, filename) {
          if (err) return cb(err)
          cb(null, filename)
        })
      },
      function (filename, cb) {
        buildLog('Packing ' + filename + ' into ' + tarPath)
        pack(filename, tarPath, function (err) {
          if (err) return cb(err)
          buildLog('Prebuild written to ' + tarPath)
          cb(null, tarPath)
        })
      }
    ]

    if (opts.strip) {
      tasks.splice(1, 0, function (filename, cb) {
        buildLog('Stripping debug information from ' + filename)
        strip(filename, function (err) {
          if (err) return cb(err)
          cb(null, filename)
        })
      })
    }

    async.waterfall(tasks, callback)
  })
}

module.exports = prebuild
<|endoftext|>


<commit_before>module.exports = [
  {
    name: 'GPRS',
    bandwidth: 50,
    rtt: 500
  },
  {
    name: 'Regular 2G',
    bandwidth: 250,
    rtt: 300
  },
  {
    name: 'Good 2G',
    bandwidth: 450,
    rtt: 150
  },
  {
    name: 'Regular 3G',
    bandwidth: 750,
    rtt: 100
  },
  {
    name: 'Good 3G',
    bandwidth: 1000,
    rtt: 40
  },
  {
    name: 'Regular 4G',
    bandwidth: 4000,
    rtt: 20
  }
]
<commit_msg>chore(profiles): Add 3G and 4G profiles<commit_after>module.exports = [
  {
    name: 'GPRS',
    bandwidth: 50,
    rtt: 500
  },
  {
    name: 'Regular 2G',
    bandwidth: 250,
    rtt: 300
  },
  {
    name: 'Good 2G',
    bandwidth: 450,
    rtt: 150
  },
  {
    name: 'Regular 3G',
    bandwidth: 750,
    rtt: 100
  },
  {
    name: 'Good 3G',
    bandwidth: 1000,
    rtt: 40
  },
  {
    name: 'Regular 4G',
    bandwidth: 4000,
    rtt: 20
  },

  // Based on Ofcom's research into the bandwidth and latency of 4G and 3G
  // networks in the UK in 2015
  // (see http://stakeholders.ofcom.org.uk/market-data-research/other/telecoms-research/broadband-speeds/mobile-bb-april-15/).
  //
  // Currently, µDL doesn't support configuring download and upload bandwidth.
  // As it's more likely that the user is downloading via µDL, use the download
  // bandwidth.
  {
    name: '4G (UK)',
    bandwidth: 14.7,
    // bandwidth: {
    //   download: 14.7,
    //   upload: 13.6
    //},
    rtt: 53.1
  },
  {
    name: '3G (UK)',
    bandwidth: 5.9,
    // bandwidth: {
    //   download: 5.9,
    //   upload: 1.6
    //},
    rtt: 63.5
  }
]
<|endoftext|>