<commit_before>'use strict';

var _ = require('lodash');

function RandomScenePlayer (elementManager) {
    this._playing = false;

    this._elementManager = elementManager;
    // holds tags assigned by setTagFilter
    this._manualTagFilter = [];
    // holds tags assigned by setThemeFilter
    this._themeTagFilter = [];

    // holds the unique'd version of both above, it's what actually gets checked
    this._tagFilter = [];

    this._videoPlaying = false;
}

function getRandomMediaObject(mediaScene, tagsArray, type) {
    var objs = filterMediaScene(mediaScene, tagsArray, type);
    return objs[Math.floor(Math.random() * objs.length)];
}

function filterMediaScene(mediaScene, tagsArray, mediaType) {
    return _.filter(mediaScene.scene, function (obj) {
        if ((tagsArray.length === 0 || _.intersection(obj.tags, tagsArray).length > 0 ) &&
            (! mediaType || obj.type === mediaType)) {
            return true;
        }
    });
}

function parseTagString (tagString) {
    return _.uniq(_.map(tagString.split(','), function(s) { return s.trim(); }));
}

function mergeFilters (self) {
    self._tagFilter = _.uniq(self._manualTagFilter.concat(self._themeTagFilter));
}

RandomScenePlayer.prototype.setScene = function(newScene) {
    var scene = _.cloneDeep(newScene);

    // best to parse the tag string up front, rather than every time a new media object is selected
    _.forEach(scene.scene, function(mediaObject) {
        mediaObject.tags = parseTagString(mediaObject.tags);
    });

    this._scene = scene;

    if (this._playing) {
        this.showNewMedia();
    }
};

RandomScenePlayer.prototype.setTagFilter = function(tagString) {
    tagString = tagString.trim();

    if (tagString !== '') {
        this._manualTagFilter = parseTagString(tagString);
    } else {
        this._manualTagFilter = [];
    }

    mergeFilters(this);
};

RandomScenePlayer.prototype.setThemeFilter = function(themeArray) {
    // concatenate the various tag strings of the themes
    if (themeArray.length > 0) {
        var themeTags = _.map(themeArray, function(theme) {
            return this._scene.themes[theme];
        }.bind(this)).join(',');

        this._themeTagFilter = parseTagString(themeTags);
    } else {
        this._themeTagFilter = [];
    }

    mergeFilters(this);
};

RandomScenePlayer.prototype.getRandomMediaObject = function(type) {
    return getRandomMediaObject(this._scene, this._tagFilter, type);
};

// returns true if there is 1 less than the maximum number of images currently
// being displayed
RandomScenePlayer.prototype.canShowImage = function() {
    var maxImages;
    // wrap in try catch incase attribute is missing from the json
    try {
        maxImages = this._scene.maximumOnScreen.images;
    } catch (e) {
        if (e instanceof TypeError) {
            console.log('missing maximumOnScreen.image in scene JSON, defaulting to 3');
        } else {
            throw e;
        }
    } finally {
        if (maxImages === null || maxImages === undefined || isNaN(maxImages)){
            maxImages = 3;
        }
    }

    return this._elementManager.getImageCount() < maxImages;
};

// returns the appropriate display duration (ms) for the passed in mediaObject
RandomScenePlayer.prototype.getDisplayDuration = function(mediaObject) {
    return 3000;
};

RandomScenePlayer.prototype.showNewImages = function() {
    var obj = this.getRandomMediaObject('image');
    if (obj && this.canShowImage()) {
        this._elementManager.showImage(obj.url, this.getDisplayDuration(obj), function() {
            this.showNewImages();
        }.bind(this));

        this.showNewImages();
    }
};

RandomScenePlayer.prototype.showNewVideo = function() {
    if (! this._videoPlaying) {
        var obj = this.getRandomMediaObject('video');
        if (obj) {
            this._videoPlaying = true;
            this._elementManager.showVideo(obj.url, function() {
                this._videoPlaying = false;
                this.showNewVideo();
            }.bind(this));
        }
    }

};

RandomScenePlayer.prototype.showNewMedia = function() {
    this.showNewImages();
    this.showNewVideo();

};

RandomScenePlayer.prototype.start = function() {
    if (! this._playing) {
        this._playing = true;

        this.showNewMedia();
    }
};

module.exports = function(elementManager) {
    return new RandomScenePlayer(elementManager);
};<commit_msg>mark internal methods for RandomScenePlayer with underscores #38<commit_after>'use strict';

var _ = require('lodash');

function RandomScenePlayer (elementManager) {
    this._playing = false;

    this._elementManager = elementManager;
    // holds tags assigned by setTagFilter
    this._manualTagFilter = [];
    // holds tags assigned by setThemeFilter
    this._themeTagFilter = [];

    // holds the unique'd version of both above, it's what actually gets checked
    this._tagFilter = [];

    this._videoPlaying = false;
}

function getRandomMediaObject(mediaScene, tagsArray, type) {
    var objs = filterMediaScene(mediaScene, tagsArray, type);
    return objs[Math.floor(Math.random() * objs.length)];
}

function filterMediaScene(mediaScene, tagsArray, mediaType) {
    return _.filter(mediaScene.scene, function (obj) {
        if ((tagsArray.length === 0 || _.intersection(obj.tags, tagsArray).length > 0 ) &&
            (! mediaType || obj.type === mediaType)) {
            return true;
        }
    });
}

function parseTagString (tagString) {
    return _.uniq(_.map(tagString.split(','), function(s) { return s.trim(); }));
}

function mergeFilters (self) {
    self._tagFilter = _.uniq(self._manualTagFilter.concat(self._themeTagFilter));
}

RandomScenePlayer.prototype.setScene = function(newScene) {
    var scene = _.cloneDeep(newScene);

    // best to parse the tag string up front, rather than every time a new media object is selected
    _.forEach(scene.scene, function(mediaObject) {
        mediaObject.tags = parseTagString(mediaObject.tags);
    });

    this._scene = scene;

    if (this._playing) {
        this._showNewMedia();
    }
};

RandomScenePlayer.prototype.setTagFilter = function(tagString) {
    tagString = tagString.trim();

    if (tagString !== '') {
        this._manualTagFilter = parseTagString(tagString);
    } else {
        this._manualTagFilter = [];
    }

    mergeFilters(this);
};

RandomScenePlayer.prototype.setThemeFilter = function(themeArray) {
    // concatenate the various tag strings of the themes
    if (themeArray.length > 0) {
        var themeTags = _.map(themeArray, function(theme) {
            return this._scene.themes[theme];
        }.bind(this)).join(',');

        this._themeTagFilter = parseTagString(themeTags);
    } else {
        this._themeTagFilter = [];
    }

    mergeFilters(this);
};

RandomScenePlayer.prototype.getRandomMediaObject = function(type) {
    return getRandomMediaObject(this._scene, this._tagFilter, type);
};

// returns true if there is 1 less than the maximum number of images currently
// being displayed
RandomScenePlayer.prototype.canShowImage = function() {
    var maxImages;
    // wrap in try catch incase attribute is missing from the json
    try {
        maxImages = this._scene.maximumOnScreen.images;
    } catch (e) {
        if (e instanceof TypeError) {
            console.log('missing maximumOnScreen.image in scene JSON, defaulting to 3');
        } else {
            throw e;
        }
    } finally {
        if (maxImages === null || maxImages === undefined || isNaN(maxImages)){
            maxImages = 3;
        }
    }

    return this._elementManager.getImageCount() < maxImages;
};

// returns the appropriate display duration (ms) for the passed in mediaObject
RandomScenePlayer.prototype._getDisplayDuration = function(mediaObject) {
    return 3000;
};

RandomScenePlayer.prototype._showNewImages = function() {
    var obj = this.getRandomMediaObject('image');
    if (obj && this.canShowImage()) {
        this._elementManager.showImage(obj.url, this._getDisplayDuration(obj), function() {
            this._showNewImages();
        }.bind(this));

        this._showNewImages();
    }
};

RandomScenePlayer.prototype._showNewVideo = function() {
    if (! this._videoPlaying) {
        var obj = this.getRandomMediaObject('video');
        if (obj) {
            this._videoPlaying = true;
            this._elementManager.showVideo(obj.url, function() {
                this._videoPlaying = false;
                this._showNewVideo();
            }.bind(this));
        }
    }

};

RandomScenePlayer.prototype._showNewText = function() {

};

RandomScenePlayer.prototype._showNewMedia = function() {
    this._showNewImages();
    this._showNewVideo();
    this._showNewText();
};

RandomScenePlayer.prototype.start = function() {
    if (! this._playing) {
        this._playing = true;

        this._showNewMedia();
    }
};

module.exports = function(elementManager) {
    return new RandomScenePlayer(elementManager);
};<|endoftext|>


<commit_before>(function () {
    'use strict';

    var DEFAULT_FEE_AMOUNT = '0.001';
    var FEE_CURRENCY = Currency.WAV;

    function WavesLeasingController ($scope, $timeout, constants, events, autocomplete, applicationContext,
                                     apiService, dialogService, notificationService, transactionBroadcast,
                                     formattingService, addressService, leasingRequestService) {
        var minimumFee = new Money(constants.MINIMUM_TRANSACTION_FEE, FEE_CURRENCY);

        var leasing = this;
        leasing.autocomplete = autocomplete;
        leasing.availableBalance = Money.fromCoins(0, Currency.WAV);
        leasing.broadcast = new transactionBroadcast.instance(apiService.leasing.lease,
            function (transaction, response) {
                var amount = Money.fromCoins(transaction.amount, Currency.WAV);
                var address = transaction.recipient;
                var displayMessage = 'Leased ' + amount.formatAmount(true) + ' of ' +
                    amount.currency.displayName +
                    '
Recipient ' + address.substr(0,15) + '...
Date: ' +
                    formattingService.formatTimestamp(transaction.timestamp);
                notificationService.notice(displayMessage);
            });
        leasing.validationOptions = {
            rules: {
                leasingRecipient: {
                    required: true,
                    address: true
                },
                leasingAmount: {
                    required: true,
                    decimal: 8, // stub value updated on validation
                    min: 0, // stub value updated on validation
                    max: constants.JAVA_MAX_LONG // stub value updated on validation
                },
                leasingFee: {
                    required: true,
                    decimal: Currency.WAV.precision,
                    min: minimumFee.toTokens()
                }
            },
            messages: {
                leasingRecipient: {
                    required: 'Recipient account number is required'
                },
                leasingAmount: {
                    required: 'Amount to lease is required'
                },
                leasingFee: {
                    required: 'Transaction fee is required',
                    decimal: 'Transaction fee must be with no more than ' +
                        minimumFee.currency.precision + ' digits after the decimal point (.)',
                    min: 'Transaction fee is too small. It should be greater or equal to ' +
                        minimumFee.formatAmount(true)
                }
            }
        };
        leasing.confirm = {
            recipient: ''
        };
        leasing.confirmLease = confirmLease;
        leasing.broadcastTransaction = broadcastTransaction;

        reset();

        $scope.$on(events.WALLET_LEASE, function (event, eventData) {
            //FIXME: add here a correct value available to lease
            leasing.availableBalance = eventData.balanceDetails.effective;

            reset();

            // update validation options and check how it affects form validation
            leasing.validationOptions.rules.leasingAmount.decimal = leasing.availableBalance.currency.precision;
            var minimumPayment = Money.fromCoins(1, leasing.availableBalance.currency);
            leasing.validationOptions.rules.leasingAmount.min = minimumPayment.toTokens();
            leasing.validationOptions.rules.leasingAmount.max = leasing.availableBalance.toTokens();
            leasing.validationOptions.messages.leasingAmount.decimal = 'The amount to leasing must be a number ' +
                'with no more than ' + minimumPayment.currency.precision +
                ' digits after the decimal point (.)';
            leasing.validationOptions.messages.leasingAmount.min = 'Leasing amount is too small. ' +
                'It should be greater or equal to ' + minimumPayment.formatAmount(false);
            leasing.validationOptions.messages.leasingAmount.max = 'Leasing amount is too big. ' +
                'It should be less or equal to ' + leasing.availableBalance.formatAmount(false);

            $timeout(function () {
                dialogService.open('#start-leasing-dialog');
            }, 1);
        });

        function confirmLease(form) {
            if (!form.validate(leasing.validationOptions))
                return false;

            var amount = Money.fromTokens(leasing.amount, leasing.availableBalance.currency);
            var transferFee = Money.fromTokens(leasing.autocomplete.getFeeAmount(), FEE_CURRENCY);

            // we assume here that amount and fee are in Waves, however it's not hardcoded
            var leasingCost = amount.plus(transferFee);
            if (leasingCost.greaterThan(leasing.availableBalance)) {
                notificationService.error('Not enough ' + FEE_CURRENCY.displayName + ' for the leasing transaction');

                return false;
            }

            var startLeasing = {
                recipient: addressService.cleanupOptionalPrefix(leasing.recipient),
                amount: amount,
                fee: transferFee
            };

            var sender = {
                publicKey: applicationContext.account.keyPair.public,
                privateKey: applicationContext.account.keyPair.private
            };

            // creating the transaction and waiting for confirmation
            leasing.broadcast.setTransaction(leasingRequestService.buildStartLeasingRequest(startLeasing, sender));

            // setting data for the confirmation dialog
            leasing.confirm.amount = startLeasing.amount;
            leasing.confirm.fee = startLeasing.fee;
            leasing.confirm.recipient = startLeasing.recipient;

            // open confirmation dialog
            // doing it async because this method is called while another dialog is open
            $timeout(function () {
                dialogService.open('#start-leasing-confirmation');
            }, 1);

            return true;
        }

        function broadcastTransaction() {
            leasing.broadcast.broadcast();
        }

        function reset() {
            leasing.amount = Money.fromTokens(0, Currency.WAV);
            leasing.recipient = '';
            leasing.fee = Money.fromTokens(DEFAULT_FEE_AMOUNT, FEE_CURRENCY);
            leasing.autocomplete.defaultFee(Number(DEFAULT_FEE_AMOUNT));
        }
    }

    WavesLeasingController.$inject = ['$scope', '$timeout', 'constants.ui', 'wallet.events', 'autocomplete.fees',
        'applicationContext', 'apiService', 'dialogService', 'notificationService', 'transactionBroadcast',
        'formattingService', 'addressService', 'leasingRequestService'];

    angular
        .module('app.wallet')
        .controller('leasingController', WavesLeasingController);
})();
<commit_msg>Fixed leasing amount reset bug<commit_after>(function () {
    'use strict';

    var DEFAULT_FEE_AMOUNT = '0.001';
    var FEE_CURRENCY = Currency.WAV;

    function WavesLeasingController ($scope, $timeout, constants, events, autocomplete, applicationContext,
                                     apiService, dialogService, notificationService, transactionBroadcast,
                                     formattingService, addressService, leasingRequestService) {
        var minimumFee = new Money(constants.MINIMUM_TRANSACTION_FEE, FEE_CURRENCY);

        var leasing = this;
        leasing.autocomplete = autocomplete;
        leasing.availableBalance = Money.fromCoins(0, Currency.WAV);
        leasing.broadcast = new transactionBroadcast.instance(apiService.leasing.lease,
            function (transaction, response) {
                var amount = Money.fromCoins(transaction.amount, Currency.WAV);
                var address = transaction.recipient;
                var displayMessage = 'Leased ' + amount.formatAmount(true) + ' of ' +
                    amount.currency.displayName +
                    '
Recipient ' + address.substr(0,15) + '...
Date: ' +
                    formattingService.formatTimestamp(transaction.timestamp);
                notificationService.notice(displayMessage);
            });
        leasing.validationOptions = {
            rules: {
                leasingRecipient: {
                    required: true,
                    address: true
                },
                leasingAmount: {
                    required: true,
                    decimal: 8, // stub value updated on validation
                    min: 0, // stub value updated on validation
                    max: constants.JAVA_MAX_LONG // stub value updated on validation
                },
                leasingFee: {
                    required: true,
                    decimal: Currency.WAV.precision,
                    min: minimumFee.toTokens()
                }
            },
            messages: {
                leasingRecipient: {
                    required: 'Recipient account number is required'
                },
                leasingAmount: {
                    required: 'Amount to lease is required'
                },
                leasingFee: {
                    required: 'Transaction fee is required',
                    decimal: 'Transaction fee must be with no more than ' +
                        minimumFee.currency.precision + ' digits after the decimal point (.)',
                    min: 'Transaction fee is too small. It should be greater or equal to ' +
                        minimumFee.formatAmount(true)
                }
            }
        };
        leasing.confirm = {
            recipient: ''
        };
        leasing.confirmLease = confirmLease;
        leasing.broadcastTransaction = broadcastTransaction;

        reset();

        $scope.$on(events.WALLET_LEASE, function (event, eventData) {
            //FIXME: add here a correct value available to lease
            leasing.availableBalance = eventData.balanceDetails.effective;

            reset();

            // update validation options and check how it affects form validation
            leasing.validationOptions.rules.leasingAmount.decimal = leasing.availableBalance.currency.precision;
            var minimumPayment = Money.fromCoins(1, leasing.availableBalance.currency);
            leasing.validationOptions.rules.leasingAmount.min = minimumPayment.toTokens();
            leasing.validationOptions.rules.leasingAmount.max = leasing.availableBalance.toTokens();
            leasing.validationOptions.messages.leasingAmount.decimal = 'The amount to leasing must be a number ' +
                'with no more than ' + minimumPayment.currency.precision +
                ' digits after the decimal point (.)';
            leasing.validationOptions.messages.leasingAmount.min = 'Leasing amount is too small. ' +
                'It should be greater or equal to ' + minimumPayment.formatAmount(false);
            leasing.validationOptions.messages.leasingAmount.max = 'Leasing amount is too big. ' +
                'It should be less or equal to ' + leasing.availableBalance.formatAmount(false);

            $timeout(function () {
                dialogService.open('#start-leasing-dialog');
            }, 1);
        });

        function confirmLease(form) {
            if (!form.validate(leasing.validationOptions))
                return false;

            var amount = Money.fromTokens(leasing.amount, leasing.availableBalance.currency);
            var transferFee = Money.fromTokens(leasing.autocomplete.getFeeAmount(), FEE_CURRENCY);

            // we assume here that amount and fee are in Waves, however it's not hardcoded
            var leasingCost = amount.plus(transferFee);
            if (leasingCost.greaterThan(leasing.availableBalance)) {
                notificationService.error('Not enough ' + FEE_CURRENCY.displayName + ' for the leasing transaction');

                return false;
            }

            var startLeasing = {
                recipient: addressService.cleanupOptionalPrefix(leasing.recipient),
                amount: amount,
                fee: transferFee
            };

            var sender = {
                publicKey: applicationContext.account.keyPair.public,
                privateKey: applicationContext.account.keyPair.private
            };

            // creating the transaction and waiting for confirmation
            leasing.broadcast.setTransaction(leasingRequestService.buildStartLeasingRequest(startLeasing, sender));

            // setting data for the confirmation dialog
            leasing.confirm.amount = startLeasing.amount;
            leasing.confirm.fee = startLeasing.fee;
            leasing.confirm.recipient = startLeasing.recipient;

            // open confirmation dialog
            // doing it async because this method is called while another dialog is open
            $timeout(function () {
                dialogService.open('#start-leasing-confirmation');
            }, 1);

            return true;
        }

        function broadcastTransaction() {
            leasing.broadcast.broadcast();
        }

        function reset() {
            leasing.amount = '0';
            leasing.recipient = '';
            leasing.confirm.amount = Money.fromTokens(0, Currency.WAV);
            leasing.confirm.fee = Money.fromTokens(DEFAULT_FEE_AMOUNT, FEE_CURRENCY);
            leasing.autocomplete.defaultFee(Number(DEFAULT_FEE_AMOUNT));
        }
    }

    WavesLeasingController.$inject = ['$scope', '$timeout', 'constants.ui', 'wallet.events', 'autocomplete.fees',
        'applicationContext', 'apiService', 'dialogService', 'notificationService', 'transactionBroadcast',
        'formattingService', 'addressService', 'leasingRequestService'];

    angular
        .module('app.wallet')
        .controller('leasingController', WavesLeasingController);
})();
<|endoftext|>


<commit_before>var AnatoliaList = {
    render: function (state) {
        var cc = Component.createElement;

        var container = cc(state.containerElementName);
        var firstRow = cc("div", {class: "row clearfix"});

        var ul = cc("ul", {class: state.class});

        state.list.forEach(function (listItem) {
            var li = cc("li", {class: "list-group-item", text: listItem.text});

            ul.append(li);
        });

        firstRow.append(ul);

        var secondRow = cc("div", {class: "row clearfix", style: "margin-top: 30px;"});
        var pushButton = cc("a", {class: "btn btn-success", text: "PUSH", id: "pushButton"});
        var popButton = cc("a", {class: "btn btn-danger", text: "POP", id: "popButton"});

        secondRow.append(pushButton);
        secondRow.append(popButton);

        container.append(secondRow);
        container.append(firstRow);

        return container;
    }
};

<commit_msg>anatolia list 1.0.0<commit_after>/**
 * Anatolia List Component.
 * Returns <ul> instance.
 *
 * @summary creates a <ul> element
 * @author Güner Kaan ALKIM <g.kaanalkim@gmail.com>
 * @version 1.0.0
 *
 * @param {object}  state                           - Contains list 's items and class attribute
 * @param {string}  state.class                     - List container(ul) class attribute
 * @param {array}   state.items                     - Defines list items
 * @param {string}  state.items[0].class            - List item class
 * @param {string}  state.items[0].text             - List item text content
 * **/

'use strict';

var AnatoliaList = function (state) {
    //  Toolkit declarations
    var create = Component.createElement;
    var is = Util.is;

    //  Attributes declarations
    var parentAttributes = state.attributes.parent;
    var itemAttributes = state.attributes.item;

    //  List container declaration
    var listContainer = create("ul");

    //  Attribute assignment
    if (is.defined(parentAttributes) && is.not.null(parentAttributes) && is.object(parentAttributes)) {
        for (var name in parentAttributes) {
            listContainer.setAttribute(name, parentAttributes[name]);
        }
    }

    //  List items declarations
    var listItems = state.items;

    if (is.defined(listItems) && is.not.null(listItems) && is.array(listItems)) {
        listItems.forEach(function (listItem) {
            var listItemElement = create("li", {
                text: listItem.text
            });

            //  Attribute assignment
            if (is.defined(itemAttributes) && is.not.null(itemAttributes) && is.object(itemAttributes)) {
                for (var name in itemAttributes) {
                    listItemElement.setAttribute(name, itemAttributes[name]);
                }
            }

            listContainer.append(listItemElement);
        });
    }

    return listContainer;
};

<|endoftext|>


<commit_before>/*
adapted from https://gist.github.com/matthiasg/56b5915c61cbc6a384d9

from https://gist.github.com/adactio/fbaa3a5952774553f5e7

https://googlechrome.github.io/samples/service-worker/custom-offline-page/
https://github.com/phamann/embrace-the-network/blob/master/src/stale-while-revalidate/sw.js
https://github.com/GoogleChrome/sw-toolbox#defining-routes
https://github.com/mozilla/serviceworker-cookbook/tree/master/virtual-server

OTHER:
https://googlechrome.github.io/samples/service-worker/post-message/index.html

https://serviceworke.rs/

*/

// Update 'version' if you need to refresh the cache
var staticCacheName = 'static';
var version = 'v1.0.7::';
var CACHE = version + staticCacheName;
var timeout = 1500;

var staticCacheList = [
  './',
  './login/',
  './images/launcher-icon-3x.png',
  './css/raleway.css',
  './css/flickity.css',
  './css/bootstrap.3.3.4.min.css',
  './css/skeleton.css',
  './css/cents.css',
  './css/font-awesome.min.css',
  './fonts/fontawesome-webfont.woff?v=4.4.0',
  './fonts/-_Ctzj9b56b8RgXW8FAriQzyDMXhdD8sAj6OAJTFsBI.woff2 ',
  './js/jquery.2.1.3.min.js',
  './js/flickity.pkgd.js',
  './js/highcharts.4.2.2.js',
  './js/moment.2.18.1.min.js',
  './js/accountData.js',
  './js/popup.js',
  './js/app.js',
  './offline.html'
];

self.addEventListener('activate', function (event) {
  event.waitUntil(clearStaleCaches());
});

self.addEventListener('install', function (event) {
  event.waitUntil(updateStaticCache());
});

self.addEventListener('fetch', fetchHandler);
//self.addEventListener('fetch', serveCacheAndUpdate); //alternate

// --- FUNCTION DEFS -----------------------------------------------------------
// (will be hoisted because using function keyword)

// Store core files in a cache (including a page to display when offline)
function updateStaticCache() {
  return caches.open(version + staticCacheName)
    .then(function (cache) {
      return cache.addAll(staticCacheList);
    });
}

function clearStaleCaches(){
  return caches.keys()
    .then(function (keys) {
      // Remove caches whose name is no longer valid
      return Promise.all(keys
        .filter(function (key) {
          return key.indexOf(version) !== 0;
        })
        .map(function (key) {
          return caches.delete(key);
        })
      );
    });
}

function offlineResponse(request){
  // If the request is for an image, show an offline placeholder
  // if (!!~request.headers.get('Accept').indexOf('image')) {
  //   return new Response('<svg width="400" height="300" role="img" aria-labelledby="offline-title" viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg"><title id="offline-title">Offline</title><g fill="none" fill-rule="evenodd"><path fill="#D8D8D8" d="M0 0h400v300H0z"/><text fill="#9B9B9B" font-family="Helvetica Neue,Arial,Helvetica,sans-serif" font-size="72" font-weight="bold"><tspan x="93" y="172">offline</tspan></text></g></svg>', { headers: { 'Content-Type': 'image/svg+xml' } });
  // }

  if(!!~request.headers.get('Accept').indexOf('application/json')){
    const fallbackResponse = {
      error: "offline"
    };
    const jsonResponse = new Response(JSON.stringify(fallbackResponse), {
      headers: {'Content-Type': 'application/json'}
    });
    return jsonResponse;
  }
  const htmlResponse = caches.match('./offline.html');
  return htmlResponse;
}

function fetchHandler(event){
  var request = event.request;

  const isHTMLRequest = !!~request.headers.get('Accept').indexOf('text/html');
  const isJSONRequest = !!~request.headers.get('Accept').indexOf('application/json');

  const staticCacheMatches = staticCacheList
    .map(item => item.replace(/^./, ''))
    .filter(x => x !== '/');
  const urlInStatic = request.url === `${self.location.origin}/` || staticCacheMatches.some(m => {
    return request.url.includes(m);
  });
  if(urlInStatic){
    event.respondWith(fromCache(request));
    return;
  }

  // non-GET requests, -> NETWORK -> OFFLINE
  if (request.method !== 'GET') {
    event.respondWith(
      fromNetwork(request, timeout)
        .catch(function () {
          return offlineResponse(request);
        })
    );
    return;
  }

  // HTML requests, -> NETWORK -> CACHE -> OFFLINE
  if (isHTMLRequest || isJSONRequest) {
    event.respondWith(
      fromNetwork(request, timeout)
        .catch(function () {
          return fromCache(request);
        })
    );
    return;
  }

  // non-HTML requests, CACHE -> NETWORK -> OFFLINE
  event.respondWith(
    caches.match(request)
      .then(function (response) {
        return response || fromNetwork(request, timeout)
          .catch(function () {
            return offlineResponse(request);
          })
      })
  );
}

function fromNetwork(request, timeout) {
  return new Promise(function (fulfill, reject) {
    var timeoutId = setTimeout(reject, timeout);

    fetch(request).then(function (response) {
      clearTimeout(timeoutId);
      // Stash a copy of this page in the cache
      // tag as cached if json
      var clone = response.clone();
      const isJSONRequest = !!~request.headers.get('Accept').indexOf('application/json');

      if(request.method !== 'GET'){
        fulfill(response);
        return;
      }

      if(isJSONRequest){
        clone.json().then(json => {
          json.cached = true;
          var jsonRes = new Response(JSON.stringify(json), {
            headers: {
              'content-type': 'application/json'
            }
          });
          caches.open(version + staticCacheName)
          .then(function (cache) {
            cache.put(request, jsonRes);
          });
          fulfill(response);
        });
        return;
      }

      caches.open(version + staticCacheName)
        .then(function (cache) {
          cache.put(request, clone);
        });
      fulfill(response);
    }, reject);
  });
}

// https://serviceworke.rs/strategy-cache-update-and-refresh_demo.html
function serveCacheAndUpdate(event){
  var request = event.request;

  event.respondWith(fromCache(request));
  event.waitUntil(
    update(request)
    .then(refresh)
  );
}

// Open the cache where the assets were stored and search for the requested
// resource. Notice that in case of no matching, the promise still resolves
// but it does with `undefined` as value.
function fromCache(request) {
  return caches.open(CACHE)
    .then(function (cache) {
      return cache.match(request) || offlineResponse(request);
  });
}

// Update consists in opening the cache, performing a network request and
// storing the new response data.
function update(request) {
  return caches.open(CACHE).then(function (cache) {
    return fetch(request).then(function (response) {
      return cache.put(request, response.clone()).then(function () {
        return response;
      });
    });
  });
}

// Sends a message to the clients.
function refresh(response) {
  return self.clients.matchAll().then(function (clients) {
    clients.forEach(function (client) {
      // Encode which resource has been updated. By including the
      // [ETag](https://en.wikipedia.org/wiki/HTTP_ETag) the client can
      // check if the content has changed.
      var message = {
        type: 'refresh',
        url: response.url,
        // Notice not all servers return the ETag header. If this is not
        // provided you should use other cache headers or rely on your own
        // means to check if the content has changed.
        eTag: response.headers.get('ETag')
      };
      // Tell the client about the update.
      client.postMessage(JSON.stringify(message));
    });
  });
}

<commit_msg>fix login problem<commit_after>/*
adapted from https://gist.github.com/matthiasg/56b5915c61cbc6a384d9

from https://gist.github.com/adactio/fbaa3a5952774553f5e7

https://googlechrome.github.io/samples/service-worker/custom-offline-page/
https://github.com/phamann/embrace-the-network/blob/master/src/stale-while-revalidate/sw.js
https://github.com/GoogleChrome/sw-toolbox#defining-routes
https://github.com/mozilla/serviceworker-cookbook/tree/master/virtual-server

OTHER:
https://googlechrome.github.io/samples/service-worker/post-message/index.html

https://serviceworke.rs/

*/

// Update 'version' if you need to refresh the cache
var staticCacheName = 'static';
var version = 'v1.0.7::';
var CACHE = version + staticCacheName;
var timeout = 1500;

var staticCacheList = [
  './',
  './login/',
  './images/launcher-icon-3x.png',
  './css/raleway.css',
  './css/flickity.css',
  './css/bootstrap.3.3.4.min.css',
  './css/skeleton.css',
  './css/cents.css',
  './css/font-awesome.min.css',
  './fonts/fontawesome-webfont.woff?v=4.4.0',
  './fonts/-_Ctzj9b56b8RgXW8FAriQzyDMXhdD8sAj6OAJTFsBI.woff2 ',
  './js/jquery.2.1.3.min.js',
  './js/flickity.pkgd.js',
  './js/highcharts.4.2.2.js',
  './js/moment.2.18.1.min.js',
  './js/accountData.js',
  './js/popup.js',
  './js/app.js',
  './offline.html'
];

self.addEventListener('activate', function (event) {
  event.waitUntil(clearStaleCaches());
});

self.addEventListener('install', function (event) {
  event.waitUntil(updateStaticCache());
});

self.addEventListener('fetch', fetchHandler);
//self.addEventListener('fetch', serveCacheAndUpdate); //alternate

// --- FUNCTION DEFS -----------------------------------------------------------
// (will be hoisted because using function keyword)

// Store core files in a cache (including a page to display when offline)
function updateStaticCache() {
  return caches.open(version + staticCacheName)
    .then(function (cache) {
      return cache.addAll(staticCacheList);
    });
}

function clearStaleCaches(){
  return caches.keys()
    .then(function (keys) {
      // Remove caches whose name is no longer valid
      return Promise.all(keys
        .filter(function (key) {
          return key.indexOf(version) !== 0;
        })
        .map(function (key) {
          return caches.delete(key);
        })
      );
    });
}

function offlineResponse(request){
  // If the request is for an image, show an offline placeholder
  // if (!!~request.headers.get('Accept').indexOf('image')) {
  //   return new Response('<svg width="400" height="300" role="img" aria-labelledby="offline-title" viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg"><title id="offline-title">Offline</title><g fill="none" fill-rule="evenodd"><path fill="#D8D8D8" d="M0 0h400v300H0z"/><text fill="#9B9B9B" font-family="Helvetica Neue,Arial,Helvetica,sans-serif" font-size="72" font-weight="bold"><tspan x="93" y="172">offline</tspan></text></g></svg>', { headers: { 'Content-Type': 'image/svg+xml' } });
  // }

  if(!!~request.headers.get('Accept').indexOf('application/json')){
    const fallbackResponse = {
      error: "offline"
    };
    const jsonResponse = new Response(JSON.stringify(fallbackResponse), {
      headers: {'Content-Type': 'application/json'}
    });
    return jsonResponse;
  }
  const htmlResponse = caches.match('./offline.html');
  return htmlResponse;
}

function fetchHandler(event){
  var request = event.request;
  const isHTMLRequest = !!~request.headers.get('Accept').indexOf('text/html');
  const isJSONRequest = !!~request.headers.get('Accept').indexOf('application/json');

  // non-GET requests, -> NETWORK -> OFFLINE
  if (request.method !== 'GET') {
    event.respondWith(
      fromNetwork(request, timeout)
        .catch(function () {
          return offlineResponse(request);
        })
    );
    return;
  }

  // always return cached static GETs
  const staticCacheMatches = staticCacheList
  .map(item => item.replace(/^./, ''))
  .filter(x => x !== '/');
  const urlInStatic = request.url === `${self.location.origin}/` || staticCacheMatches.some(m => {
    return request.url.includes(m);
  });
  if(urlInStatic){
    event.respondWith(fromCache(request));
    return;
  }

  // HTML requests, -> NETWORK -> CACHE -> OFFLINE
  if (isHTMLRequest || isJSONRequest) {
    event.respondWith(
      fromNetwork(request, timeout)
        .catch(function () {
          return fromCache(request);
        })
    );
    return;
  }

  // non-HTML requests, CACHE -> NETWORK -> OFFLINE
  event.respondWith(
    caches.match(request)
      .then(function (response) {
        return response || fromNetwork(request, timeout)
          .catch(function () {
            return offlineResponse(request);
          })
      })
  );
}

function fromNetwork(request, timeout) {
  return new Promise(function (fulfill, reject) {
    var timeoutId = setTimeout(reject, timeout);

    fetch(request).then(function (response) {
      clearTimeout(timeoutId);
      // Stash a copy of this page in the cache
      // tag as cached if json
      var clone = response.clone();
      const isJSONRequest = !!~request.headers.get('Accept').indexOf('application/json');

      if(request.method !== 'GET'){
        fulfill(response);
        return;
      }

      if(isJSONRequest){
        clone.json().then(json => {
          json.cached = true;
          var jsonRes = new Response(JSON.stringify(json), {
            headers: {
              'content-type': 'application/json'
            }
          });
          caches.open(version + staticCacheName)
          .then(function (cache) {
            cache.put(request, jsonRes);
          });
          fulfill(response);
        });
        return;
      }

      caches.open(version + staticCacheName)
        .then(function (cache) {
          cache.put(request, clone);
        });
      fulfill(response);
    }, reject);
  });
}

// https://serviceworke.rs/strategy-cache-update-and-refresh_demo.html
function serveCacheAndUpdate(event){
  var request = event.request;

  event.respondWith(fromCache(request));
  event.waitUntil(
    update(request)
    .then(refresh)
  );
}

// Open the cache where the assets were stored and search for the requested
// resource. Notice that in case of no matching, the promise still resolves
// but it does with `undefined` as value.
function fromCache(request) {
  return caches.open(CACHE)
    .then(function (cache) {
      return cache.match(request) || offlineResponse(request);
  });
}

// Update consists in opening the cache, performing a network request and
// storing the new response data.
function update(request) {
  return caches.open(CACHE).then(function (cache) {
    return fetch(request).then(function (response) {
      return cache.put(request, response.clone()).then(function () {
        return response;
      });
    });
  });
}

// Sends a message to the clients.
function refresh(response) {
  return self.clients.matchAll().then(function (clients) {
    clients.forEach(function (client) {
      // Encode which resource has been updated. By including the
      // [ETag](https://en.wikipedia.org/wiki/HTTP_ETag) the client can
      // check if the content has changed.
      var message = {
        type: 'refresh',
        url: response.url,
        // Notice not all servers return the ETag header. If this is not
        // provided you should use other cache headers or rely on your own
        // means to check if the content has changed.
        eTag: response.headers.get('ETag')
      };
      // Tell the client about the update.
      client.postMessage(JSON.stringify(message));
    });
  });
}

<|endoftext|>


<commit_before>import jspm from 'jspm';
import whacko from 'whacko';
import fs from 'fs';
import path from 'path';
import * as log from '../logger';
import globby from 'globby';
import utils from 'systemjs-builder/lib/utils';

export function bundleTemplate(pattern, fileName, options, bundleOpts) {
  var templates = [];
  var builder = new jspm.Builder();
  var baseURL = builder.loader.baseURL;
  var cwd = utils.fromFileURL(baseURL);;
  var outfile = path.resolve(utils.fromFileURL(baseURL), fileName);

  if (fs.existsSync(outfile)) {
    if (!bundleOpts.force) {
      log.err('A bundle named `' + outfile + '` is already exists. Use --force to overwrite.');
      return;
    }
    fs.unlinkSync(outfile);
  }

  globby
    .sync(pattern, {
      cwd: cwd.replace(/\\/g, '/')
    })
    .forEach(function(file) {
      file = path.resolve(cwd, file);
      var content = fs.readFileSync(file, {
        encoding: 'utf8'
      });

      var $ = whacko.load(content);
      var name = getCanonicalName(builder, file, 'view');

      $('template').attr('id', name);
      var template = $.html('template');
      templates.push(template);
    });

  fs.writeFileSync(outfile, templates.join('\n'));

  if (options.inject) {
    injectLink(outfile, utils.fromFileURL(baseURL), options.inject.indexFile);
  }
}

function injectLink(outfile, baseURL, fileName) {
  var link = '';
  var bundle = path.resolve(baseURL, path.relative(baseURL, outfile));

  var index = path.resolve(baseURL, fileName || 'index.html');
  var relpath = path.relative(path.dirname(index), path.dirname(bundle)).replace(/\\/g, '/');

  if (!relpath.startsWith('.')) {
    link = relpath ? './' + relpath + '/' + path.basename(bundle) : './' + path.basename(bundle);
  } else {
    link = relpath + '/' + path.basename(bundle);
  }

  var content = fs.readFileSync(index, {
    encoding: 'utf8'
  });

  var $ = whacko.load(content);

  if ($('link[aurelia-view-bundle][href="' + link + '"]').length === 0) {
    $('body').append('<link aurelia-view-bundle rel="import" href="' + link + '">');
  }

  fs.writeFileSync(index, $.html());
}

function getCanonicalName(builder, file, pluginName) {
  return builder.getCanonicalName(utils.toFileURL(file) + '!' + pluginName);
}
<commit_msg>feat(template bundle): support for creating a new html file with the injected link and not writing it into the original index.html #126<commit_after>import jspm from 'jspm';
import whacko from 'whacko';
import fs from 'fs';
import path from 'path';
import * as log from '../logger';
import globby from 'globby';
import utils from 'systemjs-builder/lib/utils';

export function bundleTemplate(pattern, fileName, options, bundleOpts) {
  var templates = [];
  var builder = new jspm.Builder();
  var baseURL = builder.loader.baseURL;
  var cwd = utils.fromFileURL(baseURL);;
  var outfile = path.resolve(utils.fromFileURL(baseURL), fileName);

  if (fs.existsSync(outfile)) {
    if (!bundleOpts.force) {
      log.err('A bundle named `' + outfile + '` is already exists. Use --force to overwrite.');
      return;
    }
    fs.unlinkSync(outfile);
  }

  globby
    .sync(pattern, {
      cwd: cwd.replace(/\\/g, '/')
    })
    .forEach(function(file) {
      file = path.resolve(cwd, file);
      var content = fs.readFileSync(file, {
        encoding: 'utf8'
      });

      var $ = whacko.load(content);
      var name = getCanonicalName(builder, file, 'view');

      $('template').attr('id', name);
      var template = $.html('template');
      templates.push(template);
    });

  fs.writeFileSync(outfile, templates.join('\n'));

  if (options.inject) {
    injectLink(outfile, utils.fromFileURL(baseURL), options.inject);
  }
}

function injectLink(outfile, baseURL, injectOptions) {
  var link = '';
  var fileName = injectOptions.indexFile;
  var bundle = path.resolve(baseURL, path.relative(baseURL, outfile));
  var index = path.resolve(baseURL, fileName || 'index.html');
  var destFile = injectOptions.destFile ? path.resolve(baseURL, injectOptions.destFile) : index;

  var relpath = path.relative(path.dirname(index), path.dirname(bundle)).replace(/\\/g, '/');

  if (!relpath.startsWith('.')) {
    link = relpath ? './' + relpath + '/' + path.basename(bundle) : './' + path.basename(bundle);
  } else {
    link = relpath + '/' + path.basename(bundle);
  }

  var content = fs.readFileSync(index, {
    encoding: 'utf8'
  });

  var $ = whacko.load(content);

  if ($('link[aurelia-view-bundle][href="' + link + '"]').length === 0) {
    $('body').append('<link aurelia-view-bundle rel="import" href="' + link + '">');
  }

  fs.writeFileSync(destFile, $.html());
}

function getCanonicalName(builder, file, pluginName) {
  return builder.getCanonicalName(utils.toFileURL(file) + '!' + pluginName);
}
<|endoftext|>


<commit_before>const cmd = require('node-cmd')

this.info = {
  aliases: [
    'gitpull'
  ],
  helpInfo: {
    show: false,
    catagory: 'TEMPLATE',
    name: 'Template',
    usage: 'temp [template]',
    desc: 'Templates a template'
  }
}

this.Command = function (data) {
  if (data.message.member.hasPermission('ADMINISTRATOR')) {
    console.log(`[STATS] ${data.user.username}#${data.user.discriminator} has checked for the bot's status`)
    cmd.run('git pull')
    cmd.run('npm install')
    return 'Pulling'
  } else {
    return 'Hey! You can\'t do that!'
  }
}
<commit_msg>Updated log on !pull<commit_after>const cmd = require('node-cmd')

this.info = {
  aliases: [
    'gitpull'
  ],
  helpInfo: {
    show: false,
    catagory: 'TEMPLATE',
    name: 'Template',
    usage: 'temp [template]',
    desc: 'Templates a template'
  }
}

this.Command = function (data) {
  if (data.message.member.hasPermission('ADMINISTRATOR')) {
    console.log(`[GIT] ${data.user.username}#${data.user.discriminator} ran git pull`)
    cmd.run('git pull')
    cmd.run('npm install')
    return 'Pulling'
  } else {
    return 'Hey! You can\'t do that!'
  }
}
<|endoftext|>


<commit_before>/*renders a colored panel*/
import React, { Component } from 'react';

class Panel extends React.Component{
  constructor(props){
    super(props);
  }
  toggleOn(){
    console.log('panel ' + this.props.id + ' turned on!');
  }
  toggleOff(){
    console.log('panel ' + this.props.id + ' turned off!');
  }
  render(){
    if(this.props.panelClicked === this.props.id){
      console.log('red panel was clicked and is now on');
      return (

 this.props.onPanelUnClick(this) } onMouseLeave={ () => this.props.onPanelUnClick(this) } >

This is panel #{this.props.id}

      );
    }
    else{
      return (

 this.props.onPanelClick(this) } >

This is panel #{this.props.id}

      );
    }

  }
}

export default Panel;
<commit_msg>Play correct sound when clicking on associated panel<commit_after>/*renders a colored panel*/
import React, { Component } from 'react';

class Panel extends React.Component{
  constructor(props){
    super(props);
    this.panelSound = new Audio();
  }
  toggleOn(){
    const sound1 = "media/simonSound1.mp3",
        sound2 = "media/simonSound2.mp3",
        sound3 = "media/simonSound3.mp3",
        sound4 = "media/simonSound4.mp3";
    let currentSound = "";

        switch(this.props.id){
            case "green":
                currentSound = sound1;
                break;
            case "red":
                currentSound = sound2;
                break;
            case "blue":
                currentSound = sound3;
                break;
            case "yellow":
                currentSound = sound4;
                break;
            default:
                console.log("WRONG ID FOR PANEL! CAN'T PLAY SOUND!");
        }
        this.panelSound.src = currentSound;

    this.panelSound.play();

    console.log('panel ' + this.props.id + ' turned on!');
  }
  toggleOff(){
    console.log('panel ' + this.props.id + ' turned off!');
  }
  render(){
    if(this.props.panelClicked === this.props.id){
      console.log('red panel was clicked and is now on');
      return (

 this.props.onPanelUnClick(this) } onMouseLeave={ () => this.props.onPanelUnClick(this) } >

This is panel #{this.props.id}

      );
    }
    else{
      return (

 this.props.onPanelClick(this) } >

This is panel #{this.props.id}

      );
    }

  }
}

export default Panel;
<|endoftext|>


<commit_before>function getter(instance, path, unboundFn) {
  if (!path) return instance;
  var element = path.split('.');
  var key;
  var lastInstance = instance;
  var len = element.length;
  for ( var i = 0; i < len; i++) {
    key = element[i];
    if (!key.match(/^[\$\w][\$\w\d]*$/))
        throw "Expression '" + path + "' is not a valid expression for accesing variables.";
    if (instance) {
      lastInstance = instance;
      instance = instance[key];
    }
    if (isUndefined(instance)  && key.charAt(0) == '$') {
      var type = angular['Global']['typeOf'](lastInstance);
      type = angular[type.charAt(0).toUpperCase()+type.substring(1)];
      var fn = type ? type[[key.substring(1)]] : undefined;
      if (fn) {
        instance = bind(lastInstance, fn, lastInstance);
        return instance;
      }
    }
  }
  if (!unboundFn && isFunction(instance) && !instance['$$factory']) {
    return bind(lastInstance, instance);
  }
  return instance;
}

function setter(instance, path, value){
  var element = path.split('.');
  for ( var i = 0; element.length > 1; i++) {
    var key = element.shift();
    var newInstance = instance[key];
    if (!newInstance) {
      newInstance = {};
      instance[key] = newInstance;
    }
    instance = newInstance;
  }
  instance[element.shift()] = value;
  return value;
}

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

var getterFnCache = {};
var JS_KEYWORDS = {};
foreach(
  ["break", "const", "continue", "class", "delete",
   "do", "while", "for", "function", "if",
   "instanceof", "new", "return", "switch",
   "this", "throw", "try", "catch", "with"],
  function(key){ JS_KEYWORDS[key] = true;}
);
function getterFn(path){
  var fn = getterFnCache[path];
  if (fn) return fn;

  var code = 'function (self){\n';
  code += '  var last, fn, type;\n';
  foreach(path.split('.'), function(key) {
    key = (JS_KEYWORDS[key]) ? '["' + key + '"]' : '.' + key;
    code += '  if(!self) return self;\n';
    code += '  last = self;\n';
    code += '  self = self' + key + ';\n';
    code += '  if(typeof self == "function") \n';
    code += '    self = function(){ return last'+key+'.apply(last, arguments); };\n';
    if (key.charAt(1) == '$') {
      // special code for super-imposed functions
      var name = key.substr(2);
      code += '  if(!self) {\n';
      code += '    type = angular.Global.typeOf(last);\n';
      code += '    fn = (angular[type.charAt(0).toUpperCase() + type.substring(1)]||{})["' + name + '"];\n';
      code += '    if (fn)\n';
      code += '      self = function(){ return fn.apply(last, [last].concat(slice.call(arguments, 0, arguments.length))); };\n';
      code += '  }\n';
    }
  });
  code += '  return self;\n}';
  fn = eval('fn = ' + code);
  fn["toString"] = function(){ return code; };

  return getterFnCache[path] = fn;
}

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

var compileCache = {};
function expressionCompile(exp){
  if (isFunction(exp)) return exp;
  var fn = compileCache[exp];
  if (!fn) {
    var parser = new Parser(exp);
    var fnSelf = parser.statements();
    parser.assertAllConsumed();
    fn = compileCache[exp] = extend(
      function(){ return fnSelf(this);},
      {fnSelf: fnSelf});
  }
  return fn;
}

function rethrow(e) { throw e; }
function errorHandlerFor(element, error) {
  elementError(element, NG_EXCEPTION, isDefined(error) ? toJson(error) : error);
}

var scopeId = 0;
function createScope(parent, services, existing) {
  function Parent(){}
  function API(){}
  function Behavior(){}

  var instance, behavior, api, evalLists = {sorted:[]}, servicesCache = extend({}, existing);

  parent = Parent.prototype = (parent || {});
  api = API.prototype = new Parent();
  behavior = Behavior.prototype = new API();
  instance = new Behavior();

  extend(api, {
    'this': instance,
    $id: (scopeId++),
    $parent: parent,
    $bind: bind(instance, bind, instance),
    $get: bind(instance, getter, instance),
    $set: bind(instance, setter, instance),

    $eval: function $eval(exp) {
      if (exp !== undefined) {
        return expressionCompile(exp).apply(instance, slice.call(arguments, 1, arguments.length));
      } else {
        for ( var i = 0, iSize = evalLists.sorted.length; i < iSize; i++) {
          for ( var queue = evalLists.sorted[i],
                    jSize = queue.length,
                    j= 0; j < jSize; j++) {
            instance.$tryEval(queue[j].fn, queue[j].handler);
          }
        }
      }
    },

    $tryEval: function (expression, exceptionHandler) {
      try {
        return expressionCompile(expression).apply(instance, slice.call(arguments, 2, arguments.length));
      } catch (e) {
        error(e);
        if (isFunction(exceptionHandler)) {
          exceptionHandler(e);
        } else if (exceptionHandler) {
          errorHandlerFor(exceptionHandler, e);
        } else if (isFunction(instance.$exceptionHandler)) {
          instance.$exceptionHandler(e);
        }
      }
    },

    $watch: function(watchExp, listener, exceptionHandler) {
      var watch = expressionCompile(watchExp),
          last;
      function watcher(){
        var value = watch.call(instance),
            lastValue = last;
        if (last !== value) {
          last = value;
          instance.$tryEval(listener, exceptionHandler, value, lastValue);
        }
      }
      instance.$onEval(PRIORITY_WATCH, watcher);
      watcher();
    },

    $onEval: function(priority, expr, exceptionHandler){
      if (!isNumber(priority)) {
        exceptionHandler = expr;
        expr = priority;
        priority = 0;
      }
      var evalList = evalLists[priority];
      if (!evalList) {
        evalList = evalLists[priority] = [];
        evalList.priority = priority;
        evalLists.sorted.push(evalList);
        evalLists.sorted.sort(function(a,b){return a.priority-b.priority;});
      }
      evalList.push({
        fn: expressionCompile(expr),
        handler: exceptionHandler
      });
    },

    $become: function(Class) {
      // remove existing
      foreach(behavior, function(value, key){ delete behavior[key]; });
      foreach((Class || noop).prototype, function(fn, name){
        behavior[name] = bind(instance, fn);
      });
      (Class || noop).call(instance);
    }

  });

  if (!parent.$root) {
    api.$root = instance;
    api.$parent = instance;
  }

  function inject(name){
    var service = servicesCache[name], factory, args = [];
    if (isUndefined(service)) {
      factory = services[name];
      if (!isFunction(factory))
        throw "Don't know how to inject '" + name + "'.";
      foreach(factory.inject, function(dependency){
        args.push(inject(dependency));
      });
      servicesCache[name] = service = factory.apply(instance, args);
    }
    return service;
  }

  foreach(services, function(_, name){
    var service = inject(name);
    if (service) {
      setter(instance, name, service);
    }
  });

  return instance;
}
<commit_msg>updated list of JavaScript keywords<commit_after>function getter(instance, path, unboundFn) {
  if (!path) return instance;
  var element = path.split('.');
  var key;
  var lastInstance = instance;
  var len = element.length;
  for ( var i = 0; i < len; i++) {
    key = element[i];
    if (!key.match(/^[\$\w][\$\w\d]*$/))
        throw "Expression '" + path + "' is not a valid expression for accesing variables.";
    if (instance) {
      lastInstance = instance;
      instance = instance[key];
    }
    if (isUndefined(instance)  && key.charAt(0) == '$') {
      var type = angular['Global']['typeOf'](lastInstance);
      type = angular[type.charAt(0).toUpperCase()+type.substring(1)];
      var fn = type ? type[[key.substring(1)]] : undefined;
      if (fn) {
        instance = bind(lastInstance, fn, lastInstance);
        return instance;
      }
    }
  }
  if (!unboundFn && isFunction(instance) && !instance['$$factory']) {
    return bind(lastInstance, instance);
  }
  return instance;
}

function setter(instance, path, value){
  var element = path.split('.');
  for ( var i = 0; element.length > 1; i++) {
    var key = element.shift();
    var newInstance = instance[key];
    if (!newInstance) {
      newInstance = {};
      instance[key] = newInstance;
    }
    instance = newInstance;
  }
  instance[element.shift()] = value;
  return value;
}

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

var getterFnCache = {};
var JS_KEYWORDS = {};
foreach(
   ["abstract", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "debugger", "default",
    "delete", "do", "double", "else", "enum", "export", "extends", "false", "final", "finally", "float", "for", "function", "goto",
    "if", "implements", "import", "ininstanceof", "intinterface", "long", "native", "new", "null", "package", "private",
    "protected", "public", "return", "short", "static", "super", "switch", "synchronized", "this", "throw", "throws",
    "transient", "true", "try", "typeof", "var", "volatile", "void", "while", "with"],
  function(key){ JS_KEYWORDS[key] = true;}
);
function getterFn(path){
  var fn = getterFnCache[path];
  if (fn) return fn;

  var code = 'function (self){\n';
  code += '  var last, fn, type;\n';
  foreach(path.split('.'), function(key) {
    key = (JS_KEYWORDS[key]) ? '["' + key + '"]' : '.' + key;
    code += '  if(!self) return self;\n';
    code += '  last = self;\n';
    code += '  self = self' + key + ';\n';
    code += '  if(typeof self == "function") \n';
    code += '    self = function(){ return last'+key+'.apply(last, arguments); };\n';
    if (key.charAt(1) == '$') {
      // special code for super-imposed functions
      var name = key.substr(2);
      code += '  if(!self) {\n';
      code += '    type = angular.Global.typeOf(last);\n';
      code += '    fn = (angular[type.charAt(0).toUpperCase() + type.substring(1)]||{})["' + name + '"];\n';
      code += '    if (fn)\n';
      code += '      self = function(){ return fn.apply(last, [last].concat(slice.call(arguments, 0, arguments.length))); };\n';
      code += '  }\n';
    }
  });
  code += '  return self;\n}';
  fn = eval('fn = ' + code);
  fn["toString"] = function(){ return code; };

  return getterFnCache[path] = fn;
}

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

var compileCache = {};
function expressionCompile(exp){
  if (isFunction(exp)) return exp;
  var fn = compileCache[exp];
  if (!fn) {
    var parser = new Parser(exp);
    var fnSelf = parser.statements();
    parser.assertAllConsumed();
    fn = compileCache[exp] = extend(
      function(){ return fnSelf(this);},
      {fnSelf: fnSelf});
  }
  return fn;
}

function rethrow(e) { throw e; }
function errorHandlerFor(element, error) {
  elementError(element, NG_EXCEPTION, isDefined(error) ? toJson(error) : error);
}

var scopeId = 0;
function createScope(parent, services, existing) {
  function Parent(){}
  function API(){}
  function Behavior(){}

  var instance, behavior, api, evalLists = {sorted:[]}, servicesCache = extend({}, existing);

  parent = Parent.prototype = (parent || {});
  api = API.prototype = new Parent();
  behavior = Behavior.prototype = new API();
  instance = new Behavior();

  extend(api, {
    'this': instance,
    $id: (scopeId++),
    $parent: parent,
    $bind: bind(instance, bind, instance),
    $get: bind(instance, getter, instance),
    $set: bind(instance, setter, instance),

    $eval: function $eval(exp) {
      if (exp !== undefined) {
        return expressionCompile(exp).apply(instance, slice.call(arguments, 1, arguments.length));
      } else {
        for ( var i = 0, iSize = evalLists.sorted.length; i < iSize; i++) {
          for ( var queue = evalLists.sorted[i],
                    jSize = queue.length,
                    j= 0; j < jSize; j++) {
            instance.$tryEval(queue[j].fn, queue[j].handler);
          }
        }
      }
    },

    $tryEval: function (expression, exceptionHandler) {
      try {
        return expressionCompile(expression).apply(instance, slice.call(arguments, 2, arguments.length));
      } catch (e) {
        error(e);
        if (isFunction(exceptionHandler)) {
          exceptionHandler(e);
        } else if (exceptionHandler) {
          errorHandlerFor(exceptionHandler, e);
        } else if (isFunction(instance.$exceptionHandler)) {
          instance.$exceptionHandler(e);
        }
      }
    },

    $watch: function(watchExp, listener, exceptionHandler) {
      var watch = expressionCompile(watchExp),
          last;
      function watcher(){
        var value = watch.call(instance),
            lastValue = last;
        if (last !== value) {
          last = value;
          instance.$tryEval(listener, exceptionHandler, value, lastValue);
        }
      }
      instance.$onEval(PRIORITY_WATCH, watcher);
      watcher();
    },

    $onEval: function(priority, expr, exceptionHandler){
      if (!isNumber(priority)) {
        exceptionHandler = expr;
        expr = priority;
        priority = 0;
      }
      var evalList = evalLists[priority];
      if (!evalList) {
        evalList = evalLists[priority] = [];
        evalList.priority = priority;
        evalLists.sorted.push(evalList);
        evalLists.sorted.sort(function(a,b){return a.priority-b.priority;});
      }
      evalList.push({
        fn: expressionCompile(expr),
        handler: exceptionHandler
      });
    },

    $become: function(Class) {
      // remove existing
      foreach(behavior, function(value, key){ delete behavior[key]; });
      foreach((Class || noop).prototype, function(fn, name){
        behavior[name] = bind(instance, fn);
      });
      (Class || noop).call(instance);
    }

  });

  if (!parent.$root) {
    api.$root = instance;
    api.$parent = instance;
  }

  function inject(name){
    var service = servicesCache[name], factory, args = [];
    if (isUndefined(service)) {
      factory = services[name];
      if (!isFunction(factory))
        throw "Don't know how to inject '" + name + "'.";
      foreach(factory.inject, function(dependency){
        args.push(inject(dependency));
      });
      servicesCache[name] = service = factory.apply(instance, args);
    }
    return service;
  }

  foreach(services, function(_, name){
    var service = inject(name);
    if (service) {
      setter(instance, name, service);
    }
  });

  return instance;
}
<|endoftext|>


<commit_before>export class Slide {
  /**
   * Creates new Slide instance
   * @constructor
   */
  constructor() {
    this._shapes = [];
  }

  /**
   * Adds shape to slide
   * @param {Shape} shape
   * @returns {Slide}
   */
  addShape(shape) {
    this._shapes.push(shape);
    return this;
  }

  /**
   * Renders the slide
   * @param {Cursor} cursor
   * @returns {Slide}
   */
  render(cursor) {
    this._shapes.forEach(shape => shape.render(cursor));
    return this;
  }
}
<commit_msg>feat(shape): Adds checking for Shape instance when you add it to Slide<commit_after>import { Shape } from './Shape';

export class Slide {
  /**
   * Creates new Slide instance
   * @constructor
   */
  constructor() {
    this._shapes = [];
  }

  /**
   * Adds shape to slide
   * @param {Shape} shape
   * @returns {Slide}
   */
  addShape(shape) {
    if (!(shape instanceof Shape)) throw new Error('You must provide Shape instance');

    this._shapes.push(shape);
    return this;
  }

  /**
   * Renders the slide
   * @param {Cursor} cursor
   * @returns {Slide}
   */
  render(cursor) {
    this._shapes.forEach(shape => shape.render(cursor));
    return this;
  }
}
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import Background, { backgroundPropTypes } from '../../../style/background/macOs';
import Dimension, { dimensionPropTypes } from '../../../style/dimension';
import Padding, { paddingPropTypes } from '../../../style/padding';
import styles from './style/10.11';

@Background({ background: '#f0f0f0' })
@Dimension()
@Padding({ paddingLeft: '10px', paddingRight: '10px', paddingTop: '2px', paddingBottom: '2px' })
class Header extends Component {
  static propTypes = {
    ...backgroundPropTypes,
    ...dimensionPropTypes,
    ...paddingPropTypes
  };

  render() {
    const { children, style, ...props } = this.props;

    return (
      <header style={{ ...styles.header, ...style }} {...props}>
        {children}
      </header>
    );
  }
}

export default Header;
<commit_msg>Fixed eslint<commit_after>import React, { Component } from 'react';
import Background, { backgroundPropTypes } from '../../../style/background/macOs';
import Dimension, { dimensionPropTypes } from '../../../style/dimension';
import Padding, { paddingPropTypes } from '../../../style/padding';
import styles from './style/10.11';

@Background({ background: '#f0f0f0' })
@Dimension()
@Padding({ paddingLeft: '10px', paddingRight: '10px', paddingTop: '2px', paddingBottom: '2px' })
class Header extends Component {
  static propTypes = {
    ...backgroundPropTypes,
    ...dimensionPropTypes,
    ...paddingPropTypes
  };

  render() {
    const { children, style, ...props } = this.props;

    return (
      <header style={{ ...styles.header, ...style }} {...props}>
        {children}
      </header>
    );
  }
}

export default Header;
<|endoftext|>


<commit_before>/* global angular, _, jQuery, Backbone */

angular.module('dci').factory('utils', () => {

	var utils = {
		// company id -> company names
		makeId2Names:(details) =>
			_.keys(details).reduce((a,id) => {
				a[id] = details[id].company;
				return a;
			}, {}),

		// returns { host -> companyid }
		makeHTC:function(data) {
			var hTh = this.makeHTH(data);
			return data.reduce((r,a) => {
				if (a.host_company) {
					r[a.host] = r[a.host_2ld] = a.host_company;
				} else {
					// no host company provided
					var mfirst = hTh[a.host].match(/^([^\.]+)\./);
					if (mfirst) {
						r[a.host] = r[a.host_2ld] = mfirst[1];
					} else {
						console.error('no company for host ', a.host); return r;
					}
				}
				return r;
			}, {});
		},

		// returns { host -> host_2ld }
		makeHTH:(data) => data.reduce((r,a) => {
			// host -> 2ld
			if (a.host_2ld) {
				r[a.host] = a.host_2ld;
			} else { console.error('warning no 2ld ', a.host); }
			return r;
		}, {}),

		// returns true if company_id is of marketing type t
		isType: (details, id, type) => id &&
			details[id] &&
			details[id].typetag &&
			details[id].typetag.indexOf(type) >= 0,

		// aggressive matching of appcompany
		cimatch : (appcompany, x) => appcompany &&
			(x || '').toLowerCase() === appcompany.toLowerCase(),

		// isType and not 1st party
		is3rdPartyType: (appcompany, details, id, type) =>
			utils.isType(details,id,type) &&
			!_.some([details[id] && details[id].company || id, id].map((x) => utils.cimatch(appcompany,x))),

		// compile { company_id -> [pitype1,pitype2] .. } filtering by optional threshold
		makeCompany2pi: (app, data, hosts, pitypes, threshold) => {
			var hTc = utils.makeHTC(data),
				apphosts = _(hosts[app]).pickBy((val, key) => (val > threshold || 0) && hTc[key]).keys().value();

			// next we wanna group together all the pi_types, and consolidate around company
			// console.info('threshold', $scope.threshold, 'apphosts', apphosts.length);
			return apphosts.reduce((r,host) => {
				var company = hTc[host], host_pis = pitypes[host] || [];

				if (!company) {
					console.error('no company for host ', host); return r;
				}
				r[company] = _.union(r[company] || [], host_pis);
				return r;
			}, {});
		},
		makeApp2company:(apps, data, c2pi, hosts, threshold)  => {
			// WARNING this transforms keys into appname + "_app"
			var hTc = utils.makeHTC(data),
				apphosts = _.fromPairs(apps.map((app) => [app, _(hosts[app]).pickBy((val, key) => (val > threshold || 0) && hTc[key]).keys().value()])),
				app2pairs = _.map(apphosts, (hosts, app) => [app+"_app", _(hosts).map((host) => hTc[host]).uniq().value()]);
			return _.fromPairs(app2pairs);
		},
		// makeApp2pi:(apps, data, c2pi, hosts, threshold)  => {
		// 	var hTc = utils.makeHTC(data),
		// 		apphosts = _(apps).map((app) => [app, _(hosts[app]).pickBy((val, key) => (val > threshold || 0) && hTc[key]).keys().value()]).fromPairs().value();
		// 	return _.map(apphosts).map((hosts, app) => [app, _(hosts).map((host) => c2pi[hTc[host]]).flatten().uniq().value()]).fromPairs().value();
		// },
		makePDCIc2pi: (apps, data, hosts, pitypes, threshold) => {
			return apps.reduce((result, app) => {
				var c2pi = utils.makeCompany2pi(app, data, hosts, pitypes, threshold);
				// merge with result
				_.map(c2pi, (pis, company) => {
					result[company] = _.union(result[company]||[],pis);
				});
				return result;
			}, {});
		},
		makeCategories:(appCompany, details, c2pi) => {
			return {
				'app-publisher': _.pickBy(c2pi, (pis, company) =>
					utils.cimatch(appCompany, company)),
				'app-functionality': _.pickBy(c2pi, (pis, company) =>
					!utils.isType(details, company, 'ignore') &&
					!utils.isType(details, company, 'platform') &&
					utils.is3rdPartyType(appCompany, details, company, 'app')),
				'marketing': _.pickBy(c2pi, (pis, company) =>
					!utils.isType(details, company, 'ignore') &&
					!utils.isType(details, company, 'platform') &&
					utils.is3rdPartyType(appCompany, details, company, 'marketing')),
				'usage tracking': _.pickBy(c2pi, (pis, company) =>
					!utils.isType(details, company, 'ignore') &&
					!utils.isType(details, company, 'platform') &&
					utils.is3rdPartyType(appCompany, details, company, 'usage')),
				'payments':_.pickBy(c2pi, (pis, company) =>
					!utils.isType(details, company, 'ignore') &&
					!utils.isType(details, company, 'platform') &&
					utils.is3rdPartyType(appCompany, details, company, 'payments')),
				'security':_.pickBy(c2pi, (pis, company) =>
					!utils.isType(details, company, 'ignore') &&
					!utils.isType(details, company, 'platform') &&
					utils.is3rdPartyType(appCompany, details, company, 'security')),
				'other': _.pickBy(c2pi, (pis, company) =>
					!utils.cimatch(appCompany, company) &&
					!utils.isType(details, company, 'ignore') &&
					!utils.isType(details, company, 'app') &&
					!utils.isType(details, company,'marketing') &&
					!utils.isType(details, company, 'platform') &&
					!utils.isType(details, company, 'usage') &&
					!utils.isType(details, company, 'payments') &&
					!utils.isType(details, company, 'security'))
			};
		},
		pilabels: {
			USER_PERSONAL_DETAILS: 'personal details',
			USER_LOCATION: 'your location',
			USER_LOCATION_COARSE: 'your approximate location',
			DEVICE_ID:'phone id',
			DEVICE_SOFT:'phone characteristics'
		}
	};
	return utils;
});<commit_msg>app to company id<commit_after>/* global angular, _, jQuery, Backbone */

angular.module('dci').factory('utils', () => {

	var utils = {
		// company id -> company names
		makeId2Names:(details) =>
			_.keys(details).reduce((a,id) => {
				a[id] = details[id].company;
				return a;
			}, {}),

		// returns { host -> companyid }
		makeHTC:function(data) {
			var hTh = this.makeHTH(data);
			return data.reduce((r,a) => {
				if (a.host_company) {
					r[a.host] = r[a.host_2ld] = a.host_company;
				} else {
					// no host company provided
					var mfirst = hTh[a.host].match(/^([^\.]+)\./);
					if (mfirst) {
						r[a.host] = r[a.host_2ld] = mfirst[1];
					} else {
						console.error('no company for host ', a.host); return r;
					}
				}
				return r;
			}, {});
		},

		// returns { host -> host_2ld }
		makeHTH:(data) => data.reduce((r,a) => {
			// host -> 2ld
			if (a.host_2ld) {
				r[a.host] = a.host_2ld;
			} else { console.error('warning no 2ld ', a.host); }
			return r;
		}, {}),

		// returns true if company_id is of marketing type t
		isType: (details, id, type) => id &&
			details[id] &&
			details[id].typetag &&
			details[id].typetag.indexOf(type) >= 0,

		// aggressive matching of appcompany
		cimatch : (appcompany, x) => appcompany &&
			(x || '').toLowerCase() === appcompany.toLowerCase(),

		toAppId : (appname) => appname + " app",

		// isType and not 1st party
		is3rdPartyType: (appcompany, details, id, type) =>
			utils.isType(details,id,type) &&
			!_.some([details[id] && details[id].company || id, id].map((x) => utils.cimatch(appcompany,x))),

		// compile { company_id -> [pitype1,pitype2] .. } filtering by optional threshold
		makeCompany2pi: (app, data, hosts, pitypes, threshold) => {
			var hTc = utils.makeHTC(data),
				apphosts = _(hosts[app]).pickBy((val, key) => (val > threshold || 0) && hTc[key]).keys().value();

			// next we wanna group together all the pi_types, and consolidate around company
			// console.info('threshold', $scope.threshold, 'apphosts', apphosts.length);
			return apphosts.reduce((r,host) => {
				var company = hTc[host], host_pis = pitypes[host] || [];

				if (!company) {
					console.error('no company for host ', host); return r;
				}
				r[company] = _.union(r[company] || [], host_pis);
				return r;
			}, {});
		},
		makeApp2company:function(apps, data, c2pi, hosts, threshold) {
			// WARNING this transforms keys into toApp(appname)
			var hTc = utils.makeHTC(data),
				apphosts = _.fromPairs(apps.map((app) => [app, _(hosts[app]).pickBy((val, key) => (val > threshold || 0) && hTc[key]).keys().value()])),
				app2pairs = _.map(apphosts, (hosts, app) => [this.toAppId(app), _(hosts).map((host) => hTc[host]).uniq().value()]);
			return _.fromPairs(app2pairs);
		},
		// makeApp2pi:(apps, data, c2pi, hosts, threshold)  => {
		// 	var hTc = utils.makeHTC(data),
		// 		apphosts = _(apps).map((app) => [app, _(hosts[app]).pickBy((val, key) => (val > threshold || 0) && hTc[key]).keys().value()]).fromPairs().value();
		// 	return _.map(apphosts).map((hosts, app) => [app, _(hosts).map((host) => c2pi[hTc[host]]).flatten().uniq().value()]).fromPairs().value();
		// },
		makePDCIc2pi: (apps, data, hosts, pitypes, threshold) => {
			return apps.reduce((result, app) => {
				var c2pi = utils.makeCompany2pi(app, data, hosts, pitypes, threshold);
				// merge with result
				_.map(c2pi, (pis, company) => {
					result[company] = _.union(result[company]||[],pis);
				});
				return result;
			}, {});
		},
		makeCategories:(appCompany, details, c2pi) => {
			return {
				'app-publisher': _.pickBy(c2pi, (pis, company) =>
					utils.cimatch(appCompany, company)),
				'app-functionality': _.pickBy(c2pi, (pis, company) =>
					!utils.isType(details, company, 'ignore') &&
					!utils.isType(details, company, 'platform') &&
					utils.is3rdPartyType(appCompany, details, company, 'app')),
				'marketing': _.pickBy(c2pi, (pis, company) =>
					!utils.isType(details, company, 'ignore') &&
					!utils.isType(details, company, 'platform') &&
					utils.is3rdPartyType(appCompany, details, company, 'marketing')),
				'usage tracking': _.pickBy(c2pi, (pis, company) =>
					!utils.isType(details, company, 'ignore') &&
					!utils.isType(details, company, 'platform') &&
					utils.is3rdPartyType(appCompany, details, company, 'usage')),
				'payments':_.pickBy(c2pi, (pis, company) =>
					!utils.isType(details, company, 'ignore') &&
					!utils.isType(details, company, 'platform') &&
					utils.is3rdPartyType(appCompany, details, company, 'payments')),
				'security':_.pickBy(c2pi, (pis, company) =>
					!utils.isType(details, company, 'ignore') &&
					!utils.isType(details, company, 'platform') &&
					utils.is3rdPartyType(appCompany, details, company, 'security')),
				'other': _.pickBy(c2pi, (pis, company) =>
					!utils.cimatch(appCompany, company) &&
					!utils.isType(details, company, 'ignore') &&
					!utils.isType(details, company, 'app') &&
					!utils.isType(details, company,'marketing') &&
					!utils.isType(details, company, 'platform') &&
					!utils.isType(details, company, 'usage') &&
					!utils.isType(details, company, 'payments') &&
					!utils.isType(details, company, 'security'))
			};
		},
		pilabels: {
			USER_PERSONAL_DETAILS: 'personal details',
			USER_LOCATION: 'your location',
			USER_LOCATION_COARSE: 'your approximate location',
			DEVICE_ID:'phone id',
			DEVICE_SOFT:'phone characteristics'
		}
	};
	return utils;
});<|endoftext|>


<commit_before>/**
 * Created by tushar.mathur on 22/01/16.
 */

'use strict'

import PATH from 'path'
import URL from 'url'
import {Observable as O} from 'rx'
import R from 'ramda'
import * as Rx from './RxFP'
import {mux, demux} from 'muxer'
import {MTDError, FILE_SIZE_UNKNOWN} from './Error'

const first = R.nth(0)
const second = R.nth(1)
export const trace = R.curry((msg, value) => {
  console.log(msg, value)
  return value
})
export const BUFFER_SIZE = 512
export const NormalizePath = (path) => PATH.resolve(process.cwd(), path)
export const GenerateFileName = (x) => R.last(URL.parse(x).pathname.split('/')) || Date.now()
export const ResolvePath = R.compose(NormalizePath, GenerateFileName)
export const SplitRange = (totalBytes, range) => {
  const delta = Math.round(totalBytes / range)
  const start = R.times((x) => x * delta, range)
  const end = R.times((x) => (x + 1) * delta - 1, range)
  end[range - 1] = totalBytes
  return R.zip(start, end)
}
export const CreateRangeHeader = ([start, end]) => `bytes=${start}-${end}`
export const SetRangeHeader = ({request, range}) => {
  return R.set(
    R.lensPath(['headers', 'range']),
    CreateRangeHeader(range),
    R.omit(['threads', 'offsets'], request)
  )
}
export const CreateRequestParams = ({meta, index}) => {
  const range = [meta.offsets[index], second(meta.threads[index])]
  return SetRangeHeader({request: meta, range})
}
export const ToBuffer = R.curry((size, str) => {
  var buffer = CreateFilledBuffer(size)
  buffer.write(str)
  return buffer
})
export const CreateFilledBuffer = (size = BUFFER_SIZE, fill = ' ') => {
  const buffer = new Buffer(size)
  buffer.fill(fill)
  return buffer
}
export const MergeDefaultOptions = (options) => R.mergeAll([
  {mtdPath: options.path + '.mtd', range: 3, metaWrite: 300},
  options
])
/*
 * STREAM BASED
 */
export const RxFromCB = () => {
  let _observer
  return [O.create(observer => (_observer = observer)), x => _observer.onNext(x)]
}
export const RequestDataOffset = ({HTTP, requestParams, offset}) => {
  const [{data$, response$}] = demux(HTTP.request(requestParams), 'data$', 'response$')
  const accumulator = ([_buffer, _offset], buffer) => [buffer, _buffer.length + _offset]
  const buffer$ = data$.scan(accumulator, [{length: 0}, offset])
  return mux({buffer$, response$})
}
export const ToJSON$ = source$ => source$.map(JSON.stringify.bind(JSON))
export const ToBuffer$ = source$ => source$.map(ToBuffer(BUFFER_SIZE))
export const JSToBuffer$ = R.compose(ToBuffer$, ToJSON$)
export const BufferToJS$ = buffer$ => buffer$.map(buffer => JSON.parse(buffer.toString()))
export const RemoteFileSize$ = ({HTTP, options}) => {
  return HTTP.requestHead(options)
    .pluck('headers', 'content-length')
    .map((x) => parseInt(x, 10))
}
export const LocalFileSize$ = ({FILE, fd$}) => FILE.fstat(fd$.map(R.of)).pluck('size')
export const PickFirst = R.map(first)
export const CreateMeta$ = ({size$, options}) => {
  return size$.map((totalBytes) => {
    if (!isFinite(totalBytes)) throw new MTDError(FILE_SIZE_UNKNOWN)
    const threads = SplitRange(totalBytes, options.range)
    return R.merge(options, {totalBytes, threads, offsets: PickFirst(threads)})
  })
}
export const ReadFileAt$ = ({FILE, fd$, position$, size = BUFFER_SIZE}) => {
  const readParams$ = O.combineLatest(position$, fd$)
  const buffer = CreateFilledBuffer(size)
  const toParam = ([position, fd]) => [fd, buffer, 0, buffer.length, position]
  return FILE.read(readParams$.map(toParam))
}
export const MetaPosition$ = ({size$}) => size$.map(R.add(-BUFFER_SIZE))
export const CreateWriteBufferAtParams = ({fd$, buffer$, position$}) => {
  const toParam = ([buffer, fd, position]) => [fd, buffer, 0, buffer.length, position]
  return O.combineLatest(buffer$, fd$, position$.first()).map(toParam)
}
export const CreateWriteBufferParams = ({fd$, buffer$, position$}) => {
  const toParams = ([fd, buffer, position]) => [fd, buffer, 0, buffer.length, position]
  return O.combineLatest(fd$, O.zip(buffer$, position$))
    .map(R.compose(toParams, R.unnest))
}
export const AccumulateOffset = ({meta$, written$, thread$}) => {
  const offsetLens = thread => R.compose(R.lensProp('offsets'), R.lensIndex(thread))
  const start$ = meta$.map(meta => ({meta, len: 0, thread: 0})).first()
  const source$ = O.merge(
    start$,
    O.zip(written$, thread$)
      .map(R.zipObj(['len', 'thread']))
      .withLatestFrom(meta$.map(R.objOf('meta')))
      .map(R.mergeAll)
  )

  const accumulator = (previous, current) => {
    const thread = current.thread
    const pMeta = previous.meta
    const oldVal = pMeta.offsets[thread]
    const lens = offsetLens(thread)
    const meta = R.set(lens, R.add(oldVal, current.len), pMeta)
    return R.merge(current, {meta})
  }

  return source$
    .scan(accumulator)
    .skip(1)
    .pluck('meta')
}
export const ReadJSON$ = R.compose(BufferToJS$, Rx.map(second), ReadFileAt$)
export const CreateRequestParamsWithOffset = ({meta$, CreateRequestParams}) => {
  const MetaOffset = ({meta, index}) => meta.offsets[index]
  const addIndex = (meta) => meta.threads.map((_, index) => ({meta, index}))
  const Params = R.applySpec({
    offset: MetaOffset,
    requestParams: CreateRequestParams
  })
  return Rx.flatMap(addIndex, meta$).map(Params)
}
export const RxFlatMapReplay = R.curryN(2, R.compose(Rx.shareReplay(1), Rx.flatMap))
export const RxThrottleComplete = (window$, $, sh) => {
  const selector = window => O.merge($.throttle(window, sh), $.last())
  return window$.first().flatMap(selector)
}
export const RemoveMETA = ({FILE, meta$, fd$}) => {
  const size$ = meta$.pluck('totalBytes')
  return FILE.truncate(O.combineLatest(fd$, size$).take(1))
}
export const ResetFileName = ({FILE, meta$}) => FILE.rename(
  meta$.map(meta => [meta.mtdPath, meta.path]).take(1)
)
export const FinalizeDownload = ({FILE, fd$, meta$, complete$}) => {
  const metaRemoved$ = complete$.flatMap(() => RemoveMETA({FILE, meta$, fd$}))
  const renamed$ = metaRemoved$.flatMap(() => ResetFileName({FILE, meta$}))
  return mux({metaRemoved$, renamed$})
}
export const DownloadFromMTDFile = ({FILE, HTTP, mtdPath}) => {
  /**
   * Create Request function
   */
  const HttpRequestReplay = RxFlatMapReplay(R.compose(RequestDataOffset, R.merge({HTTP})))

  /**
   * Open file to read+append
   */
  const fd$ = FILE.open(O.just([mtdPath, 'r+']))

  /**
   * Retrieve File size on disk
   */
  const size$ = LocalFileSize$({FILE, fd$})

  /**
   * Retrieve Meta info
   */
  const metaPosition$ = MetaPosition$({size$})
  const meta$ = ReadJSON$({FILE, fd$, position$: metaPosition$})

  /**
   * Create request params and make HTTP requests
   */
  const request$ = CreateRequestParamsWithOffset({meta$, CreateRequestParams})

  /**
   * Receive response stream
   */
  const [{response$, buffer$}] = demux(HttpRequestReplay(request$), 'buffer$', 'response$')

  /**
   * Create write params and save buffer+offset to disk
   */
  const saveBuffer$ = FILE.write(CreateWriteBufferParams({
    FILE,
    fd$,
    buffer$: buffer$.map(first),
    position$: buffer$.map(second)
  }))

  /**
   * Update META info
   */
  const nMeta$ = AccumulateOffset({meta$, written$: saveBuffer$.map(first), thread$: buffer$.map(second)})

  /**
   * Persist META to disk
   */
  const metaWritten$ = FILE.write(CreateWriteBufferAtParams({
    fd$,
    buffer$: JSToBuffer$(RxThrottleComplete(meta$.pluck('metaWrite'), nMeta$)),
    position$: size$
  }))
  return mux({
    metaWritten$, localFileSize$: size$, fd$, metaPosition$,
    meta$: O.merge(nMeta$, meta$),
    response$
  })
}
export const CreateMTDFile = ({FILE, HTTP, options}) => {
  /**
   * Create a new file
   */
  const fd$ = FILE.open(O.just([options.mtdPath, 'w']))

  /**
   * Retreive file size on remote server
   */
  const size$ = RemoteFileSize$({HTTP, options})

  /**
   * Create initial meta data
   */
  const meta$ = CreateMeta$({options, size$})

  /**
   * Create a new file with meta info appended at the end
   */
  const written$ = FILE.write(CreateWriteBufferAtParams({FILE, fd$, buffer$: JSToBuffer$(meta$), position$: size$}))
  return mux({written$, meta$, remoteFileSize: size$, fd$})
}
<commit_msg>refactor(utils): rename muxed fd streams<commit_after>/**
 * Created by tushar.mathur on 22/01/16.
 */

'use strict'

import PATH from 'path'
import URL from 'url'
import {Observable as O} from 'rx'
import R from 'ramda'
import * as Rx from './RxFP'
import {mux, demux} from 'muxer'
import {MTDError, FILE_SIZE_UNKNOWN} from './Error'

const first = R.nth(0)
const second = R.nth(1)
export const trace = R.curry((msg, value) => {
  console.log(msg, value)
  return value
})
export const BUFFER_SIZE = 512
export const NormalizePath = (path) => PATH.resolve(process.cwd(), path)
export const GenerateFileName = (x) => R.last(URL.parse(x).pathname.split('/')) || Date.now()
export const ResolvePath = R.compose(NormalizePath, GenerateFileName)
export const SplitRange = (totalBytes, range) => {
  const delta = Math.round(totalBytes / range)
  const start = R.times((x) => x * delta, range)
  const end = R.times((x) => (x + 1) * delta - 1, range)
  end[range - 1] = totalBytes
  return R.zip(start, end)
}
export const CreateRangeHeader = ([start, end]) => `bytes=${start}-${end}`
export const SetRangeHeader = ({request, range}) => {
  return R.set(
    R.lensPath(['headers', 'range']),
    CreateRangeHeader(range),
    R.omit(['threads', 'offsets'], request)
  )
}
export const CreateRequestParams = ({meta, index}) => {
  const range = [meta.offsets[index], second(meta.threads[index])]
  return SetRangeHeader({request: meta, range})
}
export const ToBuffer = R.curry((size, str) => {
  var buffer = CreateFilledBuffer(size)
  buffer.write(str)
  return buffer
})
export const CreateFilledBuffer = (size = BUFFER_SIZE, fill = ' ') => {
  const buffer = new Buffer(size)
  buffer.fill(fill)
  return buffer
}
export const MergeDefaultOptions = (options) => R.mergeAll([
  {mtdPath: options.path + '.mtd', range: 3, metaWrite: 300},
  options
])
/*
 * STREAM BASED
 */
export const RxFromCB = () => {
  let _observer
  return [O.create(observer => (_observer = observer)), x => _observer.onNext(x)]
}
export const RequestDataOffset = ({HTTP, requestParams, offset}) => {
  const [{data$, response$}] = demux(HTTP.request(requestParams), 'data$', 'response$')
  const accumulator = ([_buffer, _offset], buffer) => [buffer, _buffer.length + _offset]
  const buffer$ = data$.scan(accumulator, [{length: 0}, offset])
  return mux({buffer$, response$})
}
export const ToJSON$ = source$ => source$.map(JSON.stringify.bind(JSON))
export const ToBuffer$ = source$ => source$.map(ToBuffer(BUFFER_SIZE))
export const JSToBuffer$ = R.compose(ToBuffer$, ToJSON$)
export const BufferToJS$ = buffer$ => buffer$.map(buffer => JSON.parse(buffer.toString()))
export const RemoteFileSize$ = ({HTTP, options}) => {
  return HTTP.requestHead(options)
    .pluck('headers', 'content-length')
    .map((x) => parseInt(x, 10))
}
export const LocalFileSize$ = ({FILE, fd$}) => FILE.fstat(fd$.map(R.of)).pluck('size')
export const PickFirst = R.map(first)
export const CreateMeta$ = ({size$, options}) => {
  return size$.map((totalBytes) => {
    if (!isFinite(totalBytes)) throw new MTDError(FILE_SIZE_UNKNOWN)
    const threads = SplitRange(totalBytes, options.range)
    return R.merge(options, {totalBytes, threads, offsets: PickFirst(threads)})
  })
}
export const ReadFileAt$ = ({FILE, fd$, position$, size = BUFFER_SIZE}) => {
  const readParams$ = O.combineLatest(position$, fd$)
  const buffer = CreateFilledBuffer(size)
  const toParam = ([position, fd]) => [fd, buffer, 0, buffer.length, position]
  return FILE.read(readParams$.map(toParam))
}
export const MetaPosition$ = ({size$}) => size$.map(R.add(-BUFFER_SIZE))
export const CreateWriteBufferAtParams = ({fd$, buffer$, position$}) => {
  const toParam = ([buffer, fd, position]) => [fd, buffer, 0, buffer.length, position]
  return O.combineLatest(buffer$, fd$, position$.first()).map(toParam)
}
export const CreateWriteBufferParams = ({fd$, buffer$, position$}) => {
  const toParams = ([fd, buffer, position]) => [fd, buffer, 0, buffer.length, position]
  return O.combineLatest(fd$, O.zip(buffer$, position$))
    .map(R.compose(toParams, R.unnest))
}
export const AccumulateOffset = ({meta$, written$, thread$}) => {
  const offsetLens = thread => R.compose(R.lensProp('offsets'), R.lensIndex(thread))
  const start$ = meta$.map(meta => ({meta, len: 0, thread: 0})).first()
  const source$ = O.merge(
    start$,
    O.zip(written$, thread$)
      .map(R.zipObj(['len', 'thread']))
      .withLatestFrom(meta$.map(R.objOf('meta')))
      .map(R.mergeAll)
  )

  const accumulator = (previous, current) => {
    const thread = current.thread
    const pMeta = previous.meta
    const oldVal = pMeta.offsets[thread]
    const lens = offsetLens(thread)
    const meta = R.set(lens, R.add(oldVal, current.len), pMeta)
    return R.merge(current, {meta})
  }

  return source$
    .scan(accumulator)
    .skip(1)
    .pluck('meta')
}
export const ReadJSON$ = R.compose(BufferToJS$, Rx.map(second), ReadFileAt$)
export const CreateRequestParamsWithOffset = ({meta$, CreateRequestParams}) => {
  const MetaOffset = ({meta, index}) => meta.offsets[index]
  const addIndex = (meta) => meta.threads.map((_, index) => ({meta, index}))
  const Params = R.applySpec({
    offset: MetaOffset,
    requestParams: CreateRequestParams
  })
  return Rx.flatMap(addIndex, meta$).map(Params)
}
export const RxFlatMapReplay = R.curryN(2, R.compose(Rx.shareReplay(1), Rx.flatMap))
export const RxThrottleComplete = (window$, $, sh) => {
  const selector = window => O.merge($.throttle(window, sh), $.last())
  return window$.first().flatMap(selector)
}
export const RemoveMETA = ({FILE, meta$, fd$}) => {
  const size$ = meta$.pluck('totalBytes')
  return FILE.truncate(O.combineLatest(fd$, size$).take(1))
}
export const ResetFileName = ({FILE, meta$}) => FILE.rename(
  meta$.map(meta => [meta.mtdPath, meta.path]).take(1)
)
export const FinalizeDownload = ({FILE, fd$, meta$, complete$}) => {
  const metaRemoved$ = complete$.flatMap(() => RemoveMETA({FILE, meta$, fd$}))
  const renamed$ = metaRemoved$.flatMap(() => ResetFileName({FILE, meta$}))
  return mux({metaRemoved$, renamed$})
}
export const DownloadFromMTDFile = ({FILE, HTTP, mtdPath}) => {
  /**
   * Create Request function
   */
  const HttpRequestReplay = RxFlatMapReplay(R.compose(RequestDataOffset, R.merge({HTTP})))

  /**
   * Open file to read+append
   */
  const fd$ = FILE.open(O.just([mtdPath, 'r+']))

  /**
   * Retrieve File size on disk
   */
  const size$ = LocalFileSize$({FILE, fd$})

  /**
   * Retrieve Meta info
   */
  const metaPosition$ = MetaPosition$({size$})
  const meta$ = ReadJSON$({FILE, fd$, position$: metaPosition$})

  /**
   * Create request params and make HTTP requests
   */
  const request$ = CreateRequestParamsWithOffset({meta$, CreateRequestParams})

  /**
   * Receive response stream
   */
  const [{response$, buffer$}] = demux(HttpRequestReplay(request$), 'buffer$', 'response$')

  /**
   * Create write params and save buffer+offset to disk
   */
  const saveBuffer$ = FILE.write(CreateWriteBufferParams({
    FILE,
    fd$,
    buffer$: buffer$.map(first),
    position$: buffer$.map(second)
  }))

  /**
   * Update META info
   */
  const nMeta$ = AccumulateOffset({meta$, written$: saveBuffer$.map(first), thread$: buffer$.map(second)})

  /**
   * Persist META to disk
   */
  const metaWritten$ = FILE.write(CreateWriteBufferAtParams({
    fd$,
    buffer$: JSToBuffer$(RxThrottleComplete(meta$.pluck('metaWrite'), nMeta$)),
    position$: size$
  }))
  return mux({
    metaWritten$, localFileSize$: size$, fdR$: fd$, metaPosition$,
    meta$: O.merge(nMeta$, meta$),
    response$
  })
}
export const CreateMTDFile = ({FILE, HTTP, options}) => {
  /**
   * Create a new file
   */
  const fd$ = FILE.open(O.just([options.mtdPath, 'w']))

  /**
   * Retreive file size on remote server
   */
  const size$ = RemoteFileSize$({HTTP, options})

  /**
   * Create initial meta data
   */
  const meta$ = CreateMeta$({options, size$})

  /**
   * Create a new file with meta info appended at the end
   */
  const written$ = FILE.write(CreateWriteBufferAtParams({
    FILE,
    fd$: fd$,
    buffer$: JSToBuffer$(meta$),
    position$: size$
  }))
  return mux({written$, meta$, remoteFileSize: size$, fdW$: fd$})
}
<|endoftext|>


<commit_before>function Voice() {
  var that = Object.create(Voice.prototype);
  that.scheduleToneChange = function() {

  };

  return that;
}
<commit_msg>Unused class.<commit_after><|endoftext|>