Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

ng-tasty

Package Overview
Dependencies
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ng-tasty - npm Package Compare versions

Comparing version 0.4.4 to 0.4.5

src/filter/camelize.js

6

bower.json
{
"name": "ng-tasty",
"version": "0.4.4",
"version": "0.4.5",
"homepage": "https://github.com/Zizzamia/ng-tasty",
"authors": [
"@zizzamia",
"@proudlygeek"
{ "name" : "Leonardo Zizzamia", "homepage" : "https://twitter.com/Zizzamia" }
],
"main": "./ng-tasty.js",
"dependencies": {
"angular": "^1.3.0"
}
}

@@ -5,6 +5,6 @@ /*

* Version: 0.4.4 - 2014-12-27
* Version: 0.4.5 - 2015-01-19
* License: MIT
*/
angular.module("ngTasty", ["ngTasty.tpls", "ngTasty.component.table","ngTasty.filter.cleanFieldName","ngTasty.filter.filterInt","ngTasty.filter.range","ngTasty.service.bindTo","ngTasty.service.debounce","ngTasty.service.joinObjects","ngTasty.service.setProperty","ngTasty.service.tastyUtil","ngTasty.service.throttle","ngTasty.service.webSocket"]);
angular.module("ngTasty", ["ngTasty.tpls", "ngTasty.component.table","ngTasty.filter.camelize","ngTasty.filter.cleanFieldName","ngTasty.filter.filterInt","ngTasty.filter.range","ngTasty.filter.slugify","ngTasty.service.bindTo","ngTasty.service.debounce","ngTasty.service.joinObjects","ngTasty.service.setProperty","ngTasty.service.tastyUtil","ngTasty.service.throttle","ngTasty.service.webSocket"]);
angular.module("ngTasty.tpls", ["ngTasty.tpls.table.head","ngTasty.tpls.table.pagination"]);

@@ -47,3 +47,4 @@ /**

listItemsPerPage: [5, 25, 50, 100],
itemsPerPage: 5
itemsPerPage: 5,
watchResource: 'reference'
})

@@ -59,5 +60,8 @@ .controller('TableController', ["$scope", "$attrs", "$filter", "tableConfig", "tastyUtil", function($scope, $attrs, $filter, tableConfig, tastyUtil) {

$scope.query = {};
$scope.logs = {
'buildClientResourceCount': 0
};
listScopeToWatch = ['bindFilters', 'bindInit', 'bindQuery', 'bindResource',
'bindResourceCallback'];
'bindResourceCallback', 'bindWatchResource'];
listScopeToWatch.forEach(function (scopeName) {

@@ -80,2 +84,3 @@ newScopeName = scopeName.substring(4);

$scope.init.sortOrder = $scope.init.sortOrder || tableConfig.init.sortOrder;
$scope.watchResource = $scope.watchResource || tableConfig.watchResource;

@@ -121,3 +126,3 @@ // Defualt variables

throw 'AngularJS tastyTable directive: the bind-resource ('+
$attrs.bindResource + ') it\'s not an object';
$attrs.bindResource + ') is not an object';
} else if (!$scope.resource.header && !$scope.resource.rows) {

@@ -131,3 +136,3 @@ throw 'AngularJS tastyTable directive: the bind-resource ('+

throw 'AngularJS tastyTable directive: the bind-resource-callback ('+
$attrs.bindResourceCallback + ') it\'s not a function';
$attrs.bindResourceCallback + ') is not a function';
}

@@ -155,13 +160,13 @@ $scope.clientSide = false;

initStatus[keyDirective] = true;
if (!$scope.theadDirective && !$scope.paginationDirective) {
if (!$scope.theadDirective && !$scope.paginationDirective) { // None of them
this.start = true;
} else if ($scope.theadDirective && $scope.paginationDirective) {
} else if ($scope.theadDirective && $scope.paginationDirective) { // Both directives
if (initStatus.thead && initStatus.pagination){
this.start = true;
}
} else if ($scope.theadDirective && !$scope.paginationDirective) {
} else if ($scope.theadDirective && !$scope.paginationDirective) { // Only Thead directive
if (initStatus.thead){
this.start = true;
}
} else if (!$scope.theadDirective && $scope.paginationDirective) {
} else if (!$scope.theadDirective && $scope.paginationDirective) { // Only Pagination directive
if (initStatus.pagination){

@@ -193,7 +198,6 @@ this.start = true;

setDirectivesValues = function (resource) {
if (!angular.isObject(resource)) {
throw 'AngularJS tastyTable directive: the bind-resource '+
'it\'s not an object';
if (!$scope.resource && !angular.isObject(resource)) {
throw 'AngularJS tastyTable directive: the resource response is not an object';
} else if (!resource.header && !resource.rows) {
throw 'AngularJS tastyTable directive: the bind-resource '+
throw 'AngularJS tastyTable directive: the resource response object '+
'has the property header or rows undefined';

@@ -248,2 +252,3 @@ }

var fromRow, toRow, rowToShow, reverse, listSortBy;
$scope.logs.buildClientResourceCount += 1;
if ($scope.theadDirective && $scope.header.columns.length) {

@@ -342,3 +347,3 @@ reverse = $scope.header.sortOrder === 'asc' ? false : true;

if ($scope.resource) {
$scope.$watch('resource', function watchResource (newValue, oldValue){
var watchResource = function (newValue, oldValue){
if (newValue !== oldValue) {

@@ -348,4 +353,29 @@ $scope.params.sortBy = newValue.sortBy;

$scope.$evalAsync(updateClientSideResource('resource'));
if (!$scope.resource.reload) {
$scope.resource.reload = function () {
$scope.$evalAsync(updateClientSideResource('resource'));
};
}
}
}, true);
};
if ($scope.watchResource === 'reference') {
$scope.$watch('resource', watchResource);
} else if ($scope.watchResource === 'collection') {
$scope.$watchCollection('resource.header', watchResource);
$scope.$watchCollection('resource.rows', watchResource);
$scope.$watchGroup(['sortBy',
'sortOrder',
'pagination.count',
'pagination.page',
'pagination.pages',
'pagination.size'], watchResource);
} else if ($scope.watchResource === 'equality') {
$scope.$watch('resource', function (newValue, oldValue){
if (newValue !== oldValue) {
$scope.params.sortBy = newValue.sortBy;
$scope.params.sortOrder = newValue.sortOrder;
$scope.$evalAsync(updateClientSideResource('resource'));
}
}, true);
}
}

@@ -414,6 +444,5 @@ }])

scope.setColumns = function () {
var lenHeader, width, i, active, sortable, sort,
var width, i, active, sortable, sort,
isSorted, isSortedCaret;
scope.columns = [];
lenHeader = scope.header.columns.length;
scope.header.columns.forEach(function (column, index) {

@@ -679,3 +708,36 @@ column.style = column.style || {};

* @ngdoc filter
* @name filterCamelize
* @function
*
*/
angular.module('ngTasty.filter.camelize', [])
.filter('camelize', function() {
var CAMELIZE_REGEX = /(?:^|[-_ ])(\w)/g;
return function (input, first) {
var isString = typeof input === 'string',
first = typeof first === 'undefined' ? false : !!first;
if(typeof input === 'undefined' ||
input === null ||
(!isString && isNaN(input)) ) {
return '';
}
if(!isString){
return '' + input;
}
return input.trim() //remove trailing spaces
.replace(/ +(?= )/g,'') //remove multiple WS
.replace(CAMELIZE_REGEX, function (_, character, pos) { //actual conversion
return character && (first || pos > 0) ? character.toUpperCase () : character;
});
};
});
/**
* @ngdoc filter
* @name cleanFieldName
* @function
*

@@ -699,3 +761,3 @@ * @description

* @name filterInt
* @kind function
* @function
*

@@ -716,3 +778,3 @@ */

* @name range
* @kind function
* @function
*

@@ -754,2 +816,54 @@ * @description

/**
* @author https://github.com/bogdan-alexandrescu/ - @balx
* @ngdoc filter
* @name ngTasty.filter.slugify
* @function
*
* @description
* Transform text into an ascii slug by replacing whitespaces, accentuated,
* and special characters with the coresponding latin character or completely
* removing them when no latin equivalent is found. This can be used safely to
* generate valid URLs.
*/
angular.module('ngTasty.filter.slugify', [])
.filter('slugify', function () {
var makeString = function (object) {
if (object == null) {
return '';
}
return '' + object;
};
var defaultToWhiteSpace = function (characters) {
if (characters == null) {
return '\\s';
} else if (characters.source) {
return characters.source;
} else {
return '[' + characters.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1') + ']';
}
};
var from = "ąàáäâãåæăćčĉęèéëêĝĥìíïîĵłľńňòóöőôõðøśșšŝťțŭùúüűûñÿýçżźž",
to = "aaaaaaaaaccceeeeeghiiiijllnnoooooooossssttuuuuuunyyczzz",
regex = new RegExp(defaultToWhiteSpace(from), 'g');
return function (str) {
str = makeString(str)
.toString() //make sure is a string
.toLowerCase()
.replace(regex, function (c){
var index = from.indexOf(c);
return to.charAt(index) || '-';
}) //normalize some foreign characters
.replace(/[^\w\-\s]+/g, '') //remove unwanted characters
.trim() //trim spaces
.replace(/\s+/g, '-') //replace any space with a dash
.replace(/\-\-+/g, '-'); //remove duplicate dashes
return str;
};
});
/**
* @ngdoc service

@@ -806,12 +920,20 @@ * @name ngTasty.service.bindTo

angular.module('ngTasty.service.debounce', [])
.factory('debounce', ["$timeout", function($timeout) {
.factory('debounce', ["$timeout", function ($timeout) {
return function (func, wait, immediate) {
var timeout;
var args, context, debounceTimeout, timeout;
var debounceTimeout = function() {
timeout = null;
if (!immediate) {
func.apply(context, args);
}
};
return function debounce () {
var context = this, args = arguments;
context = this;
args = arguments;
var callNow = immediate && !timeout;
$timeout.cancel(timeout);
timeout = $timeout(function debounceTimeout () {
timeout = null;
timeout = $timeout(debounceTimeout, wait);
if (callNow) {
func.apply(context, args);
}, wait);
}
};

@@ -895,3 +1017,3 @@ };

var last, promise;
return function () {
return function throttle () {
var context = scope || this;

@@ -903,3 +1025,3 @@ var now = +new Date,

$timeout.cancel(promise);
promise = $timeout(function () {
promise = $timeout(function throttleTimeout () {
last = now;

@@ -926,2 +1048,11 @@ fn.apply(context, args);

return function(url) {
/**
* Creates a String[1] representing a binary blob[2] function
* containing the WebSocket Factory API.
*
* [1]: https://developer.mozilla.org/en-US/docs/Web/API/URL.createObjectURL
* [2]: https://developer.mozilla.org/en-US/docs/Web/API/Blob
*
* @return {string} String containing the encoded script
*/
var blobURL = URL.createObjectURL(new Blob(['(', function() {

@@ -931,2 +1062,8 @@ var WSWorker = (function() {

/**
* Initialize a new WebSocket using
* the provided URL parameters.
*
* @param {string} url The WebSocket URL
*/
var initialize = function(url) {

@@ -936,3 +1073,10 @@ _ws = new WebSocket(url);

var on = function(event) {
/**
* Listens for any message coming from the WebSocket
* and send its content to the main JS thread using postMessage[1].
*
* [1]: https://developer.mozilla.org/en-US/docs/Web/API/Worker.postMessage
*
*/
var on = function() {
_ws.onmessage = function(response) {

@@ -944,2 +1088,7 @@ var data = JSON.parse(response.data);

/**
* Sends data to the WebSocket.
*
* @param {string} data
*/
var send = function(data) {

@@ -957,2 +1106,14 @@ _ws.send(data);

/**
* Listens for incoming messages from the main
* JavaScript Thread.
*
* The commands allowed are:
*
* ws_new ~> Calls initialize on the Web Socket Worker
* ws_on ~> Register the supplied callback
* ws_send ~> Sends a message to the underlying WebSocket
* encoding it as a string (JSON.stringify)
*
*/
self.addEventListener('message', function(e) {

@@ -964,3 +1125,3 @@ switch (e.data.cmd) {

case 'ws_on':
WSWorker.on(e.data.event, e.data.cb);
WSWorker.on();
break;

@@ -976,9 +1137,38 @@ case 'ws_send':

}.toString(), ')()'], { type: 'application/javascript' }));
// Create a new WebSocket Worker, revoke the URL since
// it's not useful anymore.
var _worker = new Worker(blobURL);
URL.revokeObjectURL(blobURL);
// Tell the WebSocket Worker to init a new WebSocket
_worker.postMessage({ cmd: 'ws_new', url: url });
return {
/**
* Registers a callback to a specific Worker event listener.
* There are two different events:
*
* - 'all' ~> subscribes to all websocket messages
* - 'type'~> subscribes to all websocket messages containing
* a field named 'type'.
*
* For example, WebSockets Server events like this one:
*
* {
* 'type': 'tweet',
* 'data': ...
* }
*
* can be handled in the following way:
*
* ws.on('twitter', function(data) {
* ...
* });
*
* @param {string} event The event name
* @param {Function} cb Callback with output data (first param)
*/
on: function(event, cb) {

@@ -992,2 +1182,7 @@ _worker.postMessage({ cmd: 'ws_on' });

},
/**
* Sends data to the WebSocket.
*
* @param {Any} data
*/
send: function(data) {

@@ -994,0 +1189,0 @@ _worker.postMessage({ cmd: 'ws_send', data: data });

@@ -5,5 +5,5 @@ /*

* Version: 0.4.4 - 2014-12-27
* Version: 0.4.5 - 2015-01-19
* License: MIT
*/
angular.module("ngTasty",["ngTasty.tpls","ngTasty.component.table","ngTasty.filter.cleanFieldName","ngTasty.filter.filterInt","ngTasty.filter.range","ngTasty.service.bindTo","ngTasty.service.debounce","ngTasty.service.joinObjects","ngTasty.service.setProperty","ngTasty.service.tastyUtil","ngTasty.service.throttle","ngTasty.service.webSocket"]),angular.module("ngTasty.tpls",["ngTasty.tpls.table.head","ngTasty.tpls.table.pagination"]),angular.module("ngTasty.component.table",["ngTasty.filter.cleanFieldName","ngTasty.filter.range","ngTasty.service.tastyUtil","ngTasty.tpls.table.head","ngTasty.tpls.table.pagination"]).constant("tableConfig",{init:{count:5,page:1,sortBy:void 0,sortOrder:void 0},query:{page:"page",count:"count",sortBy:"sort-by",sortOrder:"sort-order"},bindOnce:!0,iconUp:"fa fa-sort-up",iconDown:"fa fa-sort-down",bootstrapIcon:!1,templateUrl:"template/table/pagination.html",listItemsPerPage:[5,25,50,100],itemsPerPage:5}).controller("TableController",["$scope","$attrs","$filter","tableConfig","tastyUtil",function($scope,$attrs,$filter,tableConfig,tastyUtil){"use strict";var listScopeToWatch,newScopeName,initStatus,updateClientSideResource,updateServerSideResource,setDirectivesValues,buildClientResource,buildUrl;this.$scope=$scope,initStatus={},$scope.init={},$scope.query={},listScopeToWatch=["bindFilters","bindInit","bindQuery","bindResource","bindResourceCallback"],listScopeToWatch.forEach(function(scopeName){newScopeName=scopeName.substring(4),newScopeName=newScopeName.charAt(0).toLowerCase()+newScopeName.slice(1),$attrs[scopeName]&&tastyUtil.bindTo(scopeName,$scope,$attrs,newScopeName)}),$scope.query.page=$scope.query.page||tableConfig.query.page,$scope.query.count=$scope.query.count||tableConfig.query.count,$scope.query.sortBy=$scope.query.sortBy||tableConfig.query.sortBy,$scope.query.sortOrder=$scope.query.sortOrder||tableConfig.query.sortOrder,$scope.init.count=$scope.init.count||tableConfig.init.count,$scope.init.page=$scope.init.page||tableConfig.init.page,$scope.init.sortBy=$scope.init.sortBy||tableConfig.init.sortBy,$scope.init.sortOrder=$scope.init.sortOrder||tableConfig.init.sortOrder;var listImmutableKey=["filters","init","query","rows","header","pagination","params","sortOrder","sortBy","url"];if($scope.clientSide=!0,$scope.url="",$scope.header={columns:[]},$scope.rows=[],$scope.params={},$scope.pagination={count:$scope.init.count,page:$scope.init.page,pages:1,size:0},$scope.theadDirective=!1,$scope.paginationDirective=!1,!angular.isDefined($attrs.bindResource)&&!angular.isDefined($attrs.bindResourceCallback))throw"AngularJS tastyTable directive: need the bind-resource or bind-resource-callback attribute";if(angular.isDefined($attrs.bindResource)){if(!angular.isObject($scope.resource))throw"AngularJS tastyTable directive: the bind-resource ("+$attrs.bindResource+") it's not an object";if(!$scope.resource.header&&!$scope.resource.rows)throw"AngularJS tastyTable directive: the bind-resource ("+$attrs.bindResource+") has the property header or rows undefined"}if(angular.isDefined($attrs.bindResourceCallback)){if(!angular.isFunction($scope.resourceCallback))throw"AngularJS tastyTable directive: the bind-resource-callback ("+$attrs.bindResourceCallback+") it's not a function";$scope.clientSide=!1}this.start=!1,this.activate=function(directiveName){$scope[directiveName+"Directive"]=!0,$scope.params[directiveName]=!0},this.setParams=function(key,value){$scope.params[key]=value,["sortBy","sortOrder"].indexOf(key)>=0&&($scope.header[key]=value)},this.initTable=function(keyDirective){initStatus[keyDirective]=!0,$scope.theadDirective||$scope.paginationDirective?$scope.theadDirective&&$scope.paginationDirective?initStatus.thead&&initStatus.pagination&&(this.start=!0):$scope.theadDirective&&!$scope.paginationDirective?initStatus.thead&&(this.start=!0):!$scope.theadDirective&&$scope.paginationDirective&&initStatus.pagination&&(this.start=!0):this.start=!0,this.start&&($scope.clientSide?($scope.params.sortBy=$scope.resource.sortBy||$scope.init.sortBy,$scope.params.sortOrder=$scope.resource.sortOrder||$scope.init.sortOrder,$scope.params.page=$scope.init.page,$scope.resource.pagination&&($scope.params.page=$scope.resource.pagination.page||$scope.init.page),$scope.$evalAsync(updateClientSideResource)):($scope.params.sortBy=$scope.init.sortBy,$scope.params.sortOrder=$scope.init.sortOrder,$scope.params.page=$scope.init.page,$scope.$evalAsync(updateServerSideResource)))},this.bindOnce=tableConfig.bindOnce,setDirectivesValues=function(resource){if(!angular.isObject(resource))throw"AngularJS tastyTable directive: the bind-resource it's not an object";if(!resource.header&&!resource.rows)throw"AngularJS tastyTable directive: the bind-resource has the property header or rows undefined";Object.keys(resource).forEach(function(key){listImmutableKey.indexOf(key)<0&&($scope[key]=resource[key])}),resource.header.length&&1===Object.keys(resource.header[0]).length&&(resource.header=resource.header.map(function(header){var key=Object.keys(header)[0];return{key:key,name:header[key]}})),$scope.header={columns:resource.header,sortBy:$scope.params.sortBy,sortOrder:$scope.params.sortOrder},$scope.clientSide||($scope.header.sortBy=$scope.header.sortBy||resource.sortBy,$scope.header.sortOrder=$scope.header.sortOrder||resource.sortOrder),$scope.rows=resource.rows,$scope.paginationDirective&&($scope.pagination.page=$scope.params.page,$scope.pagination.count=$scope.params.count,$scope.pagination.size=$scope.rows.length,resource.pagination&&(resource.pagination.count&&($scope.pagination.count=resource.pagination.count),resource.pagination.page&&($scope.pagination.page=resource.pagination.page),resource.pagination.size&&($scope.pagination.size=resource.pagination.size)),$scope.pagination.pages=Math.ceil($scope.pagination.size/$scope.pagination.count))},buildClientResource=function(updateFrom){var fromRow,toRow,rowToShow,reverse,listSortBy;$scope.theadDirective&&$scope.header.columns.length&&(reverse="asc"===$scope.header.sortOrder?!1:!0,listSortBy=[function(item){return item[$scope.header.sortBy]}],$scope.header.columns[0].key!==$scope.header.sortBy&&listSortBy.push(function(item){return item[$scope.header.columns[0].key]}),$scope.header.sortBy&&($scope.rows=$filter("orderBy")($scope.rows,listSortBy,reverse))),$attrs.bindFilters&&($scope.rows=$filter("filter")($scope.rows,$scope.filters)),$scope.paginationDirective&&($scope.pagination.page="filters"===updateFrom?1:$scope.params.page,$scope.pagination.count=$scope.params.count,$scope.pagination.size=$scope.rows.length,$scope.pagination.pages=Math.ceil($scope.rows.length/$scope.pagination.count),toRow=$scope.pagination.count*$scope.pagination.page,fromRow=toRow-$scope.pagination.count,fromRow>=0&&toRow>=0&&(rowToShow=$scope.rows.slice(fromRow,toRow),$scope.rows=rowToShow))},buildUrl=function(params,filters){var urlQuery,value,listKeyNotJoin;return urlQuery={},listKeyNotJoin=["sortBy","sortOrder","page","count"],$scope.theadDirective&&(urlQuery=tastyUtil.setProperty(urlQuery,params,"sortBy"),urlQuery=tastyUtil.setProperty(urlQuery,params,"sortOrder")),$scope.paginationDirective&&(urlQuery=tastyUtil.setProperty(urlQuery,params,"page"),urlQuery=tastyUtil.setProperty(urlQuery,params,"count")),$attrs.bindFilters&&(urlQuery=tastyUtil.joinObjects(urlQuery,filters,listKeyNotJoin)),Object.keys(urlQuery).map(function(key){return value=urlQuery[key],$scope.query[key]&&(key=$scope.query[key]),encodeURIComponent(key)+"="+encodeURIComponent(value)}).join("&")},updateClientSideResource=function(updateFrom){setDirectivesValues($scope.resource),buildClientResource(updateFrom)},updateServerSideResource=function(){$scope.url=buildUrl($scope.params,$scope.filters),$scope.resourceCallback($scope.url,angular.copy($scope.params)).then(function(resource){setDirectivesValues(resource)})},$attrs.bindFilters&&$scope.$watch("filters",function(newValue,oldValue){newValue!==oldValue&&($scope.clientSide?$scope.$evalAsync(updateClientSideResource("filters")):$scope.$evalAsync(updateServerSideResource))},!0),$scope.$watchCollection("params",function(newValue,oldValue){newValue!==oldValue&&($scope.clientSide?$scope.$evalAsync(updateClientSideResource("params")):$scope.$evalAsync(updateServerSideResource))}),$scope.resource&&$scope.$watch("resource",function(newValue,oldValue){newValue!==oldValue&&($scope.params.sortBy=newValue.sortBy,$scope.params.sortOrder=newValue.sortOrder,$scope.$evalAsync(updateClientSideResource("resource")))},!0)}]).directive("tastyTable",function(){return{restrict:"A",scope:!0,controller:"TableController",link:function(scope,element,attrs,tastyTable){(element.find("tasty-thead").length||element[0].querySelector("[tasty-thead]"))&&tastyTable.activate("thead"),(element.find("tasty-pagination").length||element[0].querySelector("[tasty-pagination]"))&&tastyTable.activate("pagination"),tastyTable.initTable()}}}).directive("tastyThead",["$filter","tableConfig","tastyUtil",function($filter,tableConfig,tastyUtil){return{restrict:"AE",require:"^tastyTable",scope:{},templateUrl:"template/table/head.html",link:function(scope,element,attrs,tastyTable){"use strict";var newScopeName,listScopeToWatch;scope.bindOnce=tastyTable.bindOnce,scope.columns=[],scope.bootstrapIcon=tableConfig.bootstrapIcon,scope.iconUp=tableConfig.iconUp,scope.iconDown=tableConfig.iconDown,listScopeToWatch=["bindNotSortBy","bindBootstrapIcon","bindIconUp","bindIconDown"],listScopeToWatch.forEach(function(scopeName){newScopeName=scopeName.substring(4),newScopeName=newScopeName.charAt(0).toLowerCase()+newScopeName.slice(1),attrs[scopeName]?tastyUtil.bindTo(scopeName,scope,attrs,newScopeName):attrs[newScopeName]&&(scope[newScopeName]="["===attrs[newScopeName][0]?JSON.parse(attrs[newScopeName]):attrs[newScopeName])}),scope.setColumns=function(){var lenHeader,active,sortable,sort,isSorted,isSortedCaret;scope.columns=[],lenHeader=scope.header.columns.length,scope.header.columns.forEach(function(column){column.style=column.style||{},sortable=!0,active=!1,isSorted="",isSortedCaret="",angular.isArray(scope.notSortBy)&&(sortable=scope.notSortBy.length?scope.notSortBy.indexOf(column.key)<0:!1),(column.key===scope.header.sortBy||"-"+column.key===scope.header.sortBy)&&(active=!0),sort=$filter("cleanFieldName")(column.key),scope.header.sortBy==="-"+sort?tableConfig.bootstrapIcon?(isSorted="",isSortedCaret="caret"):isSorted=scope.iconDown:scope.header.sortBy===sort&&(tableConfig.bootstrapIcon?(isSorted="dropup",isSortedCaret="caret"):isSorted=scope.iconUp),scope.columns.push({key:column.key,name:column.name,active:active,sortable:sortable,style:column.style,isSorted:isSorted,isSortedCaret:isSortedCaret})}),"dsc"===scope.header.sortOrder&&scope.header.sortBy&&"-"!==scope.header.sortBy[0]&&(scope.header.sortBy="-"+scope.header.sortBy),tastyTable.start||tastyTable.initTable("thead")},scope.sortBy=function(column){if(!column.sortable)return!1;var columnName,sortOrder;columnName=$filter("cleanFieldName")(column.key),sortOrder=scope.header.sortBy===columnName?"dsc":"asc",tastyTable.setParams("sortBy",column.key),tastyTable.setParams("sortOrder",sortOrder)},scope.classToShow=function(column){var listClassToShow=[];return column.sortable&&listClassToShow.push("sortable"),column.active&&listClassToShow.push("active"),listClassToShow},tastyTable.$scope.$watchCollection("header",function(newValue,oldValue){!newValue||newValue===oldValue&&tastyTable.start||(scope.header=newValue,scope.setColumns())})}}}]).directive("tastyPagination",["$filter","$templateCache","$http","$compile","tableConfig","tastyUtil",function($filter,$templateCache,$http,$compile,tableConfig,tastyUtil){return{restrict:"AE",require:"^tastyTable",scope:{},templateUrl:function(tElement,tAttrs){return tAttrs.templateUrl||tableConfig.templateUrl},link:function(scope,element,attrs,tastyTable){"use strict";var getPage,setCount,setPaginationRange,setPreviousRange,setRemainingRange,setPaginationRanges,listScopeToWatch,newScopeName;listScopeToWatch=["bindItemsPerPage","bindListItemsPerPage","bindTemplateUrl"],listScopeToWatch.forEach(function(scopeName){newScopeName=scopeName.substring(4),newScopeName=newScopeName.charAt(0).toLowerCase()+newScopeName.slice(1),attrs[scopeName]?tastyUtil.bindTo(scopeName,scope,attrs,newScopeName):attrs[newScopeName]&&(scope[newScopeName]="itemsPerPage"===newScopeName?parseInt(attrs[newScopeName]):JSON.parse(attrs[newScopeName]))}),scope.templateUrl&&$http.get(scope.templateUrl,{cache:$templateCache}).success(function(templateContent){element.replaceWith($compile(templateContent)(scope))}),scope.itemsPerPage=scope.itemsPerPage||tableConfig.itemsPerPage,scope.listItemsPerPage=scope.listItemsPerPage||tableConfig.listItemsPerPage,scope.pagination={},scope.pagMinRange=1,scope.pagMaxRange=1,getPage=function(numPage){tastyTable.setParams("page",numPage)},setCount=function(count){var maxItems,page;maxItems=count*scope.pagination.page,maxItems>scope.pagination.size&&(page=Math.ceil(scope.pagination.size/count),tastyTable.setParams("page",page)),tastyTable.setParams("count",count)},setPaginationRange=function(){var currentPage;currentPage=scope.pagination.page,currentPage>scope.pagination.pages&&(currentPage=scope.pagination.pages),scope.pagMinRange=currentPage-2>0?currentPage-2:1,scope.pagMaxRange=currentPage+2,scope.pagination.page=currentPage,setPaginationRanges()},setPreviousRange=function(){return scope.pagHideMinRange===!0||scope.pagMinRange<1?!1:(scope.pagMaxRange=scope.pagMinRange,scope.pagMinRange=scope.pagMaxRange-scope.itemsPerPage,setPaginationRanges(),void 0)},setRemainingRange=function(){return scope.pagHideMaxRange===!0||scope.pagMaxRange>scope.pagination.pages?!1:(scope.pagMinRange=scope.pagMaxRange,scope.pagMaxRange=scope.pagMinRange+scope.itemsPerPage,scope.pagMaxRange>scope.pagination.pages&&(scope.pagMaxRange=scope.pagination.pages),scope.pagMinRange=scope.pagMaxRange-scope.itemsPerPage,setPaginationRanges(),void 0)},setPaginationRanges=function(){scope.listItemsPerPageShow=[],scope.pagMinRange=scope.pagMinRange>0?scope.pagMinRange:1,scope.pagMaxRange=scope.pagMinRange+5,scope.pagMaxRange>scope.pagination.pages&&(scope.pagMaxRange=scope.pagination.pages+1),scope.pagHideMinRange=scope.pagMinRange<=1,scope.pagHideMaxRange=scope.pagMaxRange>=scope.pagination.pages,scope.classPageMinRange=scope.pagHideMinRange?"disabled":"",scope.classPageMaxRange=scope.pagHideMaxRange?"disabled":"";for(var i=scope.listItemsPerPage.length;i>=0;i--)if(scope.pagination.size>scope.listItemsPerPage[i]){scope.listItemsPerPageShow=scope.listItemsPerPage.slice(0,i+1);break}scope.rangePage=$filter("range")([],scope.pagMinRange,scope.pagMaxRange),tastyTable.start||tastyTable.initTable("pagination")},scope.classPaginationCount=function(count){return count==scope.pagination.count?"active":""},scope.classNumPage=function(numPage){return numPage==scope.pagination.page?"active":!1},scope.page={get:getPage,setCount:setCount,previous:setPreviousRange,remaining:setRemainingRange},tastyTable.$scope.$watchCollection("pagination",function(newValue,oldValue){!newValue||newValue===oldValue&&tastyTable.start||(scope.pagination=newValue,setPaginationRange())}),scope.page.setCount(scope.itemsPerPage)}}}]),angular.module("ngTasty.filter.cleanFieldName",[]).filter("cleanFieldName",function(){return function(input){return input.replace(/[^a-zA-Z0-9-]+/g,"-")}}),angular.module("ngTasty.filter.filterInt",[]).filter("filterInt",function(){return function(input){return/^(\-|\+)?([0-9]+|Infinity)$/.test(input)?Number(input):0/0}}),angular.module("ngTasty.filter.range",["ngTasty.filter.filterInt"]).filter("range",["$filter",function($filter){return function(input,start,stop,step){if(start=$filter("filterInt")(start),stop=$filter("filterInt")(stop),step=$filter("filterInt")(step),isNaN(start)&&(start=0),isNaN(stop)&&(stop=start,start=0),isNaN(step)&&(step=1),step>0&&start>=stop||0>step&&stop>=start)return[];for(var i=start;step>0?stop>i:i>stop;i+=step)input.push(i);return input}}]),angular.module("ngTasty.service.bindTo",[]).factory("bindTo",["$parse",function($parse){return function(scopeName,scope,attrs,newScopeName){var lastValue,parentGet,compare,parentSet,parentValueWatch,isolateScopeName;attrs[scopeName]&&(parentGet=$parse(attrs[scopeName]),compare=parentGet.literal?equals:function(a,b){return a===b||a!==a&&b!==b},isolateScopeName=newScopeName?newScopeName:scopeName,parentSet=parentGet.assign,lastValue=scope[isolateScopeName]=parentGet(scope.$parent),parentValueWatch=function(parentValue){return compare(parentValue,scope[isolateScopeName])||(compare(parentValue,lastValue)?parentSet(scope.$parent,parentValue=scope[isolateScopeName]):scope[isolateScopeName]=parentValue),lastValue=parentValue},parentValueWatch.$stateful=!0,scope.$parent.$watch($parse(attrs[scopeName],parentValueWatch),null,parentGet.literal))}}]),angular.module("ngTasty.service.debounce",[]).factory("debounce",["$timeout",function($timeout){return function(func,wait){var timeout;return function(){var context=this,args=arguments;$timeout.cancel(timeout),timeout=$timeout(function(){timeout=null,func.apply(context,args)},wait)}}}]),angular.module("ngTasty.service.joinObjects",["ngTasty.service.setProperty"]).factory("joinObjects",["setProperty",function(setProperty){return function(objOne,objTwo,listKeyNotJoin){listKeyNotJoin=listKeyNotJoin||[];for(var attrname in objTwo)listKeyNotJoin.indexOf(attrname)<0&&setProperty(objOne,objTwo,attrname);return objOne}}]),angular.module("ngTasty.service.setProperty",[]).factory("setProperty",function(){return function(objOne,objTwo,attrname){return"undefined"!=typeof objTwo[attrname]&&null!==objTwo[attrname]&&(objOne[attrname]=objTwo[attrname]),objOne}}),angular.module("ngTasty.service.tastyUtil",["ngTasty.service.bindTo","ngTasty.service.debounce","ngTasty.service.setProperty","ngTasty.service.joinObjects","ngTasty.service.throttle","ngTasty.service.webSocket"]).factory("tastyUtil",["debounce","setProperty","joinObjects","bindTo","webSocket","throttle",function(debounce,setProperty,joinObjects,bindTo,webSocket,throttle){return{bindTo:bindTo,debounce:debounce,setProperty:setProperty,joinObjects:joinObjects,throttle:throttle,webSocket:webSocket}}]),angular.module("ngTasty.service.throttle",[]).factory("throttle",["$timeout",function($timeout){return function(fn,threshhold,scope){threshhold||(threshhold=250);var last,promise;return function(){var context=scope||this,now=+new Date,args=arguments;last&&last+threshhold>now?($timeout.cancel(promise),promise=$timeout(function(){last=now,fn.apply(context,args)},threshhold)):(last=now,fn.apply(context,args))}}}]),angular.module("ngTasty.service.webSocket",[]).factory("webSocket",function(){return function(url){var blobURL=URL.createObjectURL(new Blob(["(",function(){var WSWorker=function(){var _ws,initialize=function(url){_ws=new WebSocket(url)},on=function(){_ws.onmessage=function(response){var data=JSON.parse(response.data);self.postMessage(data)}},send=function(data){_ws.send(data)};return{initialize:initialize,on:on,send:send}}();self.addEventListener("message",function(e){switch(e.data.cmd){case"ws_new":WSWorker.initialize(e.data.url);break;case"ws_on":WSWorker.on(e.data.event,e.data.cb);break;case"ws_send":WSWorker.send(JSON.stringify(e.data.data));break;default:console.log("Unknown command: "+e.data.cmd)}})}.toString(),")()"],{type:"application/javascript"})),_worker=new Worker(blobURL);return URL.revokeObjectURL(blobURL),_worker.postMessage({cmd:"ws_new",url:url}),{on:function(event,cb){_worker.postMessage({cmd:"ws_on"}),_worker.addEventListener("message",function(e){("all"===event||e.data.type===event)&&cb(e.data)})},send:function(data){_worker.postMessage({cmd:"ws_send",data:data})}}}}),function(module){try{module=angular.module("ngTasty.tpls.table.head")}catch(e){module=angular.module("ngTasty.tpls.table.head",[])}module.run(["$templateCache",function($templateCache){$templateCache.put("template/table/head.html",'<tr>\n <th ng-repeat="column in columns track by $index" \n ng-class="classToShow(column)"\n ng-style="::column.style" ng-click="sortBy(column)">\n <span ng-bind="::column.name"></span>\n <span ng-class="column.isSorted">\n <span ng-class="column.isSortedCaret" ng-if="::bootstrapIcon"></span>\n </span>\n </th> \n</tr>')}])}(),function(module){try{module=angular.module("ngTasty.tpls.table.pagination")}catch(e){module=angular.module("ngTasty.tpls.table.pagination",[])}module.run(["$templateCache",function($templateCache){$templateCache.put("template/table/pagination.html",'<div class="row">\n <div class="col-xs-3 text-left">\n <div class="btn-group">\n <button type="button" class="btn btn-default" \n ng-repeat="count in listItemsPerPageShow" \n ng-class="classPaginationCount(count)" \n ng-click="page.setCount(count)" ng-bind="count"></button>\n </div>\n </div>\n <div class="col-xs-6 text-center">\n <ul class="pagination">\n <li ng-class="classPageMinRange">\n <a href ng-click="page.previous()">&laquo;</a>\n </li>\n <li ng-repeat="numPage in rangePage" ng-class="classNumPage(numPage)">\n <a href ng-click="page.get(numPage)">\n <span ng-bind="numPage"></span>\n <span class="sr-only" ng-if="classNumPage(numPage)">(current)</span>\n </a>\n </li>\n <li ng-class="classPageMaxRange">\n <a href ng-click="page.remaining()">&raquo;</a>\n </li>\n </ul>\n </div>\n <div class="col-xs-3 text-right">\n <p>Page <span ng-bind="pagination.page"></span> \n of <span ng-bind="pagination.pages"></span>,\n of <span ng-bind="pagination.size"></span> entries</p>\n </div>\n</div>')}])}();
angular.module("ngTasty",["ngTasty.tpls","ngTasty.component.table","ngTasty.filter.camelize","ngTasty.filter.cleanFieldName","ngTasty.filter.filterInt","ngTasty.filter.range","ngTasty.filter.slugify","ngTasty.service.bindTo","ngTasty.service.debounce","ngTasty.service.joinObjects","ngTasty.service.setProperty","ngTasty.service.tastyUtil","ngTasty.service.throttle","ngTasty.service.webSocket"]),angular.module("ngTasty.tpls",["ngTasty.tpls.table.head","ngTasty.tpls.table.pagination"]),angular.module("ngTasty.component.table",["ngTasty.filter.cleanFieldName","ngTasty.filter.range","ngTasty.service.tastyUtil","ngTasty.tpls.table.head","ngTasty.tpls.table.pagination"]).constant("tableConfig",{init:{count:5,page:1,sortBy:void 0,sortOrder:void 0},query:{page:"page",count:"count",sortBy:"sort-by",sortOrder:"sort-order"},bindOnce:!0,iconUp:"fa fa-sort-up",iconDown:"fa fa-sort-down",bootstrapIcon:!1,templateUrl:"template/table/pagination.html",listItemsPerPage:[5,25,50,100],itemsPerPage:5,watchResource:"reference"}).controller("TableController",["$scope","$attrs","$filter","tableConfig","tastyUtil",function($scope,$attrs,$filter,tableConfig,tastyUtil){"use strict";var listScopeToWatch,newScopeName,initStatus,updateClientSideResource,updateServerSideResource,setDirectivesValues,buildClientResource,buildUrl;this.$scope=$scope,initStatus={},$scope.init={},$scope.query={},$scope.logs={buildClientResourceCount:0},listScopeToWatch=["bindFilters","bindInit","bindQuery","bindResource","bindResourceCallback","bindWatchResource"],listScopeToWatch.forEach(function(scopeName){newScopeName=scopeName.substring(4),newScopeName=newScopeName.charAt(0).toLowerCase()+newScopeName.slice(1),$attrs[scopeName]&&tastyUtil.bindTo(scopeName,$scope,$attrs,newScopeName)}),$scope.query.page=$scope.query.page||tableConfig.query.page,$scope.query.count=$scope.query.count||tableConfig.query.count,$scope.query.sortBy=$scope.query.sortBy||tableConfig.query.sortBy,$scope.query.sortOrder=$scope.query.sortOrder||tableConfig.query.sortOrder,$scope.init.count=$scope.init.count||tableConfig.init.count,$scope.init.page=$scope.init.page||tableConfig.init.page,$scope.init.sortBy=$scope.init.sortBy||tableConfig.init.sortBy,$scope.init.sortOrder=$scope.init.sortOrder||tableConfig.init.sortOrder,$scope.watchResource=$scope.watchResource||tableConfig.watchResource;var listImmutableKey=["filters","init","query","rows","header","pagination","params","sortOrder","sortBy","url"];if($scope.clientSide=!0,$scope.url="",$scope.header={columns:[]},$scope.rows=[],$scope.params={},$scope.pagination={count:$scope.init.count,page:$scope.init.page,pages:1,size:0},$scope.theadDirective=!1,$scope.paginationDirective=!1,!angular.isDefined($attrs.bindResource)&&!angular.isDefined($attrs.bindResourceCallback))throw"AngularJS tastyTable directive: need the bind-resource or bind-resource-callback attribute";if(angular.isDefined($attrs.bindResource)){if(!angular.isObject($scope.resource))throw"AngularJS tastyTable directive: the bind-resource ("+$attrs.bindResource+") is not an object";if(!$scope.resource.header&&!$scope.resource.rows)throw"AngularJS tastyTable directive: the bind-resource ("+$attrs.bindResource+") has the property header or rows undefined"}if(angular.isDefined($attrs.bindResourceCallback)){if(!angular.isFunction($scope.resourceCallback))throw"AngularJS tastyTable directive: the bind-resource-callback ("+$attrs.bindResourceCallback+") is not a function";$scope.clientSide=!1}if(this.start=!1,this.activate=function(directiveName){$scope[directiveName+"Directive"]=!0,$scope.params[directiveName]=!0},this.setParams=function(key,value){$scope.params[key]=value,["sortBy","sortOrder"].indexOf(key)>=0&&($scope.header[key]=value)},this.initTable=function(keyDirective){initStatus[keyDirective]=!0,$scope.theadDirective||$scope.paginationDirective?$scope.theadDirective&&$scope.paginationDirective?initStatus.thead&&initStatus.pagination&&(this.start=!0):$scope.theadDirective&&!$scope.paginationDirective?initStatus.thead&&(this.start=!0):!$scope.theadDirective&&$scope.paginationDirective&&initStatus.pagination&&(this.start=!0):this.start=!0,this.start&&($scope.clientSide?($scope.params.sortBy=$scope.resource.sortBy||$scope.init.sortBy,$scope.params.sortOrder=$scope.resource.sortOrder||$scope.init.sortOrder,$scope.params.page=$scope.init.page,$scope.resource.pagination&&($scope.params.page=$scope.resource.pagination.page||$scope.init.page),$scope.$evalAsync(updateClientSideResource)):($scope.params.sortBy=$scope.init.sortBy,$scope.params.sortOrder=$scope.init.sortOrder,$scope.params.page=$scope.init.page,$scope.$evalAsync(updateServerSideResource)))},this.bindOnce=tableConfig.bindOnce,setDirectivesValues=function(resource){if(!$scope.resource&&!angular.isObject(resource))throw"AngularJS tastyTable directive: the resource response is not an object";if(!resource.header&&!resource.rows)throw"AngularJS tastyTable directive: the resource response object has the property header or rows undefined";Object.keys(resource).forEach(function(key){listImmutableKey.indexOf(key)<0&&($scope[key]=resource[key])}),resource.header.length&&1===Object.keys(resource.header[0]).length&&(resource.header=resource.header.map(function(header){var key=Object.keys(header)[0];return{key:key,name:header[key]}})),$scope.header={columns:resource.header,sortBy:$scope.params.sortBy,sortOrder:$scope.params.sortOrder},$scope.clientSide||($scope.header.sortBy=$scope.header.sortBy||resource.sortBy,$scope.header.sortOrder=$scope.header.sortOrder||resource.sortOrder),$scope.rows=resource.rows,$scope.paginationDirective&&($scope.pagination.page=$scope.params.page,$scope.pagination.count=$scope.params.count,$scope.pagination.size=$scope.rows.length,resource.pagination&&(resource.pagination.count&&($scope.pagination.count=resource.pagination.count),resource.pagination.page&&($scope.pagination.page=resource.pagination.page),resource.pagination.size&&($scope.pagination.size=resource.pagination.size)),$scope.pagination.pages=Math.ceil($scope.pagination.size/$scope.pagination.count))},buildClientResource=function(updateFrom){var fromRow,toRow,rowToShow,reverse,listSortBy;$scope.logs.buildClientResourceCount+=1,$scope.theadDirective&&$scope.header.columns.length&&(reverse="asc"===$scope.header.sortOrder?!1:!0,listSortBy=[function(item){return item[$scope.header.sortBy]}],$scope.header.columns[0].key!==$scope.header.sortBy&&listSortBy.push(function(item){return item[$scope.header.columns[0].key]}),$scope.header.sortBy&&($scope.rows=$filter("orderBy")($scope.rows,listSortBy,reverse))),$attrs.bindFilters&&($scope.rows=$filter("filter")($scope.rows,$scope.filters)),$scope.paginationDirective&&($scope.pagination.page="filters"===updateFrom?1:$scope.params.page,$scope.pagination.count=$scope.params.count,$scope.pagination.size=$scope.rows.length,$scope.pagination.pages=Math.ceil($scope.rows.length/$scope.pagination.count),toRow=$scope.pagination.count*$scope.pagination.page,fromRow=toRow-$scope.pagination.count,fromRow>=0&&toRow>=0&&(rowToShow=$scope.rows.slice(fromRow,toRow),$scope.rows=rowToShow))},buildUrl=function(params,filters){var urlQuery,value,listKeyNotJoin;return urlQuery={},listKeyNotJoin=["sortBy","sortOrder","page","count"],$scope.theadDirective&&(urlQuery=tastyUtil.setProperty(urlQuery,params,"sortBy"),urlQuery=tastyUtil.setProperty(urlQuery,params,"sortOrder")),$scope.paginationDirective&&(urlQuery=tastyUtil.setProperty(urlQuery,params,"page"),urlQuery=tastyUtil.setProperty(urlQuery,params,"count")),$attrs.bindFilters&&(urlQuery=tastyUtil.joinObjects(urlQuery,filters,listKeyNotJoin)),Object.keys(urlQuery).map(function(key){return value=urlQuery[key],$scope.query[key]&&(key=$scope.query[key]),encodeURIComponent(key)+"="+encodeURIComponent(value)}).join("&")},updateClientSideResource=function(updateFrom){setDirectivesValues($scope.resource),buildClientResource(updateFrom)},updateServerSideResource=function(){$scope.url=buildUrl($scope.params,$scope.filters),$scope.resourceCallback($scope.url,angular.copy($scope.params)).then(function(resource){setDirectivesValues(resource)})},$attrs.bindFilters&&$scope.$watch("filters",function(newValue,oldValue){newValue!==oldValue&&($scope.clientSide?$scope.$evalAsync(updateClientSideResource("filters")):$scope.$evalAsync(updateServerSideResource))},!0),$scope.$watchCollection("params",function(newValue,oldValue){newValue!==oldValue&&($scope.clientSide?$scope.$evalAsync(updateClientSideResource("params")):$scope.$evalAsync(updateServerSideResource))}),$scope.resource){var watchResource=function(newValue,oldValue){newValue!==oldValue&&($scope.params.sortBy=newValue.sortBy,$scope.params.sortOrder=newValue.sortOrder,$scope.$evalAsync(updateClientSideResource("resource")),$scope.resource.reload||($scope.resource.reload=function(){$scope.$evalAsync(updateClientSideResource("resource"))}))};"reference"===$scope.watchResource?$scope.$watch("resource",watchResource):"collection"===$scope.watchResource?($scope.$watchCollection("resource.header",watchResource),$scope.$watchCollection("resource.rows",watchResource),$scope.$watchGroup(["sortBy","sortOrder","pagination.count","pagination.page","pagination.pages","pagination.size"],watchResource)):"equality"===$scope.watchResource&&$scope.$watch("resource",function(newValue,oldValue){newValue!==oldValue&&($scope.params.sortBy=newValue.sortBy,$scope.params.sortOrder=newValue.sortOrder,$scope.$evalAsync(updateClientSideResource("resource")))},!0)}}]).directive("tastyTable",function(){return{restrict:"A",scope:!0,controller:"TableController",link:function(scope,element,attrs,tastyTable){(element.find("tasty-thead").length||element[0].querySelector("[tasty-thead]"))&&tastyTable.activate("thead"),(element.find("tasty-pagination").length||element[0].querySelector("[tasty-pagination]"))&&tastyTable.activate("pagination"),tastyTable.initTable()}}}).directive("tastyThead",["$filter","tableConfig","tastyUtil",function($filter,tableConfig,tastyUtil){return{restrict:"AE",require:"^tastyTable",scope:{},templateUrl:"template/table/head.html",link:function(scope,element,attrs,tastyTable){"use strict";var newScopeName,listScopeToWatch;scope.bindOnce=tastyTable.bindOnce,scope.columns=[],scope.bootstrapIcon=tableConfig.bootstrapIcon,scope.iconUp=tableConfig.iconUp,scope.iconDown=tableConfig.iconDown,listScopeToWatch=["bindNotSortBy","bindBootstrapIcon","bindIconUp","bindIconDown"],listScopeToWatch.forEach(function(scopeName){newScopeName=scopeName.substring(4),newScopeName=newScopeName.charAt(0).toLowerCase()+newScopeName.slice(1),attrs[scopeName]?tastyUtil.bindTo(scopeName,scope,attrs,newScopeName):attrs[newScopeName]&&(scope[newScopeName]="["===attrs[newScopeName][0]?JSON.parse(attrs[newScopeName]):attrs[newScopeName])}),scope.setColumns=function(){var active,sortable,sort,isSorted,isSortedCaret;scope.columns=[],scope.header.columns.forEach(function(column){column.style=column.style||{},sortable=!0,active=!1,isSorted="",isSortedCaret="",angular.isArray(scope.notSortBy)&&(sortable=scope.notSortBy.length?scope.notSortBy.indexOf(column.key)<0:!1),(column.key===scope.header.sortBy||"-"+column.key===scope.header.sortBy)&&(active=!0),sort=$filter("cleanFieldName")(column.key),scope.header.sortBy==="-"+sort?tableConfig.bootstrapIcon?(isSorted="",isSortedCaret="caret"):isSorted=scope.iconDown:scope.header.sortBy===sort&&(tableConfig.bootstrapIcon?(isSorted="dropup",isSortedCaret="caret"):isSorted=scope.iconUp),scope.columns.push({key:column.key,name:column.name,active:active,sortable:sortable,style:column.style,isSorted:isSorted,isSortedCaret:isSortedCaret})}),"dsc"===scope.header.sortOrder&&scope.header.sortBy&&"-"!==scope.header.sortBy[0]&&(scope.header.sortBy="-"+scope.header.sortBy),tastyTable.start||tastyTable.initTable("thead")},scope.sortBy=function(column){if(!column.sortable)return!1;var columnName,sortOrder;columnName=$filter("cleanFieldName")(column.key),sortOrder=scope.header.sortBy===columnName?"dsc":"asc",tastyTable.setParams("sortBy",column.key),tastyTable.setParams("sortOrder",sortOrder)},scope.classToShow=function(column){var listClassToShow=[];return column.sortable&&listClassToShow.push("sortable"),column.active&&listClassToShow.push("active"),listClassToShow},tastyTable.$scope.$watchCollection("header",function(newValue,oldValue){!newValue||newValue===oldValue&&tastyTable.start||(scope.header=newValue,scope.setColumns())})}}}]).directive("tastyPagination",["$filter","$templateCache","$http","$compile","tableConfig","tastyUtil",function($filter,$templateCache,$http,$compile,tableConfig,tastyUtil){return{restrict:"AE",require:"^tastyTable",scope:{},templateUrl:function(tElement,tAttrs){return tAttrs.templateUrl||tableConfig.templateUrl},link:function(scope,element,attrs,tastyTable){"use strict";var getPage,setCount,setPaginationRange,setPreviousRange,setRemainingRange,setPaginationRanges,listScopeToWatch,newScopeName;listScopeToWatch=["bindItemsPerPage","bindListItemsPerPage","bindTemplateUrl"],listScopeToWatch.forEach(function(scopeName){newScopeName=scopeName.substring(4),newScopeName=newScopeName.charAt(0).toLowerCase()+newScopeName.slice(1),attrs[scopeName]?tastyUtil.bindTo(scopeName,scope,attrs,newScopeName):attrs[newScopeName]&&(scope[newScopeName]="itemsPerPage"===newScopeName?parseInt(attrs[newScopeName]):JSON.parse(attrs[newScopeName]))}),scope.templateUrl&&$http.get(scope.templateUrl,{cache:$templateCache}).success(function(templateContent){element.replaceWith($compile(templateContent)(scope))}),scope.itemsPerPage=scope.itemsPerPage||tableConfig.itemsPerPage,scope.listItemsPerPage=scope.listItemsPerPage||tableConfig.listItemsPerPage,scope.pagination={},scope.pagMinRange=1,scope.pagMaxRange=1,getPage=function(numPage){tastyTable.setParams("page",numPage)},setCount=function(count){var maxItems,page;maxItems=count*scope.pagination.page,maxItems>scope.pagination.size&&(page=Math.ceil(scope.pagination.size/count),tastyTable.setParams("page",page)),tastyTable.setParams("count",count)},setPaginationRange=function(){var currentPage;currentPage=scope.pagination.page,currentPage>scope.pagination.pages&&(currentPage=scope.pagination.pages),scope.pagMinRange=currentPage-2>0?currentPage-2:1,scope.pagMaxRange=currentPage+2,scope.pagination.page=currentPage,setPaginationRanges()},setPreviousRange=function(){return scope.pagHideMinRange===!0||scope.pagMinRange<1?!1:(scope.pagMaxRange=scope.pagMinRange,scope.pagMinRange=scope.pagMaxRange-scope.itemsPerPage,setPaginationRanges(),void 0)},setRemainingRange=function(){return scope.pagHideMaxRange===!0||scope.pagMaxRange>scope.pagination.pages?!1:(scope.pagMinRange=scope.pagMaxRange,scope.pagMaxRange=scope.pagMinRange+scope.itemsPerPage,scope.pagMaxRange>scope.pagination.pages&&(scope.pagMaxRange=scope.pagination.pages),scope.pagMinRange=scope.pagMaxRange-scope.itemsPerPage,setPaginationRanges(),void 0)},setPaginationRanges=function(){scope.listItemsPerPageShow=[],scope.pagMinRange=scope.pagMinRange>0?scope.pagMinRange:1,scope.pagMaxRange=scope.pagMinRange+5,scope.pagMaxRange>scope.pagination.pages&&(scope.pagMaxRange=scope.pagination.pages+1),scope.pagHideMinRange=scope.pagMinRange<=1,scope.pagHideMaxRange=scope.pagMaxRange>=scope.pagination.pages,scope.classPageMinRange=scope.pagHideMinRange?"disabled":"",scope.classPageMaxRange=scope.pagHideMaxRange?"disabled":"";for(var i=scope.listItemsPerPage.length;i>=0;i--)if(scope.pagination.size>scope.listItemsPerPage[i]){scope.listItemsPerPageShow=scope.listItemsPerPage.slice(0,i+1);break}scope.rangePage=$filter("range")([],scope.pagMinRange,scope.pagMaxRange),tastyTable.start||tastyTable.initTable("pagination")},scope.classPaginationCount=function(count){return count==scope.pagination.count?"active":""},scope.classNumPage=function(numPage){return numPage==scope.pagination.page?"active":!1},scope.page={get:getPage,setCount:setCount,previous:setPreviousRange,remaining:setRemainingRange},tastyTable.$scope.$watchCollection("pagination",function(newValue,oldValue){!newValue||newValue===oldValue&&tastyTable.start||(scope.pagination=newValue,setPaginationRange())}),scope.page.setCount(scope.itemsPerPage)}}}]),angular.module("ngTasty.filter.camelize",[]).filter("camelize",function(){var CAMELIZE_REGEX=/(?:^|[-_ ])(\w)/g;return function(input,first){var isString="string"==typeof input,first="undefined"==typeof first?!1:!!first;return"undefined"==typeof input||null===input||!isString&&isNaN(input)?"":isString?input.trim().replace(/ +(?= )/g,"").replace(CAMELIZE_REGEX,function(_,character,pos){return character&&(first||pos>0)?character.toUpperCase():character}):""+input}}),angular.module("ngTasty.filter.cleanFieldName",[]).filter("cleanFieldName",function(){return function(input){return input.replace(/[^a-zA-Z0-9-]+/g,"-")}}),angular.module("ngTasty.filter.filterInt",[]).filter("filterInt",function(){return function(input){return/^(\-|\+)?([0-9]+|Infinity)$/.test(input)?Number(input):0/0}}),angular.module("ngTasty.filter.range",["ngTasty.filter.filterInt"]).filter("range",["$filter",function($filter){return function(input,start,stop,step){if(start=$filter("filterInt")(start),stop=$filter("filterInt")(stop),step=$filter("filterInt")(step),isNaN(start)&&(start=0),isNaN(stop)&&(stop=start,start=0),isNaN(step)&&(step=1),step>0&&start>=stop||0>step&&stop>=start)return[];for(var i=start;step>0?stop>i:i>stop;i+=step)input.push(i);return input}}]),angular.module("ngTasty.filter.slugify",[]).filter("slugify",function(){var makeString=function(object){return null==object?"":""+object},defaultToWhiteSpace=function(characters){return null==characters?"\\s":characters.source?characters.source:"["+characters.replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")+"]"},from="ąàáäâãåæăćčĉęèéëêĝĥìíïîĵłľńňòóöőôõðøśșšŝťțŭùúüűûñÿýçżźž",to="aaaaaaaaaccceeeeeghiiiijllnnoooooooossssttuuuuuunyyczzz",regex=new RegExp(defaultToWhiteSpace(from),"g");return function(str){return str=makeString(str).toString().toLowerCase().replace(regex,function(c){var index=from.indexOf(c);return to.charAt(index)||"-"}).replace(/[^\w\-\s]+/g,"").trim().replace(/\s+/g,"-").replace(/\-\-+/g,"-")}}),angular.module("ngTasty.service.bindTo",[]).factory("bindTo",["$parse",function($parse){return function(scopeName,scope,attrs,newScopeName){var lastValue,parentGet,compare,parentSet,parentValueWatch,isolateScopeName;attrs[scopeName]&&(parentGet=$parse(attrs[scopeName]),compare=parentGet.literal?equals:function(a,b){return a===b||a!==a&&b!==b},isolateScopeName=newScopeName?newScopeName:scopeName,parentSet=parentGet.assign,lastValue=scope[isolateScopeName]=parentGet(scope.$parent),parentValueWatch=function(parentValue){return compare(parentValue,scope[isolateScopeName])||(compare(parentValue,lastValue)?parentSet(scope.$parent,parentValue=scope[isolateScopeName]):scope[isolateScopeName]=parentValue),lastValue=parentValue},parentValueWatch.$stateful=!0,scope.$parent.$watch($parse(attrs[scopeName],parentValueWatch),null,parentGet.literal))}}]),angular.module("ngTasty.service.debounce",[]).factory("debounce",["$timeout",function($timeout){return function(func,wait,immediate){var args,context,debounceTimeout,timeout,debounceTimeout=function(){timeout=null,immediate||func.apply(context,args)};return function(){context=this,args=arguments;var callNow=immediate&&!timeout;$timeout.cancel(timeout),timeout=$timeout(debounceTimeout,wait),callNow&&func.apply(context,args)}}}]),angular.module("ngTasty.service.joinObjects",["ngTasty.service.setProperty"]).factory("joinObjects",["setProperty",function(setProperty){return function(objOne,objTwo,listKeyNotJoin){listKeyNotJoin=listKeyNotJoin||[];for(var attrname in objTwo)listKeyNotJoin.indexOf(attrname)<0&&setProperty(objOne,objTwo,attrname);return objOne}}]),angular.module("ngTasty.service.setProperty",[]).factory("setProperty",function(){return function(objOne,objTwo,attrname){return"undefined"!=typeof objTwo[attrname]&&null!==objTwo[attrname]&&(objOne[attrname]=objTwo[attrname]),objOne}}),angular.module("ngTasty.service.tastyUtil",["ngTasty.service.bindTo","ngTasty.service.debounce","ngTasty.service.setProperty","ngTasty.service.joinObjects","ngTasty.service.throttle","ngTasty.service.webSocket"]).factory("tastyUtil",["debounce","setProperty","joinObjects","bindTo","webSocket","throttle",function(debounce,setProperty,joinObjects,bindTo,webSocket,throttle){return{bindTo:bindTo,debounce:debounce,setProperty:setProperty,joinObjects:joinObjects,throttle:throttle,webSocket:webSocket}}]),angular.module("ngTasty.service.throttle",[]).factory("throttle",["$timeout",function($timeout){return function(fn,threshhold,scope){threshhold||(threshhold=250);var last,promise;return function(){var context=scope||this,now=+new Date,args=arguments;last&&last+threshhold>now?($timeout.cancel(promise),promise=$timeout(function(){last=now,fn.apply(context,args)},threshhold)):(last=now,fn.apply(context,args))}}}]),angular.module("ngTasty.service.webSocket",[]).factory("webSocket",function(){return function(url){var blobURL=URL.createObjectURL(new Blob(["(",function(){var WSWorker=function(){var _ws,initialize=function(url){_ws=new WebSocket(url)},on=function(){_ws.onmessage=function(response){var data=JSON.parse(response.data);self.postMessage(data)}},send=function(data){_ws.send(data)};return{initialize:initialize,on:on,send:send}}();self.addEventListener("message",function(e){switch(e.data.cmd){case"ws_new":WSWorker.initialize(e.data.url);break;case"ws_on":WSWorker.on();break;case"ws_send":WSWorker.send(JSON.stringify(e.data.data));break;default:console.log("Unknown command: "+e.data.cmd)}})}.toString(),")()"],{type:"application/javascript"})),_worker=new Worker(blobURL);return URL.revokeObjectURL(blobURL),_worker.postMessage({cmd:"ws_new",url:url}),{on:function(event,cb){_worker.postMessage({cmd:"ws_on"}),_worker.addEventListener("message",function(e){("all"===event||e.data.type===event)&&cb(e.data)})},send:function(data){_worker.postMessage({cmd:"ws_send",data:data})}}}}),function(module){try{module=angular.module("ngTasty.tpls.table.head")}catch(e){module=angular.module("ngTasty.tpls.table.head",[])}module.run(["$templateCache",function($templateCache){$templateCache.put("template/table/head.html",'<tr>\n <th ng-repeat="column in columns track by $index" \n ng-class="classToShow(column)"\n ng-style="::column.style" ng-click="sortBy(column)">\n <span ng-bind="::column.name"></span>\n <span ng-class="column.isSorted">\n <span ng-class="column.isSortedCaret" ng-if="::bootstrapIcon"></span>\n </span>\n </th> \n</tr>')}])}(),function(module){try{module=angular.module("ngTasty.tpls.table.pagination")}catch(e){module=angular.module("ngTasty.tpls.table.pagination",[])}module.run(["$templateCache",function($templateCache){$templateCache.put("template/table/pagination.html",'<div class="row">\n <div class="col-xs-3 text-left">\n <div class="btn-group">\n <button type="button" class="btn btn-default" \n ng-repeat="count in listItemsPerPageShow" \n ng-class="classPaginationCount(count)" \n ng-click="page.setCount(count)" ng-bind="count"></button>\n </div>\n </div>\n <div class="col-xs-6 text-center">\n <ul class="pagination">\n <li ng-class="classPageMinRange">\n <a href ng-click="page.previous()">&laquo;</a>\n </li>\n <li ng-repeat="numPage in rangePage" ng-class="classNumPage(numPage)">\n <a href ng-click="page.get(numPage)">\n <span ng-bind="numPage"></span>\n <span class="sr-only" ng-if="classNumPage(numPage)">(current)</span>\n </a>\n </li>\n <li ng-class="classPageMaxRange">\n <a href ng-click="page.remaining()">&raquo;</a>\n </li>\n </ul>\n </div>\n <div class="col-xs-3 text-right">\n <p>Page <span ng-bind="pagination.page"></span> \n of <span ng-bind="pagination.pages"></span>,\n of <span ng-bind="pagination.size"></span> entries</p>\n </div>\n</div>')}])}();

@@ -5,6 +5,6 @@ /*

* Version: 0.4.4 - 2014-12-27
* Version: 0.4.5 - 2015-01-19
* License: MIT
*/
angular.module("ngTasty", ["ngTasty.component.table","ngTasty.filter.cleanFieldName","ngTasty.filter.filterInt","ngTasty.filter.range","ngTasty.service.bindTo","ngTasty.service.debounce","ngTasty.service.joinObjects","ngTasty.service.setProperty","ngTasty.service.tastyUtil","ngTasty.service.throttle","ngTasty.service.webSocket"]);
angular.module("ngTasty", ["ngTasty.component.table","ngTasty.filter.camelize","ngTasty.filter.cleanFieldName","ngTasty.filter.filterInt","ngTasty.filter.range","ngTasty.filter.slugify","ngTasty.service.bindTo","ngTasty.service.debounce","ngTasty.service.joinObjects","ngTasty.service.setProperty","ngTasty.service.tastyUtil","ngTasty.service.throttle","ngTasty.service.webSocket"]);
/**

@@ -46,3 +46,4 @@ * @ngdoc directive

listItemsPerPage: [5, 25, 50, 100],
itemsPerPage: 5
itemsPerPage: 5,
watchResource: 'reference'
})

@@ -58,5 +59,8 @@ .controller('TableController', ["$scope", "$attrs", "$filter", "tableConfig", "tastyUtil", function($scope, $attrs, $filter, tableConfig, tastyUtil) {

$scope.query = {};
$scope.logs = {
'buildClientResourceCount': 0
};
listScopeToWatch = ['bindFilters', 'bindInit', 'bindQuery', 'bindResource',
'bindResourceCallback'];
'bindResourceCallback', 'bindWatchResource'];
listScopeToWatch.forEach(function (scopeName) {

@@ -79,2 +83,3 @@ newScopeName = scopeName.substring(4);

$scope.init.sortOrder = $scope.init.sortOrder || tableConfig.init.sortOrder;
$scope.watchResource = $scope.watchResource || tableConfig.watchResource;

@@ -120,3 +125,3 @@ // Defualt variables

throw 'AngularJS tastyTable directive: the bind-resource ('+
$attrs.bindResource + ') it\'s not an object';
$attrs.bindResource + ') is not an object';
} else if (!$scope.resource.header && !$scope.resource.rows) {

@@ -130,3 +135,3 @@ throw 'AngularJS tastyTable directive: the bind-resource ('+

throw 'AngularJS tastyTable directive: the bind-resource-callback ('+
$attrs.bindResourceCallback + ') it\'s not a function';
$attrs.bindResourceCallback + ') is not a function';
}

@@ -154,13 +159,13 @@ $scope.clientSide = false;

initStatus[keyDirective] = true;
if (!$scope.theadDirective && !$scope.paginationDirective) {
if (!$scope.theadDirective && !$scope.paginationDirective) { // None of them
this.start = true;
} else if ($scope.theadDirective && $scope.paginationDirective) {
} else if ($scope.theadDirective && $scope.paginationDirective) { // Both directives
if (initStatus.thead && initStatus.pagination){
this.start = true;
}
} else if ($scope.theadDirective && !$scope.paginationDirective) {
} else if ($scope.theadDirective && !$scope.paginationDirective) { // Only Thead directive
if (initStatus.thead){
this.start = true;
}
} else if (!$scope.theadDirective && $scope.paginationDirective) {
} else if (!$scope.theadDirective && $scope.paginationDirective) { // Only Pagination directive
if (initStatus.pagination){

@@ -192,7 +197,6 @@ this.start = true;

setDirectivesValues = function (resource) {
if (!angular.isObject(resource)) {
throw 'AngularJS tastyTable directive: the bind-resource '+
'it\'s not an object';
if (!$scope.resource && !angular.isObject(resource)) {
throw 'AngularJS tastyTable directive: the resource response is not an object';
} else if (!resource.header && !resource.rows) {
throw 'AngularJS tastyTable directive: the bind-resource '+
throw 'AngularJS tastyTable directive: the resource response object '+
'has the property header or rows undefined';

@@ -247,2 +251,3 @@ }

var fromRow, toRow, rowToShow, reverse, listSortBy;
$scope.logs.buildClientResourceCount += 1;
if ($scope.theadDirective && $scope.header.columns.length) {

@@ -341,3 +346,3 @@ reverse = $scope.header.sortOrder === 'asc' ? false : true;

if ($scope.resource) {
$scope.$watch('resource', function watchResource (newValue, oldValue){
var watchResource = function (newValue, oldValue){
if (newValue !== oldValue) {

@@ -347,4 +352,29 @@ $scope.params.sortBy = newValue.sortBy;

$scope.$evalAsync(updateClientSideResource('resource'));
if (!$scope.resource.reload) {
$scope.resource.reload = function () {
$scope.$evalAsync(updateClientSideResource('resource'));
};
}
}
}, true);
};
if ($scope.watchResource === 'reference') {
$scope.$watch('resource', watchResource);
} else if ($scope.watchResource === 'collection') {
$scope.$watchCollection('resource.header', watchResource);
$scope.$watchCollection('resource.rows', watchResource);
$scope.$watchGroup(['sortBy',
'sortOrder',
'pagination.count',
'pagination.page',
'pagination.pages',
'pagination.size'], watchResource);
} else if ($scope.watchResource === 'equality') {
$scope.$watch('resource', function (newValue, oldValue){
if (newValue !== oldValue) {
$scope.params.sortBy = newValue.sortBy;
$scope.params.sortOrder = newValue.sortOrder;
$scope.$evalAsync(updateClientSideResource('resource'));
}
}, true);
}
}

@@ -413,6 +443,5 @@ }])

scope.setColumns = function () {
var lenHeader, width, i, active, sortable, sort,
var width, i, active, sortable, sort,
isSorted, isSortedCaret;
scope.columns = [];
lenHeader = scope.header.columns.length;
scope.header.columns.forEach(function (column, index) {

@@ -678,3 +707,36 @@ column.style = column.style || {};

* @ngdoc filter
* @name filterCamelize
* @function
*
*/
angular.module('ngTasty.filter.camelize', [])
.filter('camelize', function() {
var CAMELIZE_REGEX = /(?:^|[-_ ])(\w)/g;
return function (input, first) {
var isString = typeof input === 'string',
first = typeof first === 'undefined' ? false : !!first;
if(typeof input === 'undefined' ||
input === null ||
(!isString && isNaN(input)) ) {
return '';
}
if(!isString){
return '' + input;
}
return input.trim() //remove trailing spaces
.replace(/ +(?= )/g,'') //remove multiple WS
.replace(CAMELIZE_REGEX, function (_, character, pos) { //actual conversion
return character && (first || pos > 0) ? character.toUpperCase () : character;
});
};
});
/**
* @ngdoc filter
* @name cleanFieldName
* @function
*

@@ -698,3 +760,3 @@ * @description

* @name filterInt
* @kind function
* @function
*

@@ -715,3 +777,3 @@ */

* @name range
* @kind function
* @function
*

@@ -753,2 +815,54 @@ * @description

/**
* @author https://github.com/bogdan-alexandrescu/ - @balx
* @ngdoc filter
* @name ngTasty.filter.slugify
* @function
*
* @description
* Transform text into an ascii slug by replacing whitespaces, accentuated,
* and special characters with the coresponding latin character or completely
* removing them when no latin equivalent is found. This can be used safely to
* generate valid URLs.
*/
angular.module('ngTasty.filter.slugify', [])
.filter('slugify', function () {
var makeString = function (object) {
if (object == null) {
return '';
}
return '' + object;
};
var defaultToWhiteSpace = function (characters) {
if (characters == null) {
return '\\s';
} else if (characters.source) {
return characters.source;
} else {
return '[' + characters.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1') + ']';
}
};
var from = "ąàáäâãåæăćčĉęèéëêĝĥìíïîĵłľńňòóöőôõðøśșšŝťțŭùúüűûñÿýçżźž",
to = "aaaaaaaaaccceeeeeghiiiijllnnoooooooossssttuuuuuunyyczzz",
regex = new RegExp(defaultToWhiteSpace(from), 'g');
return function (str) {
str = makeString(str)
.toString() //make sure is a string
.toLowerCase()
.replace(regex, function (c){
var index = from.indexOf(c);
return to.charAt(index) || '-';
}) //normalize some foreign characters
.replace(/[^\w\-\s]+/g, '') //remove unwanted characters
.trim() //trim spaces
.replace(/\s+/g, '-') //replace any space with a dash
.replace(/\-\-+/g, '-'); //remove duplicate dashes
return str;
};
});
/**
* @ngdoc service

@@ -805,12 +919,20 @@ * @name ngTasty.service.bindTo

angular.module('ngTasty.service.debounce', [])
.factory('debounce', ["$timeout", function($timeout) {
.factory('debounce', ["$timeout", function ($timeout) {
return function (func, wait, immediate) {
var timeout;
var args, context, debounceTimeout, timeout;
var debounceTimeout = function() {
timeout = null;
if (!immediate) {
func.apply(context, args);
}
};
return function debounce () {
var context = this, args = arguments;
context = this;
args = arguments;
var callNow = immediate && !timeout;
$timeout.cancel(timeout);
timeout = $timeout(function debounceTimeout () {
timeout = null;
timeout = $timeout(debounceTimeout, wait);
if (callNow) {
func.apply(context, args);
}, wait);
}
};

@@ -894,3 +1016,3 @@ };

var last, promise;
return function () {
return function throttle () {
var context = scope || this;

@@ -902,3 +1024,3 @@ var now = +new Date,

$timeout.cancel(promise);
promise = $timeout(function () {
promise = $timeout(function throttleTimeout () {
last = now;

@@ -925,2 +1047,11 @@ fn.apply(context, args);

return function(url) {
/**
* Creates a String[1] representing a binary blob[2] function
* containing the WebSocket Factory API.
*
* [1]: https://developer.mozilla.org/en-US/docs/Web/API/URL.createObjectURL
* [2]: https://developer.mozilla.org/en-US/docs/Web/API/Blob
*
* @return {string} String containing the encoded script
*/
var blobURL = URL.createObjectURL(new Blob(['(', function() {

@@ -930,2 +1061,8 @@ var WSWorker = (function() {

/**
* Initialize a new WebSocket using
* the provided URL parameters.
*
* @param {string} url The WebSocket URL
*/
var initialize = function(url) {

@@ -935,3 +1072,10 @@ _ws = new WebSocket(url);

var on = function(event) {
/**
* Listens for any message coming from the WebSocket
* and send its content to the main JS thread using postMessage[1].
*
* [1]: https://developer.mozilla.org/en-US/docs/Web/API/Worker.postMessage
*
*/
var on = function() {
_ws.onmessage = function(response) {

@@ -943,2 +1087,7 @@ var data = JSON.parse(response.data);

/**
* Sends data to the WebSocket.
*
* @param {string} data
*/
var send = function(data) {

@@ -956,2 +1105,14 @@ _ws.send(data);

/**
* Listens for incoming messages from the main
* JavaScript Thread.
*
* The commands allowed are:
*
* ws_new ~> Calls initialize on the Web Socket Worker
* ws_on ~> Register the supplied callback
* ws_send ~> Sends a message to the underlying WebSocket
* encoding it as a string (JSON.stringify)
*
*/
self.addEventListener('message', function(e) {

@@ -963,3 +1124,3 @@ switch (e.data.cmd) {

case 'ws_on':
WSWorker.on(e.data.event, e.data.cb);
WSWorker.on();
break;

@@ -975,9 +1136,38 @@ case 'ws_send':

}.toString(), ')()'], { type: 'application/javascript' }));
// Create a new WebSocket Worker, revoke the URL since
// it's not useful anymore.
var _worker = new Worker(blobURL);
URL.revokeObjectURL(blobURL);
// Tell the WebSocket Worker to init a new WebSocket
_worker.postMessage({ cmd: 'ws_new', url: url });
return {
/**
* Registers a callback to a specific Worker event listener.
* There are two different events:
*
* - 'all' ~> subscribes to all websocket messages
* - 'type'~> subscribes to all websocket messages containing
* a field named 'type'.
*
* For example, WebSockets Server events like this one:
*
* {
* 'type': 'tweet',
* 'data': ...
* }
*
* can be handled in the following way:
*
* ws.on('twitter', function(data) {
* ...
* });
*
* @param {string} event The event name
* @param {Function} cb Callback with output data (first param)
*/
on: function(event, cb) {

@@ -991,2 +1181,7 @@ _worker.postMessage({ cmd: 'ws_on' });

},
/**
* Sends data to the WebSocket.
*
* @param {Any} data
*/
send: function(data) {

@@ -993,0 +1188,0 @@ _worker.postMessage({ cmd: 'ws_send', data: data });

@@ -5,5 +5,5 @@ /*

* Version: 0.4.4 - 2014-12-27
* Version: 0.4.5 - 2015-01-19
* License: MIT
*/
angular.module("ngTasty",["ngTasty.component.table","ngTasty.filter.cleanFieldName","ngTasty.filter.filterInt","ngTasty.filter.range","ngTasty.service.bindTo","ngTasty.service.debounce","ngTasty.service.joinObjects","ngTasty.service.setProperty","ngTasty.service.tastyUtil","ngTasty.service.throttle","ngTasty.service.webSocket"]),angular.module("ngTasty.component.table",["ngTasty.filter.cleanFieldName","ngTasty.filter.range","ngTasty.service.tastyUtil","ngTasty.tpls.table.head","ngTasty.tpls.table.pagination"]).constant("tableConfig",{init:{count:5,page:1,sortBy:void 0,sortOrder:void 0},query:{page:"page",count:"count",sortBy:"sort-by",sortOrder:"sort-order"},bindOnce:!0,iconUp:"fa fa-sort-up",iconDown:"fa fa-sort-down",bootstrapIcon:!1,templateUrl:"template/table/pagination.html",listItemsPerPage:[5,25,50,100],itemsPerPage:5}).controller("TableController",["$scope","$attrs","$filter","tableConfig","tastyUtil",function($scope,$attrs,$filter,tableConfig,tastyUtil){"use strict";var listScopeToWatch,newScopeName,initStatus,updateClientSideResource,updateServerSideResource,setDirectivesValues,buildClientResource,buildUrl;this.$scope=$scope,initStatus={},$scope.init={},$scope.query={},listScopeToWatch=["bindFilters","bindInit","bindQuery","bindResource","bindResourceCallback"],listScopeToWatch.forEach(function(scopeName){newScopeName=scopeName.substring(4),newScopeName=newScopeName.charAt(0).toLowerCase()+newScopeName.slice(1),$attrs[scopeName]&&tastyUtil.bindTo(scopeName,$scope,$attrs,newScopeName)}),$scope.query.page=$scope.query.page||tableConfig.query.page,$scope.query.count=$scope.query.count||tableConfig.query.count,$scope.query.sortBy=$scope.query.sortBy||tableConfig.query.sortBy,$scope.query.sortOrder=$scope.query.sortOrder||tableConfig.query.sortOrder,$scope.init.count=$scope.init.count||tableConfig.init.count,$scope.init.page=$scope.init.page||tableConfig.init.page,$scope.init.sortBy=$scope.init.sortBy||tableConfig.init.sortBy,$scope.init.sortOrder=$scope.init.sortOrder||tableConfig.init.sortOrder;var listImmutableKey=["filters","init","query","rows","header","pagination","params","sortOrder","sortBy","url"];if($scope.clientSide=!0,$scope.url="",$scope.header={columns:[]},$scope.rows=[],$scope.params={},$scope.pagination={count:$scope.init.count,page:$scope.init.page,pages:1,size:0},$scope.theadDirective=!1,$scope.paginationDirective=!1,!angular.isDefined($attrs.bindResource)&&!angular.isDefined($attrs.bindResourceCallback))throw"AngularJS tastyTable directive: need the bind-resource or bind-resource-callback attribute";if(angular.isDefined($attrs.bindResource)){if(!angular.isObject($scope.resource))throw"AngularJS tastyTable directive: the bind-resource ("+$attrs.bindResource+") it's not an object";if(!$scope.resource.header&&!$scope.resource.rows)throw"AngularJS tastyTable directive: the bind-resource ("+$attrs.bindResource+") has the property header or rows undefined"}if(angular.isDefined($attrs.bindResourceCallback)){if(!angular.isFunction($scope.resourceCallback))throw"AngularJS tastyTable directive: the bind-resource-callback ("+$attrs.bindResourceCallback+") it's not a function";$scope.clientSide=!1}this.start=!1,this.activate=function(directiveName){$scope[directiveName+"Directive"]=!0,$scope.params[directiveName]=!0},this.setParams=function(key,value){$scope.params[key]=value,["sortBy","sortOrder"].indexOf(key)>=0&&($scope.header[key]=value)},this.initTable=function(keyDirective){initStatus[keyDirective]=!0,$scope.theadDirective||$scope.paginationDirective?$scope.theadDirective&&$scope.paginationDirective?initStatus.thead&&initStatus.pagination&&(this.start=!0):$scope.theadDirective&&!$scope.paginationDirective?initStatus.thead&&(this.start=!0):!$scope.theadDirective&&$scope.paginationDirective&&initStatus.pagination&&(this.start=!0):this.start=!0,this.start&&($scope.clientSide?($scope.params.sortBy=$scope.resource.sortBy||$scope.init.sortBy,$scope.params.sortOrder=$scope.resource.sortOrder||$scope.init.sortOrder,$scope.params.page=$scope.init.page,$scope.resource.pagination&&($scope.params.page=$scope.resource.pagination.page||$scope.init.page),$scope.$evalAsync(updateClientSideResource)):($scope.params.sortBy=$scope.init.sortBy,$scope.params.sortOrder=$scope.init.sortOrder,$scope.params.page=$scope.init.page,$scope.$evalAsync(updateServerSideResource)))},this.bindOnce=tableConfig.bindOnce,setDirectivesValues=function(resource){if(!angular.isObject(resource))throw"AngularJS tastyTable directive: the bind-resource it's not an object";if(!resource.header&&!resource.rows)throw"AngularJS tastyTable directive: the bind-resource has the property header or rows undefined";Object.keys(resource).forEach(function(key){listImmutableKey.indexOf(key)<0&&($scope[key]=resource[key])}),resource.header.length&&1===Object.keys(resource.header[0]).length&&(resource.header=resource.header.map(function(header){var key=Object.keys(header)[0];return{key:key,name:header[key]}})),$scope.header={columns:resource.header,sortBy:$scope.params.sortBy,sortOrder:$scope.params.sortOrder},$scope.clientSide||($scope.header.sortBy=$scope.header.sortBy||resource.sortBy,$scope.header.sortOrder=$scope.header.sortOrder||resource.sortOrder),$scope.rows=resource.rows,$scope.paginationDirective&&($scope.pagination.page=$scope.params.page,$scope.pagination.count=$scope.params.count,$scope.pagination.size=$scope.rows.length,resource.pagination&&(resource.pagination.count&&($scope.pagination.count=resource.pagination.count),resource.pagination.page&&($scope.pagination.page=resource.pagination.page),resource.pagination.size&&($scope.pagination.size=resource.pagination.size)),$scope.pagination.pages=Math.ceil($scope.pagination.size/$scope.pagination.count))},buildClientResource=function(updateFrom){var fromRow,toRow,rowToShow,reverse,listSortBy;$scope.theadDirective&&$scope.header.columns.length&&(reverse="asc"===$scope.header.sortOrder?!1:!0,listSortBy=[function(item){return item[$scope.header.sortBy]}],$scope.header.columns[0].key!==$scope.header.sortBy&&listSortBy.push(function(item){return item[$scope.header.columns[0].key]}),$scope.header.sortBy&&($scope.rows=$filter("orderBy")($scope.rows,listSortBy,reverse))),$attrs.bindFilters&&($scope.rows=$filter("filter")($scope.rows,$scope.filters)),$scope.paginationDirective&&($scope.pagination.page="filters"===updateFrom?1:$scope.params.page,$scope.pagination.count=$scope.params.count,$scope.pagination.size=$scope.rows.length,$scope.pagination.pages=Math.ceil($scope.rows.length/$scope.pagination.count),toRow=$scope.pagination.count*$scope.pagination.page,fromRow=toRow-$scope.pagination.count,fromRow>=0&&toRow>=0&&(rowToShow=$scope.rows.slice(fromRow,toRow),$scope.rows=rowToShow))},buildUrl=function(params,filters){var urlQuery,value,listKeyNotJoin;return urlQuery={},listKeyNotJoin=["sortBy","sortOrder","page","count"],$scope.theadDirective&&(urlQuery=tastyUtil.setProperty(urlQuery,params,"sortBy"),urlQuery=tastyUtil.setProperty(urlQuery,params,"sortOrder")),$scope.paginationDirective&&(urlQuery=tastyUtil.setProperty(urlQuery,params,"page"),urlQuery=tastyUtil.setProperty(urlQuery,params,"count")),$attrs.bindFilters&&(urlQuery=tastyUtil.joinObjects(urlQuery,filters,listKeyNotJoin)),Object.keys(urlQuery).map(function(key){return value=urlQuery[key],$scope.query[key]&&(key=$scope.query[key]),encodeURIComponent(key)+"="+encodeURIComponent(value)}).join("&")},updateClientSideResource=function(updateFrom){setDirectivesValues($scope.resource),buildClientResource(updateFrom)},updateServerSideResource=function(){$scope.url=buildUrl($scope.params,$scope.filters),$scope.resourceCallback($scope.url,angular.copy($scope.params)).then(function(resource){setDirectivesValues(resource)})},$attrs.bindFilters&&$scope.$watch("filters",function(newValue,oldValue){newValue!==oldValue&&($scope.clientSide?$scope.$evalAsync(updateClientSideResource("filters")):$scope.$evalAsync(updateServerSideResource))},!0),$scope.$watchCollection("params",function(newValue,oldValue){newValue!==oldValue&&($scope.clientSide?$scope.$evalAsync(updateClientSideResource("params")):$scope.$evalAsync(updateServerSideResource))}),$scope.resource&&$scope.$watch("resource",function(newValue,oldValue){newValue!==oldValue&&($scope.params.sortBy=newValue.sortBy,$scope.params.sortOrder=newValue.sortOrder,$scope.$evalAsync(updateClientSideResource("resource")))},!0)}]).directive("tastyTable",function(){return{restrict:"A",scope:!0,controller:"TableController",link:function(scope,element,attrs,tastyTable){(element.find("tasty-thead").length||element[0].querySelector("[tasty-thead]"))&&tastyTable.activate("thead"),(element.find("tasty-pagination").length||element[0].querySelector("[tasty-pagination]"))&&tastyTable.activate("pagination"),tastyTable.initTable()}}}).directive("tastyThead",["$filter","tableConfig","tastyUtil",function($filter,tableConfig,tastyUtil){return{restrict:"AE",require:"^tastyTable",scope:{},templateUrl:"template/table/head.html",link:function(scope,element,attrs,tastyTable){"use strict";var newScopeName,listScopeToWatch;scope.bindOnce=tastyTable.bindOnce,scope.columns=[],scope.bootstrapIcon=tableConfig.bootstrapIcon,scope.iconUp=tableConfig.iconUp,scope.iconDown=tableConfig.iconDown,listScopeToWatch=["bindNotSortBy","bindBootstrapIcon","bindIconUp","bindIconDown"],listScopeToWatch.forEach(function(scopeName){newScopeName=scopeName.substring(4),newScopeName=newScopeName.charAt(0).toLowerCase()+newScopeName.slice(1),attrs[scopeName]?tastyUtil.bindTo(scopeName,scope,attrs,newScopeName):attrs[newScopeName]&&(scope[newScopeName]="["===attrs[newScopeName][0]?JSON.parse(attrs[newScopeName]):attrs[newScopeName])}),scope.setColumns=function(){var lenHeader,active,sortable,sort,isSorted,isSortedCaret;scope.columns=[],lenHeader=scope.header.columns.length,scope.header.columns.forEach(function(column){column.style=column.style||{},sortable=!0,active=!1,isSorted="",isSortedCaret="",angular.isArray(scope.notSortBy)&&(sortable=scope.notSortBy.length?scope.notSortBy.indexOf(column.key)<0:!1),(column.key===scope.header.sortBy||"-"+column.key===scope.header.sortBy)&&(active=!0),sort=$filter("cleanFieldName")(column.key),scope.header.sortBy==="-"+sort?tableConfig.bootstrapIcon?(isSorted="",isSortedCaret="caret"):isSorted=scope.iconDown:scope.header.sortBy===sort&&(tableConfig.bootstrapIcon?(isSorted="dropup",isSortedCaret="caret"):isSorted=scope.iconUp),scope.columns.push({key:column.key,name:column.name,active:active,sortable:sortable,style:column.style,isSorted:isSorted,isSortedCaret:isSortedCaret})}),"dsc"===scope.header.sortOrder&&scope.header.sortBy&&"-"!==scope.header.sortBy[0]&&(scope.header.sortBy="-"+scope.header.sortBy),tastyTable.start||tastyTable.initTable("thead")},scope.sortBy=function(column){if(!column.sortable)return!1;var columnName,sortOrder;columnName=$filter("cleanFieldName")(column.key),sortOrder=scope.header.sortBy===columnName?"dsc":"asc",tastyTable.setParams("sortBy",column.key),tastyTable.setParams("sortOrder",sortOrder)},scope.classToShow=function(column){var listClassToShow=[];return column.sortable&&listClassToShow.push("sortable"),column.active&&listClassToShow.push("active"),listClassToShow},tastyTable.$scope.$watchCollection("header",function(newValue,oldValue){!newValue||newValue===oldValue&&tastyTable.start||(scope.header=newValue,scope.setColumns())})}}}]).directive("tastyPagination",["$filter","$templateCache","$http","$compile","tableConfig","tastyUtil",function($filter,$templateCache,$http,$compile,tableConfig,tastyUtil){return{restrict:"AE",require:"^tastyTable",scope:{},templateUrl:function(tElement,tAttrs){return tAttrs.templateUrl||tableConfig.templateUrl},link:function(scope,element,attrs,tastyTable){"use strict";var getPage,setCount,setPaginationRange,setPreviousRange,setRemainingRange,setPaginationRanges,listScopeToWatch,newScopeName;listScopeToWatch=["bindItemsPerPage","bindListItemsPerPage","bindTemplateUrl"],listScopeToWatch.forEach(function(scopeName){newScopeName=scopeName.substring(4),newScopeName=newScopeName.charAt(0).toLowerCase()+newScopeName.slice(1),attrs[scopeName]?tastyUtil.bindTo(scopeName,scope,attrs,newScopeName):attrs[newScopeName]&&(scope[newScopeName]="itemsPerPage"===newScopeName?parseInt(attrs[newScopeName]):JSON.parse(attrs[newScopeName]))}),scope.templateUrl&&$http.get(scope.templateUrl,{cache:$templateCache}).success(function(templateContent){element.replaceWith($compile(templateContent)(scope))}),scope.itemsPerPage=scope.itemsPerPage||tableConfig.itemsPerPage,scope.listItemsPerPage=scope.listItemsPerPage||tableConfig.listItemsPerPage,scope.pagination={},scope.pagMinRange=1,scope.pagMaxRange=1,getPage=function(numPage){tastyTable.setParams("page",numPage)},setCount=function(count){var maxItems,page;maxItems=count*scope.pagination.page,maxItems>scope.pagination.size&&(page=Math.ceil(scope.pagination.size/count),tastyTable.setParams("page",page)),tastyTable.setParams("count",count)},setPaginationRange=function(){var currentPage;currentPage=scope.pagination.page,currentPage>scope.pagination.pages&&(currentPage=scope.pagination.pages),scope.pagMinRange=currentPage-2>0?currentPage-2:1,scope.pagMaxRange=currentPage+2,scope.pagination.page=currentPage,setPaginationRanges()},setPreviousRange=function(){return scope.pagHideMinRange===!0||scope.pagMinRange<1?!1:(scope.pagMaxRange=scope.pagMinRange,scope.pagMinRange=scope.pagMaxRange-scope.itemsPerPage,setPaginationRanges(),void 0)},setRemainingRange=function(){return scope.pagHideMaxRange===!0||scope.pagMaxRange>scope.pagination.pages?!1:(scope.pagMinRange=scope.pagMaxRange,scope.pagMaxRange=scope.pagMinRange+scope.itemsPerPage,scope.pagMaxRange>scope.pagination.pages&&(scope.pagMaxRange=scope.pagination.pages),scope.pagMinRange=scope.pagMaxRange-scope.itemsPerPage,setPaginationRanges(),void 0)},setPaginationRanges=function(){scope.listItemsPerPageShow=[],scope.pagMinRange=scope.pagMinRange>0?scope.pagMinRange:1,scope.pagMaxRange=scope.pagMinRange+5,scope.pagMaxRange>scope.pagination.pages&&(scope.pagMaxRange=scope.pagination.pages+1),scope.pagHideMinRange=scope.pagMinRange<=1,scope.pagHideMaxRange=scope.pagMaxRange>=scope.pagination.pages,scope.classPageMinRange=scope.pagHideMinRange?"disabled":"",scope.classPageMaxRange=scope.pagHideMaxRange?"disabled":"";for(var i=scope.listItemsPerPage.length;i>=0;i--)if(scope.pagination.size>scope.listItemsPerPage[i]){scope.listItemsPerPageShow=scope.listItemsPerPage.slice(0,i+1);break}scope.rangePage=$filter("range")([],scope.pagMinRange,scope.pagMaxRange),tastyTable.start||tastyTable.initTable("pagination")},scope.classPaginationCount=function(count){return count==scope.pagination.count?"active":""},scope.classNumPage=function(numPage){return numPage==scope.pagination.page?"active":!1},scope.page={get:getPage,setCount:setCount,previous:setPreviousRange,remaining:setRemainingRange},tastyTable.$scope.$watchCollection("pagination",function(newValue,oldValue){!newValue||newValue===oldValue&&tastyTable.start||(scope.pagination=newValue,setPaginationRange())}),scope.page.setCount(scope.itemsPerPage)}}}]),angular.module("ngTasty.filter.cleanFieldName",[]).filter("cleanFieldName",function(){return function(input){return input.replace(/[^a-zA-Z0-9-]+/g,"-")}}),angular.module("ngTasty.filter.filterInt",[]).filter("filterInt",function(){return function(input){return/^(\-|\+)?([0-9]+|Infinity)$/.test(input)?Number(input):0/0}}),angular.module("ngTasty.filter.range",["ngTasty.filter.filterInt"]).filter("range",["$filter",function($filter){return function(input,start,stop,step){if(start=$filter("filterInt")(start),stop=$filter("filterInt")(stop),step=$filter("filterInt")(step),isNaN(start)&&(start=0),isNaN(stop)&&(stop=start,start=0),isNaN(step)&&(step=1),step>0&&start>=stop||0>step&&stop>=start)return[];for(var i=start;step>0?stop>i:i>stop;i+=step)input.push(i);return input}}]),angular.module("ngTasty.service.bindTo",[]).factory("bindTo",["$parse",function($parse){return function(scopeName,scope,attrs,newScopeName){var lastValue,parentGet,compare,parentSet,parentValueWatch,isolateScopeName;attrs[scopeName]&&(parentGet=$parse(attrs[scopeName]),compare=parentGet.literal?equals:function(a,b){return a===b||a!==a&&b!==b},isolateScopeName=newScopeName?newScopeName:scopeName,parentSet=parentGet.assign,lastValue=scope[isolateScopeName]=parentGet(scope.$parent),parentValueWatch=function(parentValue){return compare(parentValue,scope[isolateScopeName])||(compare(parentValue,lastValue)?parentSet(scope.$parent,parentValue=scope[isolateScopeName]):scope[isolateScopeName]=parentValue),lastValue=parentValue},parentValueWatch.$stateful=!0,scope.$parent.$watch($parse(attrs[scopeName],parentValueWatch),null,parentGet.literal))}}]),angular.module("ngTasty.service.debounce",[]).factory("debounce",["$timeout",function($timeout){return function(func,wait){var timeout;return function(){var context=this,args=arguments;$timeout.cancel(timeout),timeout=$timeout(function(){timeout=null,func.apply(context,args)},wait)}}}]),angular.module("ngTasty.service.joinObjects",["ngTasty.service.setProperty"]).factory("joinObjects",["setProperty",function(setProperty){return function(objOne,objTwo,listKeyNotJoin){listKeyNotJoin=listKeyNotJoin||[];for(var attrname in objTwo)listKeyNotJoin.indexOf(attrname)<0&&setProperty(objOne,objTwo,attrname);return objOne}}]),angular.module("ngTasty.service.setProperty",[]).factory("setProperty",function(){return function(objOne,objTwo,attrname){return"undefined"!=typeof objTwo[attrname]&&null!==objTwo[attrname]&&(objOne[attrname]=objTwo[attrname]),objOne}}),angular.module("ngTasty.service.tastyUtil",["ngTasty.service.bindTo","ngTasty.service.debounce","ngTasty.service.setProperty","ngTasty.service.joinObjects","ngTasty.service.throttle","ngTasty.service.webSocket"]).factory("tastyUtil",["debounce","setProperty","joinObjects","bindTo","webSocket","throttle",function(debounce,setProperty,joinObjects,bindTo,webSocket,throttle){return{bindTo:bindTo,debounce:debounce,setProperty:setProperty,joinObjects:joinObjects,throttle:throttle,webSocket:webSocket}}]),angular.module("ngTasty.service.throttle",[]).factory("throttle",["$timeout",function($timeout){return function(fn,threshhold,scope){threshhold||(threshhold=250);var last,promise;return function(){var context=scope||this,now=+new Date,args=arguments;last&&last+threshhold>now?($timeout.cancel(promise),promise=$timeout(function(){last=now,fn.apply(context,args)},threshhold)):(last=now,fn.apply(context,args))}}}]),angular.module("ngTasty.service.webSocket",[]).factory("webSocket",function(){return function(url){var blobURL=URL.createObjectURL(new Blob(["(",function(){var WSWorker=function(){var _ws,initialize=function(url){_ws=new WebSocket(url)},on=function(){_ws.onmessage=function(response){var data=JSON.parse(response.data);self.postMessage(data)}},send=function(data){_ws.send(data)};return{initialize:initialize,on:on,send:send}}();self.addEventListener("message",function(e){switch(e.data.cmd){case"ws_new":WSWorker.initialize(e.data.url);break;case"ws_on":WSWorker.on(e.data.event,e.data.cb);break;case"ws_send":WSWorker.send(JSON.stringify(e.data.data));break;default:console.log("Unknown command: "+e.data.cmd)}})}.toString(),")()"],{type:"application/javascript"})),_worker=new Worker(blobURL);return URL.revokeObjectURL(blobURL),_worker.postMessage({cmd:"ws_new",url:url}),{on:function(event,cb){_worker.postMessage({cmd:"ws_on"}),_worker.addEventListener("message",function(e){("all"===event||e.data.type===event)&&cb(e.data)})},send:function(data){_worker.postMessage({cmd:"ws_send",data:data})}}}});
angular.module("ngTasty",["ngTasty.component.table","ngTasty.filter.camelize","ngTasty.filter.cleanFieldName","ngTasty.filter.filterInt","ngTasty.filter.range","ngTasty.filter.slugify","ngTasty.service.bindTo","ngTasty.service.debounce","ngTasty.service.joinObjects","ngTasty.service.setProperty","ngTasty.service.tastyUtil","ngTasty.service.throttle","ngTasty.service.webSocket"]),angular.module("ngTasty.component.table",["ngTasty.filter.cleanFieldName","ngTasty.filter.range","ngTasty.service.tastyUtil","ngTasty.tpls.table.head","ngTasty.tpls.table.pagination"]).constant("tableConfig",{init:{count:5,page:1,sortBy:void 0,sortOrder:void 0},query:{page:"page",count:"count",sortBy:"sort-by",sortOrder:"sort-order"},bindOnce:!0,iconUp:"fa fa-sort-up",iconDown:"fa fa-sort-down",bootstrapIcon:!1,templateUrl:"template/table/pagination.html",listItemsPerPage:[5,25,50,100],itemsPerPage:5,watchResource:"reference"}).controller("TableController",["$scope","$attrs","$filter","tableConfig","tastyUtil",function($scope,$attrs,$filter,tableConfig,tastyUtil){"use strict";var listScopeToWatch,newScopeName,initStatus,updateClientSideResource,updateServerSideResource,setDirectivesValues,buildClientResource,buildUrl;this.$scope=$scope,initStatus={},$scope.init={},$scope.query={},$scope.logs={buildClientResourceCount:0},listScopeToWatch=["bindFilters","bindInit","bindQuery","bindResource","bindResourceCallback","bindWatchResource"],listScopeToWatch.forEach(function(scopeName){newScopeName=scopeName.substring(4),newScopeName=newScopeName.charAt(0).toLowerCase()+newScopeName.slice(1),$attrs[scopeName]&&tastyUtil.bindTo(scopeName,$scope,$attrs,newScopeName)}),$scope.query.page=$scope.query.page||tableConfig.query.page,$scope.query.count=$scope.query.count||tableConfig.query.count,$scope.query.sortBy=$scope.query.sortBy||tableConfig.query.sortBy,$scope.query.sortOrder=$scope.query.sortOrder||tableConfig.query.sortOrder,$scope.init.count=$scope.init.count||tableConfig.init.count,$scope.init.page=$scope.init.page||tableConfig.init.page,$scope.init.sortBy=$scope.init.sortBy||tableConfig.init.sortBy,$scope.init.sortOrder=$scope.init.sortOrder||tableConfig.init.sortOrder,$scope.watchResource=$scope.watchResource||tableConfig.watchResource;var listImmutableKey=["filters","init","query","rows","header","pagination","params","sortOrder","sortBy","url"];if($scope.clientSide=!0,$scope.url="",$scope.header={columns:[]},$scope.rows=[],$scope.params={},$scope.pagination={count:$scope.init.count,page:$scope.init.page,pages:1,size:0},$scope.theadDirective=!1,$scope.paginationDirective=!1,!angular.isDefined($attrs.bindResource)&&!angular.isDefined($attrs.bindResourceCallback))throw"AngularJS tastyTable directive: need the bind-resource or bind-resource-callback attribute";if(angular.isDefined($attrs.bindResource)){if(!angular.isObject($scope.resource))throw"AngularJS tastyTable directive: the bind-resource ("+$attrs.bindResource+") is not an object";if(!$scope.resource.header&&!$scope.resource.rows)throw"AngularJS tastyTable directive: the bind-resource ("+$attrs.bindResource+") has the property header or rows undefined"}if(angular.isDefined($attrs.bindResourceCallback)){if(!angular.isFunction($scope.resourceCallback))throw"AngularJS tastyTable directive: the bind-resource-callback ("+$attrs.bindResourceCallback+") is not a function";$scope.clientSide=!1}if(this.start=!1,this.activate=function(directiveName){$scope[directiveName+"Directive"]=!0,$scope.params[directiveName]=!0},this.setParams=function(key,value){$scope.params[key]=value,["sortBy","sortOrder"].indexOf(key)>=0&&($scope.header[key]=value)},this.initTable=function(keyDirective){initStatus[keyDirective]=!0,$scope.theadDirective||$scope.paginationDirective?$scope.theadDirective&&$scope.paginationDirective?initStatus.thead&&initStatus.pagination&&(this.start=!0):$scope.theadDirective&&!$scope.paginationDirective?initStatus.thead&&(this.start=!0):!$scope.theadDirective&&$scope.paginationDirective&&initStatus.pagination&&(this.start=!0):this.start=!0,this.start&&($scope.clientSide?($scope.params.sortBy=$scope.resource.sortBy||$scope.init.sortBy,$scope.params.sortOrder=$scope.resource.sortOrder||$scope.init.sortOrder,$scope.params.page=$scope.init.page,$scope.resource.pagination&&($scope.params.page=$scope.resource.pagination.page||$scope.init.page),$scope.$evalAsync(updateClientSideResource)):($scope.params.sortBy=$scope.init.sortBy,$scope.params.sortOrder=$scope.init.sortOrder,$scope.params.page=$scope.init.page,$scope.$evalAsync(updateServerSideResource)))},this.bindOnce=tableConfig.bindOnce,setDirectivesValues=function(resource){if(!$scope.resource&&!angular.isObject(resource))throw"AngularJS tastyTable directive: the resource response is not an object";if(!resource.header&&!resource.rows)throw"AngularJS tastyTable directive: the resource response object has the property header or rows undefined";Object.keys(resource).forEach(function(key){listImmutableKey.indexOf(key)<0&&($scope[key]=resource[key])}),resource.header.length&&1===Object.keys(resource.header[0]).length&&(resource.header=resource.header.map(function(header){var key=Object.keys(header)[0];return{key:key,name:header[key]}})),$scope.header={columns:resource.header,sortBy:$scope.params.sortBy,sortOrder:$scope.params.sortOrder},$scope.clientSide||($scope.header.sortBy=$scope.header.sortBy||resource.sortBy,$scope.header.sortOrder=$scope.header.sortOrder||resource.sortOrder),$scope.rows=resource.rows,$scope.paginationDirective&&($scope.pagination.page=$scope.params.page,$scope.pagination.count=$scope.params.count,$scope.pagination.size=$scope.rows.length,resource.pagination&&(resource.pagination.count&&($scope.pagination.count=resource.pagination.count),resource.pagination.page&&($scope.pagination.page=resource.pagination.page),resource.pagination.size&&($scope.pagination.size=resource.pagination.size)),$scope.pagination.pages=Math.ceil($scope.pagination.size/$scope.pagination.count))},buildClientResource=function(updateFrom){var fromRow,toRow,rowToShow,reverse,listSortBy;$scope.logs.buildClientResourceCount+=1,$scope.theadDirective&&$scope.header.columns.length&&(reverse="asc"===$scope.header.sortOrder?!1:!0,listSortBy=[function(item){return item[$scope.header.sortBy]}],$scope.header.columns[0].key!==$scope.header.sortBy&&listSortBy.push(function(item){return item[$scope.header.columns[0].key]}),$scope.header.sortBy&&($scope.rows=$filter("orderBy")($scope.rows,listSortBy,reverse))),$attrs.bindFilters&&($scope.rows=$filter("filter")($scope.rows,$scope.filters)),$scope.paginationDirective&&($scope.pagination.page="filters"===updateFrom?1:$scope.params.page,$scope.pagination.count=$scope.params.count,$scope.pagination.size=$scope.rows.length,$scope.pagination.pages=Math.ceil($scope.rows.length/$scope.pagination.count),toRow=$scope.pagination.count*$scope.pagination.page,fromRow=toRow-$scope.pagination.count,fromRow>=0&&toRow>=0&&(rowToShow=$scope.rows.slice(fromRow,toRow),$scope.rows=rowToShow))},buildUrl=function(params,filters){var urlQuery,value,listKeyNotJoin;return urlQuery={},listKeyNotJoin=["sortBy","sortOrder","page","count"],$scope.theadDirective&&(urlQuery=tastyUtil.setProperty(urlQuery,params,"sortBy"),urlQuery=tastyUtil.setProperty(urlQuery,params,"sortOrder")),$scope.paginationDirective&&(urlQuery=tastyUtil.setProperty(urlQuery,params,"page"),urlQuery=tastyUtil.setProperty(urlQuery,params,"count")),$attrs.bindFilters&&(urlQuery=tastyUtil.joinObjects(urlQuery,filters,listKeyNotJoin)),Object.keys(urlQuery).map(function(key){return value=urlQuery[key],$scope.query[key]&&(key=$scope.query[key]),encodeURIComponent(key)+"="+encodeURIComponent(value)}).join("&")},updateClientSideResource=function(updateFrom){setDirectivesValues($scope.resource),buildClientResource(updateFrom)},updateServerSideResource=function(){$scope.url=buildUrl($scope.params,$scope.filters),$scope.resourceCallback($scope.url,angular.copy($scope.params)).then(function(resource){setDirectivesValues(resource)})},$attrs.bindFilters&&$scope.$watch("filters",function(newValue,oldValue){newValue!==oldValue&&($scope.clientSide?$scope.$evalAsync(updateClientSideResource("filters")):$scope.$evalAsync(updateServerSideResource))},!0),$scope.$watchCollection("params",function(newValue,oldValue){newValue!==oldValue&&($scope.clientSide?$scope.$evalAsync(updateClientSideResource("params")):$scope.$evalAsync(updateServerSideResource))}),$scope.resource){var watchResource=function(newValue,oldValue){newValue!==oldValue&&($scope.params.sortBy=newValue.sortBy,$scope.params.sortOrder=newValue.sortOrder,$scope.$evalAsync(updateClientSideResource("resource")),$scope.resource.reload||($scope.resource.reload=function(){$scope.$evalAsync(updateClientSideResource("resource"))}))};"reference"===$scope.watchResource?$scope.$watch("resource",watchResource):"collection"===$scope.watchResource?($scope.$watchCollection("resource.header",watchResource),$scope.$watchCollection("resource.rows",watchResource),$scope.$watchGroup(["sortBy","sortOrder","pagination.count","pagination.page","pagination.pages","pagination.size"],watchResource)):"equality"===$scope.watchResource&&$scope.$watch("resource",function(newValue,oldValue){newValue!==oldValue&&($scope.params.sortBy=newValue.sortBy,$scope.params.sortOrder=newValue.sortOrder,$scope.$evalAsync(updateClientSideResource("resource")))},!0)}}]).directive("tastyTable",function(){return{restrict:"A",scope:!0,controller:"TableController",link:function(scope,element,attrs,tastyTable){(element.find("tasty-thead").length||element[0].querySelector("[tasty-thead]"))&&tastyTable.activate("thead"),(element.find("tasty-pagination").length||element[0].querySelector("[tasty-pagination]"))&&tastyTable.activate("pagination"),tastyTable.initTable()}}}).directive("tastyThead",["$filter","tableConfig","tastyUtil",function($filter,tableConfig,tastyUtil){return{restrict:"AE",require:"^tastyTable",scope:{},templateUrl:"template/table/head.html",link:function(scope,element,attrs,tastyTable){"use strict";var newScopeName,listScopeToWatch;scope.bindOnce=tastyTable.bindOnce,scope.columns=[],scope.bootstrapIcon=tableConfig.bootstrapIcon,scope.iconUp=tableConfig.iconUp,scope.iconDown=tableConfig.iconDown,listScopeToWatch=["bindNotSortBy","bindBootstrapIcon","bindIconUp","bindIconDown"],listScopeToWatch.forEach(function(scopeName){newScopeName=scopeName.substring(4),newScopeName=newScopeName.charAt(0).toLowerCase()+newScopeName.slice(1),attrs[scopeName]?tastyUtil.bindTo(scopeName,scope,attrs,newScopeName):attrs[newScopeName]&&(scope[newScopeName]="["===attrs[newScopeName][0]?JSON.parse(attrs[newScopeName]):attrs[newScopeName])}),scope.setColumns=function(){var active,sortable,sort,isSorted,isSortedCaret;scope.columns=[],scope.header.columns.forEach(function(column){column.style=column.style||{},sortable=!0,active=!1,isSorted="",isSortedCaret="",angular.isArray(scope.notSortBy)&&(sortable=scope.notSortBy.length?scope.notSortBy.indexOf(column.key)<0:!1),(column.key===scope.header.sortBy||"-"+column.key===scope.header.sortBy)&&(active=!0),sort=$filter("cleanFieldName")(column.key),scope.header.sortBy==="-"+sort?tableConfig.bootstrapIcon?(isSorted="",isSortedCaret="caret"):isSorted=scope.iconDown:scope.header.sortBy===sort&&(tableConfig.bootstrapIcon?(isSorted="dropup",isSortedCaret="caret"):isSorted=scope.iconUp),scope.columns.push({key:column.key,name:column.name,active:active,sortable:sortable,style:column.style,isSorted:isSorted,isSortedCaret:isSortedCaret})}),"dsc"===scope.header.sortOrder&&scope.header.sortBy&&"-"!==scope.header.sortBy[0]&&(scope.header.sortBy="-"+scope.header.sortBy),tastyTable.start||tastyTable.initTable("thead")},scope.sortBy=function(column){if(!column.sortable)return!1;var columnName,sortOrder;columnName=$filter("cleanFieldName")(column.key),sortOrder=scope.header.sortBy===columnName?"dsc":"asc",tastyTable.setParams("sortBy",column.key),tastyTable.setParams("sortOrder",sortOrder)},scope.classToShow=function(column){var listClassToShow=[];return column.sortable&&listClassToShow.push("sortable"),column.active&&listClassToShow.push("active"),listClassToShow},tastyTable.$scope.$watchCollection("header",function(newValue,oldValue){!newValue||newValue===oldValue&&tastyTable.start||(scope.header=newValue,scope.setColumns())})}}}]).directive("tastyPagination",["$filter","$templateCache","$http","$compile","tableConfig","tastyUtil",function($filter,$templateCache,$http,$compile,tableConfig,tastyUtil){return{restrict:"AE",require:"^tastyTable",scope:{},templateUrl:function(tElement,tAttrs){return tAttrs.templateUrl||tableConfig.templateUrl},link:function(scope,element,attrs,tastyTable){"use strict";var getPage,setCount,setPaginationRange,setPreviousRange,setRemainingRange,setPaginationRanges,listScopeToWatch,newScopeName;listScopeToWatch=["bindItemsPerPage","bindListItemsPerPage","bindTemplateUrl"],listScopeToWatch.forEach(function(scopeName){newScopeName=scopeName.substring(4),newScopeName=newScopeName.charAt(0).toLowerCase()+newScopeName.slice(1),attrs[scopeName]?tastyUtil.bindTo(scopeName,scope,attrs,newScopeName):attrs[newScopeName]&&(scope[newScopeName]="itemsPerPage"===newScopeName?parseInt(attrs[newScopeName]):JSON.parse(attrs[newScopeName]))}),scope.templateUrl&&$http.get(scope.templateUrl,{cache:$templateCache}).success(function(templateContent){element.replaceWith($compile(templateContent)(scope))}),scope.itemsPerPage=scope.itemsPerPage||tableConfig.itemsPerPage,scope.listItemsPerPage=scope.listItemsPerPage||tableConfig.listItemsPerPage,scope.pagination={},scope.pagMinRange=1,scope.pagMaxRange=1,getPage=function(numPage){tastyTable.setParams("page",numPage)},setCount=function(count){var maxItems,page;maxItems=count*scope.pagination.page,maxItems>scope.pagination.size&&(page=Math.ceil(scope.pagination.size/count),tastyTable.setParams("page",page)),tastyTable.setParams("count",count)},setPaginationRange=function(){var currentPage;currentPage=scope.pagination.page,currentPage>scope.pagination.pages&&(currentPage=scope.pagination.pages),scope.pagMinRange=currentPage-2>0?currentPage-2:1,scope.pagMaxRange=currentPage+2,scope.pagination.page=currentPage,setPaginationRanges()},setPreviousRange=function(){return scope.pagHideMinRange===!0||scope.pagMinRange<1?!1:(scope.pagMaxRange=scope.pagMinRange,scope.pagMinRange=scope.pagMaxRange-scope.itemsPerPage,setPaginationRanges(),void 0)},setRemainingRange=function(){return scope.pagHideMaxRange===!0||scope.pagMaxRange>scope.pagination.pages?!1:(scope.pagMinRange=scope.pagMaxRange,scope.pagMaxRange=scope.pagMinRange+scope.itemsPerPage,scope.pagMaxRange>scope.pagination.pages&&(scope.pagMaxRange=scope.pagination.pages),scope.pagMinRange=scope.pagMaxRange-scope.itemsPerPage,setPaginationRanges(),void 0)},setPaginationRanges=function(){scope.listItemsPerPageShow=[],scope.pagMinRange=scope.pagMinRange>0?scope.pagMinRange:1,scope.pagMaxRange=scope.pagMinRange+5,scope.pagMaxRange>scope.pagination.pages&&(scope.pagMaxRange=scope.pagination.pages+1),scope.pagHideMinRange=scope.pagMinRange<=1,scope.pagHideMaxRange=scope.pagMaxRange>=scope.pagination.pages,scope.classPageMinRange=scope.pagHideMinRange?"disabled":"",scope.classPageMaxRange=scope.pagHideMaxRange?"disabled":"";for(var i=scope.listItemsPerPage.length;i>=0;i--)if(scope.pagination.size>scope.listItemsPerPage[i]){scope.listItemsPerPageShow=scope.listItemsPerPage.slice(0,i+1);break}scope.rangePage=$filter("range")([],scope.pagMinRange,scope.pagMaxRange),tastyTable.start||tastyTable.initTable("pagination")},scope.classPaginationCount=function(count){return count==scope.pagination.count?"active":""},scope.classNumPage=function(numPage){return numPage==scope.pagination.page?"active":!1},scope.page={get:getPage,setCount:setCount,previous:setPreviousRange,remaining:setRemainingRange},tastyTable.$scope.$watchCollection("pagination",function(newValue,oldValue){!newValue||newValue===oldValue&&tastyTable.start||(scope.pagination=newValue,setPaginationRange())}),scope.page.setCount(scope.itemsPerPage)}}}]),angular.module("ngTasty.filter.camelize",[]).filter("camelize",function(){var CAMELIZE_REGEX=/(?:^|[-_ ])(\w)/g;return function(input,first){var isString="string"==typeof input,first="undefined"==typeof first?!1:!!first;return"undefined"==typeof input||null===input||!isString&&isNaN(input)?"":isString?input.trim().replace(/ +(?= )/g,"").replace(CAMELIZE_REGEX,function(_,character,pos){return character&&(first||pos>0)?character.toUpperCase():character}):""+input}}),angular.module("ngTasty.filter.cleanFieldName",[]).filter("cleanFieldName",function(){return function(input){return input.replace(/[^a-zA-Z0-9-]+/g,"-")}}),angular.module("ngTasty.filter.filterInt",[]).filter("filterInt",function(){return function(input){return/^(\-|\+)?([0-9]+|Infinity)$/.test(input)?Number(input):0/0}}),angular.module("ngTasty.filter.range",["ngTasty.filter.filterInt"]).filter("range",["$filter",function($filter){return function(input,start,stop,step){if(start=$filter("filterInt")(start),stop=$filter("filterInt")(stop),step=$filter("filterInt")(step),isNaN(start)&&(start=0),isNaN(stop)&&(stop=start,start=0),isNaN(step)&&(step=1),step>0&&start>=stop||0>step&&stop>=start)return[];for(var i=start;step>0?stop>i:i>stop;i+=step)input.push(i);return input}}]),angular.module("ngTasty.filter.slugify",[]).filter("slugify",function(){var makeString=function(object){return null==object?"":""+object},defaultToWhiteSpace=function(characters){return null==characters?"\\s":characters.source?characters.source:"["+characters.replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")+"]"},from="ąàáäâãåæăćčĉęèéëêĝĥìíïîĵłľńňòóöőôõðøśșšŝťțŭùúüűûñÿýçżźž",to="aaaaaaaaaccceeeeeghiiiijllnnoooooooossssttuuuuuunyyczzz",regex=new RegExp(defaultToWhiteSpace(from),"g");return function(str){return str=makeString(str).toString().toLowerCase().replace(regex,function(c){var index=from.indexOf(c);return to.charAt(index)||"-"}).replace(/[^\w\-\s]+/g,"").trim().replace(/\s+/g,"-").replace(/\-\-+/g,"-")}}),angular.module("ngTasty.service.bindTo",[]).factory("bindTo",["$parse",function($parse){return function(scopeName,scope,attrs,newScopeName){var lastValue,parentGet,compare,parentSet,parentValueWatch,isolateScopeName;attrs[scopeName]&&(parentGet=$parse(attrs[scopeName]),compare=parentGet.literal?equals:function(a,b){return a===b||a!==a&&b!==b},isolateScopeName=newScopeName?newScopeName:scopeName,parentSet=parentGet.assign,lastValue=scope[isolateScopeName]=parentGet(scope.$parent),parentValueWatch=function(parentValue){return compare(parentValue,scope[isolateScopeName])||(compare(parentValue,lastValue)?parentSet(scope.$parent,parentValue=scope[isolateScopeName]):scope[isolateScopeName]=parentValue),lastValue=parentValue},parentValueWatch.$stateful=!0,scope.$parent.$watch($parse(attrs[scopeName],parentValueWatch),null,parentGet.literal))}}]),angular.module("ngTasty.service.debounce",[]).factory("debounce",["$timeout",function($timeout){return function(func,wait,immediate){var args,context,debounceTimeout,timeout,debounceTimeout=function(){timeout=null,immediate||func.apply(context,args)};return function(){context=this,args=arguments;var callNow=immediate&&!timeout;$timeout.cancel(timeout),timeout=$timeout(debounceTimeout,wait),callNow&&func.apply(context,args)}}}]),angular.module("ngTasty.service.joinObjects",["ngTasty.service.setProperty"]).factory("joinObjects",["setProperty",function(setProperty){return function(objOne,objTwo,listKeyNotJoin){listKeyNotJoin=listKeyNotJoin||[];for(var attrname in objTwo)listKeyNotJoin.indexOf(attrname)<0&&setProperty(objOne,objTwo,attrname);return objOne}}]),angular.module("ngTasty.service.setProperty",[]).factory("setProperty",function(){return function(objOne,objTwo,attrname){return"undefined"!=typeof objTwo[attrname]&&null!==objTwo[attrname]&&(objOne[attrname]=objTwo[attrname]),objOne}}),angular.module("ngTasty.service.tastyUtil",["ngTasty.service.bindTo","ngTasty.service.debounce","ngTasty.service.setProperty","ngTasty.service.joinObjects","ngTasty.service.throttle","ngTasty.service.webSocket"]).factory("tastyUtil",["debounce","setProperty","joinObjects","bindTo","webSocket","throttle",function(debounce,setProperty,joinObjects,bindTo,webSocket,throttle){return{bindTo:bindTo,debounce:debounce,setProperty:setProperty,joinObjects:joinObjects,throttle:throttle,webSocket:webSocket}}]),angular.module("ngTasty.service.throttle",[]).factory("throttle",["$timeout",function($timeout){return function(fn,threshhold,scope){threshhold||(threshhold=250);var last,promise;return function(){var context=scope||this,now=+new Date,args=arguments;last&&last+threshhold>now?($timeout.cancel(promise),promise=$timeout(function(){last=now,fn.apply(context,args)},threshhold)):(last=now,fn.apply(context,args))}}}]),angular.module("ngTasty.service.webSocket",[]).factory("webSocket",function(){return function(url){var blobURL=URL.createObjectURL(new Blob(["(",function(){var WSWorker=function(){var _ws,initialize=function(url){_ws=new WebSocket(url)},on=function(){_ws.onmessage=function(response){var data=JSON.parse(response.data);self.postMessage(data)}},send=function(data){_ws.send(data)};return{initialize:initialize,on:on,send:send}}();self.addEventListener("message",function(e){switch(e.data.cmd){case"ws_new":WSWorker.initialize(e.data.url);break;case"ws_on":WSWorker.on();break;case"ws_send":WSWorker.send(JSON.stringify(e.data.data));break;default:console.log("Unknown command: "+e.data.cmd)}})}.toString(),")()"],{type:"application/javascript"})),_worker=new Worker(blobURL);return URL.revokeObjectURL(blobURL),_worker.postMessage({cmd:"ws_new",url:url}),{on:function(event,cb){_worker.postMessage({cmd:"ws_on"}),_worker.addEventListener("message",function(e){("all"===event||e.data.type===event)&&cb(e.data)})},send:function(data){_worker.postMessage({cmd:"ws_send",data:data})}}}});
{
"name": "ng-tasty",
"version": "0.4.4",
"version": "0.4.5",
"description": "A lightweight, flexible, and tasty collection of reusable UI components for AngularJS.",

@@ -15,5 +15,9 @@ "main": "index.js",

"components",
"table"
"table",
"throttle",
"webSocket",
"slugify",
"camelize"
],
"author": "@zizzamia",
"author": { "name" : "Leonardo Zizzamia", "url" : "https://github.com/Zizzamia" },
"license": "MIT",

@@ -20,0 +24,0 @@ "bugs": {

@@ -35,2 +35,4 @@ # #ngTasty [![Bower version](https://badge.fury.io/bo/ng-tasty.svg)](https://github.com/Zizzamia/bower-ng-tasty) [![NPM version](https://badge.fury.io/js/ng-tasty.svg)](https://www.npmjs.org/package/ng-tasty) [![NPM Downloads](http://img.shields.io/npm/dm/ng-tasty.svg)](https://www.npmjs.org/package/ng-tasty) [![Build Status](https://secure.travis-ci.org/Zizzamia/ng-tasty.svg)](https://travis-ci.org/Zizzamia/ng-tasty)

Tasty Contributors: [@proudlygeek](https://twitter.com/proudlygeek), [@wesww](https://twitter.com/w3sw), [@aganglada](https://twitter.com/aganglada), [@alexcasalboni](https://twitter.com/alex_casalboni)
[bower]: https://github.com/Zizzamia/bower-ng-tasty

@@ -37,0 +39,0 @@ [bower-badge]: https://badge.fury.io/bo/ng-tasty.svg

@@ -37,3 +37,4 @@ /**

listItemsPerPage: [5, 25, 50, 100],
itemsPerPage: 5
itemsPerPage: 5,
watchResource: 'reference'
})

@@ -49,5 +50,8 @@ .controller('TableController', function($scope, $attrs, $filter, tableConfig, tastyUtil) {

$scope.query = {};
$scope.logs = {
'buildClientResourceCount': 0
};
listScopeToWatch = ['bindFilters', 'bindInit', 'bindQuery', 'bindResource',
'bindResourceCallback'];
'bindResourceCallback', 'bindWatchResource'];
listScopeToWatch.forEach(function (scopeName) {

@@ -70,2 +74,3 @@ newScopeName = scopeName.substring(4);

$scope.init.sortOrder = $scope.init.sortOrder || tableConfig.init.sortOrder;
$scope.watchResource = $scope.watchResource || tableConfig.watchResource;

@@ -111,3 +116,3 @@ // Defualt variables

throw 'AngularJS tastyTable directive: the bind-resource ('+
$attrs.bindResource + ') it\'s not an object';
$attrs.bindResource + ') is not an object';
} else if (!$scope.resource.header && !$scope.resource.rows) {

@@ -121,3 +126,3 @@ throw 'AngularJS tastyTable directive: the bind-resource ('+

throw 'AngularJS tastyTable directive: the bind-resource-callback ('+
$attrs.bindResourceCallback + ') it\'s not a function';
$attrs.bindResourceCallback + ') is not a function';
}

@@ -145,13 +150,13 @@ $scope.clientSide = false;

initStatus[keyDirective] = true;
if (!$scope.theadDirective && !$scope.paginationDirective) {
if (!$scope.theadDirective && !$scope.paginationDirective) { // None of them
this.start = true;
} else if ($scope.theadDirective && $scope.paginationDirective) {
} else if ($scope.theadDirective && $scope.paginationDirective) { // Both directives
if (initStatus.thead && initStatus.pagination){
this.start = true;
}
} else if ($scope.theadDirective && !$scope.paginationDirective) {
} else if ($scope.theadDirective && !$scope.paginationDirective) { // Only Thead directive
if (initStatus.thead){
this.start = true;
}
} else if (!$scope.theadDirective && $scope.paginationDirective) {
} else if (!$scope.theadDirective && $scope.paginationDirective) { // Only Pagination directive
if (initStatus.pagination){

@@ -183,7 +188,6 @@ this.start = true;

setDirectivesValues = function (resource) {
if (!angular.isObject(resource)) {
throw 'AngularJS tastyTable directive: the bind-resource '+
'it\'s not an object';
if (!$scope.resource && !angular.isObject(resource)) {
throw 'AngularJS tastyTable directive: the resource response is not an object';
} else if (!resource.header && !resource.rows) {
throw 'AngularJS tastyTable directive: the bind-resource '+
throw 'AngularJS tastyTable directive: the resource response object '+
'has the property header or rows undefined';

@@ -238,2 +242,3 @@ }

var fromRow, toRow, rowToShow, reverse, listSortBy;
$scope.logs.buildClientResourceCount += 1;
if ($scope.theadDirective && $scope.header.columns.length) {

@@ -332,3 +337,3 @@ reverse = $scope.header.sortOrder === 'asc' ? false : true;

if ($scope.resource) {
$scope.$watch('resource', function watchResource (newValue, oldValue){
var watchResource = function (newValue, oldValue){
if (newValue !== oldValue) {

@@ -338,4 +343,29 @@ $scope.params.sortBy = newValue.sortBy;

$scope.$evalAsync(updateClientSideResource('resource'));
if (!$scope.resource.reload) {
$scope.resource.reload = function () {
$scope.$evalAsync(updateClientSideResource('resource'));
};
}
}
}, true);
};
if ($scope.watchResource === 'reference') {
$scope.$watch('resource', watchResource);
} else if ($scope.watchResource === 'collection') {
$scope.$watchCollection('resource.header', watchResource);
$scope.$watchCollection('resource.rows', watchResource);
$scope.$watchGroup(['sortBy',
'sortOrder',
'pagination.count',
'pagination.page',
'pagination.pages',
'pagination.size'], watchResource);
} else if ($scope.watchResource === 'equality') {
$scope.$watch('resource', function (newValue, oldValue){
if (newValue !== oldValue) {
$scope.params.sortBy = newValue.sortBy;
$scope.params.sortOrder = newValue.sortOrder;
$scope.$evalAsync(updateClientSideResource('resource'));
}
}, true);
}
}

@@ -404,6 +434,5 @@ })

scope.setColumns = function () {
var lenHeader, width, i, active, sortable, sort,
var width, i, active, sortable, sort,
isSorted, isSortedCaret;
scope.columns = [];
lenHeader = scope.header.columns.length;
scope.header.columns.forEach(function (column, index) {

@@ -410,0 +439,0 @@ column.style = column.style || {};

/**
* @ngdoc filter
* @name cleanFieldName
* @function
*

@@ -5,0 +6,0 @@ * @description

/**
* @ngdoc filter
* @name filterInt
* @kind function
* @function
*

@@ -6,0 +6,0 @@ */

/**
* @ngdoc filter
* @name range
* @kind function
* @function
*

@@ -6,0 +6,0 @@ * @description

@@ -8,14 +8,22 @@ /**

angular.module('ngTasty.service.debounce', [])
.factory('debounce', function($timeout) {
.factory('debounce', function ($timeout) {
return function (func, wait, immediate) {
var timeout;
var args, context, debounceTimeout, timeout;
var debounceTimeout = function() {
timeout = null;
if (!immediate) {
func.apply(context, args);
}
};
return function debounce () {
var context = this, args = arguments;
context = this;
args = arguments;
var callNow = immediate && !timeout;
$timeout.cancel(timeout);
timeout = $timeout(function debounceTimeout () {
timeout = null;
timeout = $timeout(debounceTimeout, wait);
if (callNow) {
func.apply(context, args);
}, wait);
}
};
};
});

@@ -13,3 +13,3 @@ /**

var last, promise;
return function () {
return function throttle () {
var context = scope || this;

@@ -21,3 +21,3 @@ var now = +new Date,

$timeout.cancel(promise);
promise = $timeout(function () {
promise = $timeout(function throttleTimeout () {
last = now;

@@ -24,0 +24,0 @@ fn.apply(context, args);

@@ -11,2 +11,11 @@ /**

return function(url) {
/**
* Creates a String[1] representing a binary blob[2] function
* containing the WebSocket Factory API.
*
* [1]: https://developer.mozilla.org/en-US/docs/Web/API/URL.createObjectURL
* [2]: https://developer.mozilla.org/en-US/docs/Web/API/Blob
*
* @return {string} String containing the encoded script
*/
var blobURL = URL.createObjectURL(new Blob(['(', function() {

@@ -16,2 +25,8 @@ var WSWorker = (function() {

/**
* Initialize a new WebSocket using
* the provided URL parameters.
*
* @param {string} url The WebSocket URL
*/
var initialize = function(url) {

@@ -21,3 +36,10 @@ _ws = new WebSocket(url);

var on = function(event) {
/**
* Listens for any message coming from the WebSocket
* and send its content to the main JS thread using postMessage[1].
*
* [1]: https://developer.mozilla.org/en-US/docs/Web/API/Worker.postMessage
*
*/
var on = function() {
_ws.onmessage = function(response) {

@@ -29,2 +51,7 @@ var data = JSON.parse(response.data);

/**
* Sends data to the WebSocket.
*
* @param {string} data
*/
var send = function(data) {

@@ -42,2 +69,14 @@ _ws.send(data);

/**
* Listens for incoming messages from the main
* JavaScript Thread.
*
* The commands allowed are:
*
* ws_new ~> Calls initialize on the Web Socket Worker
* ws_on ~> Register the supplied callback
* ws_send ~> Sends a message to the underlying WebSocket
* encoding it as a string (JSON.stringify)
*
*/
self.addEventListener('message', function(e) {

@@ -49,3 +88,3 @@ switch (e.data.cmd) {

case 'ws_on':
WSWorker.on(e.data.event, e.data.cb);
WSWorker.on();
break;

@@ -61,9 +100,38 @@ case 'ws_send':

}.toString(), ')()'], { type: 'application/javascript' }));
// Create a new WebSocket Worker, revoke the URL since
// it's not useful anymore.
var _worker = new Worker(blobURL);
URL.revokeObjectURL(blobURL);
// Tell the WebSocket Worker to init a new WebSocket
_worker.postMessage({ cmd: 'ws_new', url: url });
return {
/**
* Registers a callback to a specific Worker event listener.
* There are two different events:
*
* - 'all' ~> subscribes to all websocket messages
* - 'type'~> subscribes to all websocket messages containing
* a field named 'type'.
*
* For example, WebSockets Server events like this one:
*
* {
* 'type': 'tweet',
* 'data': ...
* }
*
* can be handled in the following way:
*
* ws.on('twitter', function(data) {
* ...
* });
*
* @param {string} event The event name
* @param {Function} cb Callback with output data (first param)
*/
on: function(event, cb) {

@@ -77,2 +145,7 @@ _worker.postMessage({ cmd: 'ws_on' });

},
/**
* Sends data to the WebSocket.
*
* @param {Any} data
*/
send: function(data) {

@@ -79,0 +152,0 @@ _worker.postMessage({ cmd: 'ws_send', data: data });

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc