aboutsummaryrefslogtreecommitdiffstats
path: root/vnfmarket/common/thirdparty/angular-material-data-table
diff options
context:
space:
mode:
Diffstat (limited to 'vnfmarket/common/thirdparty/angular-material-data-table')
-rw-r--r--vnfmarket/common/thirdparty/angular-material-data-table/.bower.json44
-rw-r--r--vnfmarket/common/thirdparty/angular-material-data-table/CHANGELOG.md129
-rw-r--r--vnfmarket/common/thirdparty/angular-material-data-table/LICENSE.md21
-rw-r--r--vnfmarket/common/thirdparty/angular-material-data-table/README.md576
-rw-r--r--vnfmarket/common/thirdparty/angular-material-data-table/bower.json35
-rw-r--r--vnfmarket/common/thirdparty/angular-material-data-table/dist/md-data-table.css394
-rw-r--r--vnfmarket/common/thirdparty/angular-material-data-table/dist/md-data-table.js1486
-rw-r--r--vnfmarket/common/thirdparty/angular-material-data-table/dist/md-data-table.min.css1
-rw-r--r--vnfmarket/common/thirdparty/angular-material-data-table/dist/md-data-table.min.js1
-rw-r--r--vnfmarket/common/thirdparty/angular-material-data-table/index.js6
-rw-r--r--vnfmarket/common/thirdparty/angular-material-data-table/package.json32
11 files changed, 2725 insertions, 0 deletions
diff --git a/vnfmarket/common/thirdparty/angular-material-data-table/.bower.json b/vnfmarket/common/thirdparty/angular-material-data-table/.bower.json
new file mode 100644
index 00000000..a7a88ab3
--- /dev/null
+++ b/vnfmarket/common/thirdparty/angular-material-data-table/.bower.json
@@ -0,0 +1,44 @@
+{
+ "name": "angular-material-data-table",
+ "version": "0.10.10",
+ "description": "Material Design data table.",
+ "main": [
+ "dist/md-data-table.js",
+ "dist/md-data-table.css"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/daniel-nagy/md-data-table.git"
+ },
+ "authors": [
+ "Daniel Nagy"
+ ],
+ "homepage": "http://danielnagy.me/md-data-table",
+ "license": "MIT",
+ "keywords": [
+ "material",
+ "table",
+ "md-data-table"
+ ],
+ "ignore": [
+ "**/.*",
+ "app",
+ "bower_components",
+ "node_modules",
+ "src",
+ "Gruntfile.js"
+ ],
+ "dependencies": {
+ "angular": "^1.4.0",
+ "angular-material": "^1.0.0"
+ },
+ "_release": "0.10.10",
+ "_resolution": {
+ "type": "version",
+ "tag": "v0.10.10",
+ "commit": "d20fb0c2126fcecdfa6cb7bb9923887c44a4dc0a"
+ },
+ "_source": "https://github.com/daniel-nagy/md-data-table.git",
+ "_target": "^0.10.10",
+ "_originalSource": "angular-material-data-table"
+} \ No newline at end of file
diff --git a/vnfmarket/common/thirdparty/angular-material-data-table/CHANGELOG.md b/vnfmarket/common/thirdparty/angular-material-data-table/CHANGELOG.md
new file mode 100644
index 00000000..c6947c85
--- /dev/null
+++ b/vnfmarket/common/thirdparty/angular-material-data-table/CHANGELOG.md
@@ -0,0 +1,129 @@
+## Change Log
+
+#### Version 0.10.10
+###### December 14, 2016
+
+**Future Proofing**
+
+* Merge #517 from [@christophercr](https://github.com/christophercr) to change the restriction on the `mdTableProgress` directive from class name to attribute to support newer versions of AngularJS.
+
+#### Version 0.10.9
+###### April 26, 2016
+
+**Bug Fix**
+
+* Removing one time binding from pagination limit options.
+
+#### Version 0.10.8
+###### April 23, 2016
+
+**New Feature**
+
+* You can now map language to limit options using the `label` and `value` properties, e.g.
+
+ ```javascript
+ ctrl.limitOptions = [5, 10, 15, {
+ label: 'All',
+ value: function () {
+ return collection.length;
+ }
+ }];
+ ```
+
+#### Version 0.10.7
+###### April 19, 2016
+
+**Bug Fixes**
+
+* Fix bug where pagination page number would disappear.
+
+#### Version 0.10.6
+###### April 19, 2016
+
+**Bug Fixes**
+
+* Fixing bug where changing the `orderBy` property of a column would add an additional sort icon.
+
+#### Version 0.10.5
+###### April 9, 2016
+
+**Bug Fixes**
+
+* Fixing bug in pagination directive where the number of pages was always equal to the number of rows in the table.
+
+#### Version 0.10.4
+###### April 5, 2016
+
+**Improvements**
+
+* Pagination is now usable on mobile.
+* More safeguards in pagination directive against performing calculations on `NaN`.
+
+**Bug Fixes**
+
+* Fixing issue where errors would be thrown if row selection was not enabled.
+
+#### Version 0.10.3
+###### April 1, 2016
+
+**Bug Fixes**
+
+* The pagination directive will now display `0 - 0 of 0` if the total is zero.
+
+#### Version 0.10.2
+###### March 30, 2016
+
+**Bug Fixes**
+
+* Fixes bug where the select all checkbox would not be added to subsequent tables.
+
+#### Version 0.10.1
+###### March 27, 2016
+
+**New Features**
+
+* Pagination elements may now be disabled with the `ng-disabled` attribute.
+
+**Bug Fixes & Improvements**
+
+* When the total changes, the pagination directive will check if the current page is greater than the total number of pages. If it is greater, the page will be set to the last available page.
+
+#### Version 0.10.0
+###### March 27, 2016
+
+**Breaking Changes**
+
+* Multiple selection must now be enabled with the `multiple` attribute.
+
+ ```html
+ <table md-table md-row-select multiple ng-model="selected">
+ ```
+
+* Unique identifiers must now be a property of the item.
+
+ ```html
+ <!-- use item.id as the unique identifier -->
+ <tr md-row md-select="item" md-select-id="id" md-auto-select ng-repeat="item in items">
+ ```
+
+* Some folks do not want the pagination limit options to be enabled. To compensate, the pagination limit options must now be enabled with the `mdLimitOptions` attribute. The `mdLimitOptions` attribute is a replacement of the `mdOptions` attribute and the default limit options have been removed.
+
+ ```html
+ <md-table-pagination md-limit-options="[5, 10, 15]">
+ ```
+
+**New Features**
+
+* Single item selection is now possible and enabled by default. Be aware that the `ngModel` attribute must still be an array; for now.
+
+* The pagination limit options are now disabled be default.
+
+* The pagination page selector is now virtualized to improve performance.
+
+**Bug Fixes & Improvements**
+
+* Preselected items will now be displayed by the UI. Keep in mind that if preselected items are not strictly equal to items in the table you will need to use the `mdSelectId` attribute.
+
+* Changes to the pagination label will now take effect without needing to reload the page.
+
+* Pagination and reorder callbacks are now deferred until the next digest cycle using Angular Material's `$mdUtil.nextTick` function to allow 2-way data binding to complete and to avoid confusion. This means your local scope variables will have the same value as the parameters passed to the `md-on-reorder` and `md-on-paginate` callbacks. \ No newline at end of file
diff --git a/vnfmarket/common/thirdparty/angular-material-data-table/LICENSE.md b/vnfmarket/common/thirdparty/angular-material-data-table/LICENSE.md
new file mode 100644
index 00000000..52cee4ab
--- /dev/null
+++ b/vnfmarket/common/thirdparty/angular-material-data-table/LICENSE.md
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Daniel Nagy
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vnfmarket/common/thirdparty/angular-material-data-table/README.md b/vnfmarket/common/thirdparty/angular-material-data-table/README.md
new file mode 100644
index 00000000..a6fb29ae
--- /dev/null
+++ b/vnfmarket/common/thirdparty/angular-material-data-table/README.md
@@ -0,0 +1,576 @@
+# Material Design Data Table
+
+This module is an effort to implement Material Design data tables in [Angular Material](https://material.angularjs.org/latest/#/). Data tables are used to present raw data sets and usually appear in desktop enterprise applications. Data tables are particularly useful for visualizing and manipulating large data sets.
+
+Specification for Material Design data tables can be found [here](http://www.google.com/design/spec/components/data-tables.html).
+
+* [License](#license)
+* [Demo](#demo)
+* [Installation](#installation)
+* [Usage](#usage)
+* [Change Log](CHANGELOG.md)
+* [API Documentation](#api-documentation)
+* [Contributing] (#contributing)
+
+## License
+
+This software is provided free of charge and without restriction under the [MIT License](LICENSE.md)
+
+## Demo
+
+A live [demo](http://danielnagy.me/md-data-table).
+
+A fork-able [Codepen](http://codepen.io/anon/pen/BjvLVJ?editors=1010). Please use this to reproduce any issues you may be experiencing.
+
+## Installation
+
+#### Using Bower
+
+This package is installable through the Bower package manager.
+
+```
+bower install angular-material-data-table --save
+```
+
+In your `index.html` file, include the data table module and style sheet.
+
+```html
+<!-- style sheet -->
+<link href="bower_components/angular-material-data-table/dist/md-data-table.min.css" rel="stylesheet" type="text/css"/>
+<!-- module -->
+<script type="text/javascript" src="bower_components/angular-material-data-table/dist/md-data-table.min.js"></script>
+```
+
+Include the `md.data.table` module as a dependency in your application.
+
+```javascript
+angular.module('myApp', ['ngMaterial', 'md.data.table']);
+```
+
+#### Using npm and Browserify (or JSPM)
+
+In addition, this package may be installed using npm.
+
+```
+npm install angular-material-data-table --save
+```
+
+You may use Browserify to inject this module into your application.
+
+```javascript
+angular.module('myApp', [require('angular-material-data-table')]);
+```
+
+## Usage
+
+**Example Controller**
+
+```javascript
+
+// Assume we have a $nutrition service that provides an API for communicating with the server
+
+angular.module('demoApp').controller('sampleController', ['$nutrition', '$scope', function ($nutrition, $scope) {
+ 'use strict';
+
+ $scope.selected = [];
+
+ $scope.query = {
+ order: 'name',
+ limit: 5,
+ page: 1
+ };
+
+ function success(desserts) {
+ $scope.desserts = desserts;
+ }
+
+ $scope.getDesserts = function () {
+ $scope.promise = $nutrition.desserts.get($scope.query, success).$promise;
+ };
+
+}]);
+```
+
+**Example Template**
+
+```html
+<md-toolbar class="md-table-toolbar md-default">
+ <div class="md-toolbar-tools">
+ <span>Nutrition</span>
+ </div>
+</md-toolbar>
+
+<!-- exact table from live demo -->
+<md-table-container>
+ <table md-table md-row-select multiple ng-model="selected" md-progress="promise">
+ <thead md-head md-order="query.order" md-on-reorder="getDesserts">
+ <tr md-row>
+ <th md-column md-order-by="nameToLower"><span>Dessert (100g serving)</span></th>
+ <th md-column md-numeric md-order-by="calories.value"><span>Calories</span></th>
+ <th md-column md-numeric>Fat (g)</th>
+ <th md-column md-numeric>Carbs (g)</th>
+ <th md-column md-numeric>Protein (g)</th>
+ <th md-column md-numeric>Sodium (mg)</th>
+ <th md-column md-numeric>Calcium (%)</th>
+ <th md-column md-numeric>Iron (%)</th>
+ </tr>
+ </thead>
+ <tbody md-body>
+ <tr md-row md-select="dessert" md-select-id="name" md-auto-select ng-repeat="dessert in desserts.data">
+ <td md-cell>{{dessert.name}}</td>
+ <td md-cell>{{dessert.calories.value}}</td>
+ <td md-cell>{{dessert.fat.value | number: 1}}</td>
+ <td md-cell>{{dessert.carbs.value}}</td>
+ <td md-cell>{{dessert.protein.value | number: 1}}</td>
+ <td md-cell>{{dessert.sodium.value}}</td>
+ <td md-cell>{{dessert.calcium.value}}{{dessert.calcium.unit}}</td>
+ <td md-cell>{{dessert.iron.value}}{{dessert.iron.unit}}</td>
+ </tr>
+ </tbody>
+ </table>
+</md-table-container>
+
+<md-table-pagination md-limit="query.limit" md-limit-options="[5, 10, 15]" md-page="query.page" md-total="{{desserts.count}}" md-on-paginate="getDesserts" md-page-select></md-table-pagination>
+
+```
+
+## API Documentation
+
+**v0.10.x**
+
+* [Column Sorting](#column-sorting)
+* [Edit Dialogs](#edit-dialogs)
+* [Inline Menus](#inline-menus)
+* [Numeric Columns](#numeric-columns)
+* [Pagination](#pagination)
+* [Row Selection](#row-selection)
+* [Table Progress] (#table-progress)
+* [Table Toolbars](#table-toolbars)
+
+**Earlier Versions**
+
+* [0.9.x](https://github.com/daniel-nagy/md-data-table/tree/v0.9.x#api-documentation)
+* [<=0.8.14](https://github.com/daniel-nagy/md-data-table/tree/legacy#api-documentation)
+
+> Tables are sorted alphabetically by their first column.
+> I will be **camelCasing** attributes in tables (otherwise the cells would wrap and be difficult to read) but don't forget to **kebab-case** them in your template.
+
+### Column Sorting
+
+| Attribute | Element | Type | Description |
+| :------------- | :--------- | :------------- | :---------- |
+| `mdDesc` | `mdColumn` | `[expression]` | If present, the column will sort descending first. The default is to sort ascending first. |
+| `mdOnReorder` | `mdHead` | `function` | A callback function for when the order changes. The callback will receive the new order. |
+| `mdOrder` | `mdHead` | `string` | A variable to bind the sort order to. |
+| `mdOrderBy` | `mdColumn` | `string` | The value to bind to the sort order. |
+
+When the user clicks the `md-column` element, the value of the `md-order-by` attribute will be bound to the variable provided to the `md-order` attribute on the `md-head` element. If the column is already sorted by that value, a minus sign `-` will be prefixed to the value. For most query languages, this is the universal symbol to sort descending.
+
+The variable can be used to send a query to the server or as the `orderBy` property of an `ng-repeat` expression.
+
+**Example Using ngRepeat**
+
+```html
+<md-table-container>
+ <table md-table>
+ <thead md-head md-order="myOrder">
+ <!-- when the user clicks this cell, the myOrder variable will get the value 'nameToLower' -->
+ <th md-column md-order-by="nameToLower">Dessert (100g serving)</th>
+ <!-- the variable myOrder will not be changed when this cell is clicked -->
+ <th md-column md-numeric>Calories</th>
+ </thead>
+ <tbody md-body>
+ <!-- we can let ng-repeat sort the columns for us -->
+ <tr ng-repeat="dessert in desserts | orderBy: myOrder"></tr>
+ </tbody>
+ </table>
+</md-table-container>
+```
+
+### Edit Dialogs
+
+Tables may require basic text editing. This module includes a service for displaying edit dialogs to modify text or anything else really. The service provides presets for both small and large edit dialogs designed for manipulating text. It also has full support for creating custom dialogs so you can be as creative as you want to be.
+
+Unlike Angular Material dialogs, the preset methods will open the dialog.
+
+**Restrictions**
+
+* The dialog will always receive a new isolated scope.
+* You must provide a `targetEvent` and the event target must be a table cell.
+
+**Example**
+
+```javascript
+$scope.editComment = function (event, dessert) {
+ // if auto selection is enabled you will want to stop the event
+ // from propagating and selecting the row
+ event.stopPropagation();
+
+ /*
+ * messages is commented out because there is a bug currently
+ * with ngRepeat and ngMessages were the messages are always
+ * displayed even if the error property on the ngModelController
+ * is not set, I've included it anyway so you get the idea
+ */
+
+ var promise = $mdEditDialog.small({
+ // messages: {
+ // test: 'I don\'t like tests!'
+ // },
+ modelValue: dessert.comment,
+ placeholder: 'Add a comment',
+ save: function (input) {
+ dessert.comment = input.$modelValue;
+ },
+ targetEvent: event,
+ validators: {
+ 'md-maxlength': 30
+ }
+ });
+
+ promise.then(function (ctrl) {
+ var input = ctrl.getInput();
+
+ input.$viewChangeListeners.push(function () {
+ input.$setValidity('test', input.$modelValue !== 'test');
+ });
+ });
+});
+```
+
+#### Small Edit Dialogs
+
+```javascript
+$mdEditDialog.small(options);
+```
+
+| Parameter | Type | Description |
+| :-------- | :----- | :---------- |
+| options | object | Small preset options. |
+
+| Property | Type | Default | Description |
+| :-------------------- | :--------- | :------- | :---------- |
+| `clickOutsideToClose` | `bool` | `true` | The user can dismiss the dialog by clicking anywhere else on the page. |
+| `disableScroll` | `bool` | `true` | Prevent user scroll while the dialog is open. |
+| `escToClose` | `bool` | `true` | The user can dismiss the dialog by clicking the esc key. |
+| `focusOnOpen` | `bool` | `true` | Will search the template for an `md-autofocus` element. |
+| `messages` | `object` | `null` | Error messages to display corresponding to errors on the `ngModelController`. |
+| `modelValue` | `string` | `null` | The initial value of the input element. |
+| `placeholder` | `string` | `null` | Placeholder text for input element. |
+| `save` | `function` | `null` | A callback function for when the use clicks the save button. The callback will receive the [ngModelController](https://docs.angularjs.org/api/ng/type/ngModel.NgModelController). The dialog will close unless the callback returns a rejected promise. |
+| `targetEvent` | `event` | `null` | The event object. This must be provided and it must be from a table cell. |
+| `type` | `string` | `"text"` | The value of the `type` attribute on the `input` element. |
+| `validators` | `object` | `null` | Optional attributes to be placed on the input element. |
+
+The `small` method will return a `promise` that will resolve with the controller instance. The controller has two public methods, `dismiss` which will close the dialog without saving and `getInput` which will return the `ngModelController`.
+
+#### Large Edit Dialogs
+
+Large edit dialogs are functionally identical to small edit dialogs but have a few additional options.
+
+```javascript
+$mdEditDialog.large(options);
+```
+| Parameter | Type | Description |
+| :-------- | :----- | :---------- |
+| options | object | Large preset options. |
+
+| Property | Type | Default | Description |
+| :-------------------- | :--------- | :--------- | :---------- |
+| `cancel` | `string` | `"Cancel"` | Text to dismiss the dialog without saving. |
+| `clickOutsideToClose` | `bool` | `true` | The user can dismiss the dialog by clicking anywhere else on the page. |
+| `disableScroll` | `bool` | `true` | Prevent user scroll while the dialog is open. |
+| `escToClose` | `bool` | `true` | The user can dismiss the dialog by clicking the esc key. |
+| `focusOnOpen` | `bool` | `true` | Will search the template for an `md-autofocus` element. |
+| `messages` | `object` | `null` | Error messages to display corresponding to errors on the `ngModelController`. |
+| `modelValue` | `string` | `null` | The initial value of the input element. |
+| `ok` | `string` | `"Save"` | Text to submit and dismiss the dialog. |
+| `placeholder` | `string` | `null` | Placeholder text for input element. |
+| `save` | `function` | `null` | A callback function for when the use clicks the save button. The callback will receive the `ngModelController`. The dialog will close unless the callback returns a rejected promise. |
+| `targetEvent` | `event` | `null` | The event object. This must be provided and it must be from a table cell. |
+| `title` | `string` | `"Edit"` | Dialog title text. |
+| `type` | `string` | `"text"` | The value of the `type` attribute on the `input` element. |
+| `validators` | `object` | `null` | Optional attributes to be placed on the input element. |
+
+The `large` method will return a `promise` that will resolve with the controller instance. The controller has two public methods, `dismiss` which will close the dialog without saving and `getInput` which will return the `ngModelController`.
+
+#### Roll Your Own
+
+```javascript
+$mdEditDialog.show(options);
+```
+
+| Parameter | Type | Description |
+| :-------- | :----- | :---------- |
+| options | object | Dialog options. |
+
+| Property | Type | Default | Description |
+| :-------------------- | :------------------ | :------ | :---------- |
+| `bindToController` | `bool` | `false` | If true, properties on the provided scope object will be bound to the controller |
+| `clickOutsideToClose` | `bool` | `true` | The user can dismiss the dialog by clicking anywhere else on the page. |
+| `controller` | `function` `string` | `null` | Either a constructor function or a string register with the `$controller` service. The controller will be automatically injected with `$scope` and `$element`. Remember to annotate your controller if you will be minifying your code. |
+| `controllerAs` | `string` | `null` | An alias to publish your controller on the scope. |
+| `disableScroll` | `bool` | `true` | Prevent user scroll while the dialog is open. |
+| `escToClose` | `bool` | `true` | The user can dismiss the dialog by clicking the esc key. |
+| `focusOnOpen` | `bool` | `true` | Will search the template for an `md-autofocus` element. |
+| `locals` | `object` | `null` | Optional dependancies to be injected into your controller. It is not necessary to inject registered services, the `$injector` will provide them for you. |
+| `resolve` | `object` | `null` | Similar to locals but waits for promises to be resolved. Once the promises resolve, their return value will be injected into the controller and the dialog will open. |
+| `scope` | `object` | `null` | Properties to bind to the new isolated scope. |
+| `targetEvent` | `event` | `null` | The event object. This must be provided and it must be from a table cell. |
+| `template` | `string` | `null` | The template for your dialog. |
+| `templateUrl` | `string` | `null` | A URL to fetch your template from. |
+
+The `show` method will return a `promise` that will resolve with the controller instance.
+
+Table cells have a `md-placeholder` CSS class that you can use for placeholder text.
+
+**Example: A Table Cell That Opens An Edit Dialog**
+
+```html
+<td md-cell ng-click="editComment($event, dessert)" ng-class="{'md-placeholder': !dessert.comment}">
+ {{dessert.comment || 'Add a comment'}}
+</td>
+```
+
+### Inline Menus
+
+Table cells support inline menus. To use an inline menu, place an `md-select` element inside an `md-cell` element.
+
+**Example**
+
+```html
+<td md-cell>
+ <md-select ng-model="dessert.type" placeholder="Other">
+ <md-option ng-value="type" ng-repeat="type in getTypes()">{{type}}</md-option>
+ </md-select>
+</td>
+```
+
+Clicking anywhere in the cell will activate the menu. In addition, if you have automatic row selection enabled the row will not be selected when the cell is clicked.
+
+### Numeric Columns
+
+Numeric columns align to the right of table cells.
+
+| Attribute | Element | Type | Description |
+| :--------- | :--------- | :------------- | :---------- |
+| `mdNumeric` | `mdColumn` | `[expression]` | If the expression is `null` or evaluates to `true` then all the cells in that column will be right aligned |
+
+You may use Angular's [number](https://docs.angularjs.org/api/ng/filter/number) filter on a cell to set the decimal precision.
+
+```html
+<!-- 2 decimal places -->
+<td md-cell>{{dessert.protein.value | number: 2}}</td>
+```
+
+> If you are using `colspan` you may need to manual correct the alignment and padding of cells. You can override the cell's style with a custom CSS class.
+
+### Pagination
+
+| Attribute | Type | Description |
+| :---------------- | :------------- | :---------- |
+| `mdBoundaryLinks` | `[expression]` | Displays first and last page navigation links |
+| `mdLabel` | `object` | Change the pagination label (see more below). |
+| `mdLimit` | `integer` | A row limit. |
+| `mdLimitOptions` | `array` | Row limit options (see more below). |
+| `mdOnPaginate` | `function` | A callback function for when the page or limit changes. The page is passed as the first argument and the limit is passed as the second argument. |
+| `mdPage` | `integer` | Page number. Pages are not zero indexed. The directive assumes the first page is one. |
+| `mdPageSelect` | `[expression]` | Display a select dropdown for the page number |
+| `mdTotal` | `integer` | Total number of items. |
+| `ngDisabled` | `[expression]` | Disable pagination elements. |
+
+The `md-label` attribute has the following properties.
+
+| Property | Type | Default |
+| :---------- | :------- | :------ |
+| of | `string` | 'of' (e.g. x - y of z) |
+| page | `string` | 'Page:' |
+| rowsPerPage | `string` | 'Rows per page:' |
+
+The `md-limit-options` attribute supports integers or objects with the properties `label` and `value`. The latter is convenient for when you want to use language to give meaning to individual options, e.g.
+
+```javascript
+// the 'All' option will show all items in the collection
+ctrl.limitOptions = [5, 10, 15, {
+ label: 'All',
+ value: function () {
+ return collection.length;
+ }
+}];
+```
+
+**Example: Changing The Pagination Label**
+
+```html
+<!-- how to change the pagination label -->
+<md-table-pagination md-label="{page: 'Página:', rowsPerPage: 'Filas por página:', of: 'de'}"></md-table-pagination>
+
+<!-- or if the label is defined on the scope -->
+<md-table-pagination md-label="{{label}}"></md-table-pagination>
+```
+
+> I used Google translate so if the translations are wrong please fix them and make a pull request.
+
+**Example: Client Side Pagination Using ngRepeat**
+
+```html
+<tr md-row ng-repeat="item in array | orderBy: myOrder | limitTo: myLimit: (myPage - 1) * myLimit">
+
+<!-- and your pagination element will look something like... -->
+<md-table-pagination md-limit="myLimit" md-page="myPage" md-total="{{array.length}}"></md-table-pagination>
+```
+
+**My Pagination Isn't Working?!**
+
+* Make sure you pass `md-page`, `md-limit`, and `md-total` to the directive and that they are finite numbers.
+* Pages are not zero indexed. The directive will assume pages start at one. If your query language expects pages to be zero indexed then just subtract one before making the query.
+
+### Row Selection
+
+| Attribute | Element | Type | Description |
+| :------------- | :-------- | :---------------- | :---------- |
+| `mdAutoSelect` | `mdRow` | `[expression]` | Select a row by clicking anywhere in the row. |
+| `mdOnDeselect` | `mdRow` | `function` | A callback function for when an item is deselected. The item will be passed as an argument to the callback. |
+| `mdOnSelect` | `mdRow` | `function` | A callback function for when an item is selected. The item will be passed as an argument to the callback. |
+| `mdRowSelect` | `mdTable` | `[expression]` | Enable row selection. |
+| `mdSelect` | `mdRow` | `any` | The item to be selected. |
+| `mdSelectId` | `mdRow` | `number` `string` | A unique identifier for the selected item. The identifier must be a property of the item. |
+| `multiple` | `mdTable` | `[expression]` | Allow multiple selection. When enabled a master toggle will be prepended to the last row of table header. |
+| `ngDisabled` | `mdRow` | `expression` | Conditionally disable row selection. |
+| `ngModel` | `mdTable` | `array` | A variable to bind selected items to. |
+
+By default selected items will persist. Equality between items is determined using the `===` operator. In cases where items may not be strictly equal, you must provide a unique identifier for the item.
+
+You may manually add or remove items from the model but be aware that select and deselect callbacks will not be triggered. When operating in single select mode, the deselect callback will not be triggered when a user selects another item. It will be trigger, however, if the user directly deselects the item. In multi-select mode, the master toggle will trigger select and deselect callbacks for all items selected or deselected respectfully.
+
+**Example: Row Selection From The Live Demo.**
+
+```html
+<tr md-row md-select="dessert" md-select-id="name" md-auto-select ng-repeat="dessert in desserts.data">
+```
+
+**Example: Clearing Selected Items On Pagination**
+
+```javascript
+$scope.onPaginate = function () {
+ $scope.selected = [];
+}
+```
+
+### Table Progress
+
+| Attribute | Target | Type | Description |
+| :----------- | :-------- | :------------------------- | :---------- |
+| `mdProgress` | `mdTable` | `promise` `promise<Array>` | The table will display a loading indicator until all promises are resolved or rejected. |
+
+The table module can display a loading indicator for you whenever asynchronous code is executing. It accepts a promise or an array of promises. If another promise is received before the previous promise is resolved or rejected it will be placed in a queue.
+
+Because I spent almost an hour debugging this I thought I would share with you. I'm not sure why this is the case but if you put the deferred object on the scope and try to pass the promise to the directive from that, the queue mechanism will not work properly.
+
+**This Will Not Work**
+
+```javascript
+function () {
+ $scope.deferred = $q.defer();
+ // ...
+ $scope.deferred.resolve();
+}
+```
+
+```html
+<table md-table md-progress="deferred.promise"></table>
+```
+
+**This Will Work**
+
+```javascript
+function () {
+ var deferred = $q.defer();
+ $scope.promise = deferred.promise;
+ // ...
+ deferred.resolve();
+}
+```
+
+```html
+<table md-table md-progress="promise"></table>
+```
+
+In addition, if you are dealing with something that returns a promise directly (not a deferred object) you don't need to worry about it.
+
+```javascript
+function () {
+ $scope.promise = $timeout(function () {
+ // ...
+ }, 2000);
+}
+```
+
+### Table Toolbars
+
+Tables may be embedded within cards that offer navigation and data manipulation tools available at the top and bottom. You can use the `md-table-toolbar` and `md-default` class on a `md-toolbar` element for a plain white toolbar.
+
+If you need to display information relative to a particular column in the table you may use use a `<md-foot>` element. For example, say you had a `calories.total` property that summed the total number of calories and you wanted to display that information directly beneath the Calories column.
+
+```html
+<tfoot md-foot>
+ <tr md-row>
+ <td md-cell></td>
+ <td md-cell><strong>Total: </strong>{{calories.total}}</td>
+ <td md-cell colspan="6"></td>
+ </tr>
+</tfoot>
+```
+
+Observe that Calories is the second column in the table. Therefore, we need to offset the first column with an empty cell. If you need to offset many columns you can use `<td colspan="${n}"></td>` where `n` is the number of columns to offset.
+
+> You may need to manually correct the the text alignment and cell padding if you use `colspan`.
+
+## Contributing
+
+**Requires**
+
+* node
+* grunt-cli
+
+This repository contains a demo application for developing features. As you make changes the application will live reload itself.
+
+**Update**
+
+I noticed the nutrition app was an inconvenience for people trying to run the app locally and contribute. I have updated the demo application to remove the dependency for the nutrition app. This is also a good example of how you can take advantage of `ngRepeat` to easily achieve client side sorting and pagination.
+
+##### Running the App Locally
+
+Clone this repository to your local machine.
+
+```
+git clone https://github.com/daniel-nagy/md-data-table.git
+cd md-data-table
+```
+
+Create a new branch for the issue you are working on.
+
+```
+git checkout -b my-issue
+```
+
+Install the package dependencies.
+
+```
+npm install
+bower install
+```
+
+Run the application and visit `127.0.0.1:8000` in the browser.
+
+```
+grunt
+```
+
+Make your modifications and update the build.
+
+```
+grunt build
+```
+
+Create a pull request!
diff --git a/vnfmarket/common/thirdparty/angular-material-data-table/bower.json b/vnfmarket/common/thirdparty/angular-material-data-table/bower.json
new file mode 100644
index 00000000..f58ce2f8
--- /dev/null
+++ b/vnfmarket/common/thirdparty/angular-material-data-table/bower.json
@@ -0,0 +1,35 @@
+{
+ "name": "angular-material-data-table",
+ "version": "0.10.9",
+ "description": "Material Design data table.",
+ "main": [
+ "dist/md-data-table.js",
+ "dist/md-data-table.css"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/daniel-nagy/md-data-table.git"
+ },
+ "authors": [
+ "Daniel Nagy"
+ ],
+ "homepage": "http://danielnagy.me/md-data-table",
+ "license": "MIT",
+ "keywords": [
+ "material",
+ "table",
+ "md-data-table"
+ ],
+ "ignore": [
+ "**/.*",
+ "app",
+ "bower_components",
+ "node_modules",
+ "src",
+ "Gruntfile.js"
+ ],
+ "dependencies": {
+ "angular": "^1.4.0",
+ "angular-material": "^1.0.0"
+ }
+}
diff --git a/vnfmarket/common/thirdparty/angular-material-data-table/dist/md-data-table.css b/vnfmarket/common/thirdparty/angular-material-data-table/dist/md-data-table.css
new file mode 100644
index 00000000..b58df874
--- /dev/null
+++ b/vnfmarket/common/thirdparty/angular-material-data-table/dist/md-data-table.css
@@ -0,0 +1,394 @@
+md-backdrop.md-edit-dialog-backdrop {
+ z-index: 80;
+}
+md-edit-dialog {
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-direction: column;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ position: fixed;
+ z-index: 81;
+ background-color: #f9f9f9;
+ border-radius: 2px;
+ cursor: default;
+}
+md-edit-dialog > .md-content {
+ padding: 16px 24px 0;
+}
+md-edit-dialog > .md-content .md-title {
+ color: rgba(0, 0, 0, 0.87);
+ margin-bottom: 8px;
+}
+md-edit-dialog > .md-content md-input-container {
+ margin: 0;
+ font-size: 13px;
+}
+md-edit-dialog > .md-content md-input-container input {
+ float: none;
+}
+md-edit-dialog > .md-content md-input-container .md-errors-spacer {
+ min-height: auto;
+ min-width: auto;
+ color: rgba(0, 0, 0, 0.54);
+}
+md-edit-dialog > .md-content md-input-container .md-errors-spacer .md-char-counter {
+ padding: 5px 2px 5px 0;
+}
+md-edit-dialog > .md-content md-input-container [ng-message] {
+ padding: 5px 0 5px 2px;
+}
+md-edit-dialog > .md-actions {
+ margin: 0 16px 8px;
+}
+md-edit-dialog > .md-actions .md-button {
+ margin: 0;
+ min-width: initial;
+}
+md-edit-dialog > .md-actions .md-button + .md-button {
+ margin-left: 8px;
+}
+.md-table-pagination {
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-align-items: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-justify-content: flex-end;
+ -ms-flex-pack: end;
+ justify-content: flex-end;
+ -webkit-flex-wrap: wrap-reverse;
+ -ms-flex-wrap: wrap-reverse;
+ flex-wrap: wrap-reverse;
+ box-sizing: border-box;
+ padding: 0 24px;
+ font-size: 12px;
+ color: rgba(0, 0, 0, 0.54);
+ border-top: 1px rgba(0, 0, 0, 0.12) solid;
+}
+.md-table-pagination md-select {
+ -webkit-justify-content: flex-end;
+ -ms-flex-pack: end;
+ justify-content: flex-end;
+ min-width: 64px;
+}
+.md-table-pagination md-select:not([disabled]):focus .md-select-value {
+ color: rgba(0, 0, 0, 0.54);
+}
+.md-table-pagination md-select .md-select-value {
+ -webkit-flex: 0 0 auto;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+}
+.md-table-pagination md-select .md-select-value span.md-select-icon {
+ -webkit-justify-content: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ text-align: center;
+ margin-right: -6px !important;
+}
+.md-table-pagination md-select .md-select-value span.md-select-icon:after {
+ top: initial;
+ -webkit-transform: scaleY(0.5) scaleX(1);
+ transform: scaleY(0.5) scaleX(1);
+}
+.md-table-pagination > * {
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-align-items: center;
+ -ms-flex-align: center;
+ align-items: center;
+ height: 56px;
+}
+.md-table-pagination > .buttons:not(:first-child),
+.md-table-pagination > .limit-select:not(:first-child) {
+ margin-left: 32px;
+}
+.md-table-pagination > .buttons {
+ margin-right: -16px;
+}
+.md-table-pagination > .buttons > .md-button.md-icon-button {
+ margin: 0;
+}
+.md-table-pagination > .buttons > .label + .md-button.md-icon-button {
+ margin-left: 20px;
+}
+md-select.md-table-select {
+ margin: 0;
+}
+md-select.md-table-select > .md-select-value {
+ padding: 0;
+ min-width: 0;
+ min-height: 24px;
+ border-bottom: 0 !important;
+}
+md-select.md-table-select > .md-select-value > span {
+ display: block;
+ height: auto;
+ -webkit-transform: none !important;
+ transform: none !important;
+}
+md-select.md-table-select > .md-select-value > span > .md-text {
+ display: inherit;
+ height: inherit;
+ -webkit-transform: inherit;
+ transform: inherit;
+}
+md-select.md-table-select > .md-select-value > span.md-select-icon {
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-align-items: center;
+ -ms-flex-align: center;
+ align-items: center;
+ height: 24px;
+ margin: 0;
+}
+md-select.md-table-select > .md-select-value > span.md-select-icon:after {
+ top: initial;
+}
+.md-select-menu-container.md-table-select,
+.md-select-menu-container.md-pagination-select {
+ margin-left: -2px;
+ border-radius: 2px;
+}
+.md-select-menu-container.md-table-select md-select-menu,
+.md-select-menu-container.md-pagination-select md-select-menu,
+.md-select-menu-container.md-table-select md-content,
+.md-select-menu-container.md-pagination-select md-content {
+ border-radius: inherit;
+}
+.md-select-menu-container.md-table-select md-content,
+.md-select-menu-container.md-pagination-select md-content {
+ padding: 0;
+}
+.md-select-menu-container.md-table-select .md-text {
+ font-size: 13px;
+}
+.md-select-menu-container.md-pagination-select .md-text {
+ font-size: 12px;
+}
+md-toolbar.md-table-toolbar {
+ box-shadow: none;
+}
+md-toolbar.md-table-toolbar.md-default-theme:not(.md-menu-toolbar).md-default,
+md-toolbar.md-table-toolbar:not(.md-menu-toolbar).md-default {
+ background-color: #ffffff;
+ color: rgba(0, 0, 0, 0.87);
+}
+md-toolbar.md-table-toolbar.md-default-theme:not(.md-menu-toolbar).md-default .md-button,
+md-toolbar.md-table-toolbar:not(.md-menu-toolbar).md-default .md-button {
+ color: rgba(0, 0, 0, 0.87);
+}
+@media only screen and (max-width: 959px) and (min-width: 0) and (orientation: landscape) {
+ md-toolbar.md-table-toolbar .md-toolbar-tools {
+ height: 64px;
+ max-height: initial;
+ }
+}
+md-toolbar.md-table-toolbar .md-toolbar-tools {
+ padding: 0 24px;
+}
+md-toolbar.md-table-toolbar .md-toolbar-tools md-icon {
+ color: rgba(0, 0, 0, 0.54);
+}
+md-toolbar.md-table-toolbar .md-toolbar-tools > .md-button.md-icon-button {
+ margin: 0;
+}
+md-toolbar.md-table-toolbar .md-toolbar-tools > .md-button.md-icon-button:first-child {
+ margin-left: -12px;
+}
+md-toolbar.md-table-toolbar .md-toolbar-tools > .md-button.md-icon-button:last-child {
+ margin-right: -12px;
+}
+md-card > md-toolbar.md-table-toolbar:first-child,
+md-card > md-table-container:first-child {
+ border-top-left-radius: 2px;
+ border-top-right-radius: 2px;
+}
+md-card > md-toolbar.md-table-toolbar:last-child,
+md-card > md-table-container:last-child {
+ border-bottom-left-radius: 2px;
+ border-bottom-right-radius: 2px;
+}
+md-table-container {
+ display: block;
+ max-width: 100%;
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+}
+table.md-table {
+ width: 100%;
+ border-spacing: 0;
+ overflow: hidden;
+}
+table.md-table thead.md-head > tr.md-row {
+ height: 56px;
+}
+table.md-table tbody.md-body > tr.md-row,
+table.md-table tfoot.md-foot > tr.md-row {
+ height: 48px;
+}
+table.md-table thead.md-head + .md-table-progress md-progress-linear {
+ top: -3px;
+}
+table.md-table .md-table-progress th {
+ padding: 0;
+}
+table.md-table .md-table-progress th md-progress-linear {
+ height: 0;
+ transition: opacity 1s;
+}
+table.md-table .md-table-progress th md-progress-linear.ng-hide {
+ opacity: 0;
+}
+table.md-table .md-table-progress th md-progress-linear > .md-container {
+ height: 3px;
+ top: 0;
+ transition: none;
+}
+table.md-table .md-table-progress th md-progress-linear > .md-container > .md-bar {
+ height: 3px;
+}
+table.md-table th.md-column {
+ color: rgba(0, 0, 0, 0.54);
+ font-size: 12px;
+ font-weight: bold;
+ white-space: nowrap;
+}
+table.md-table th.md-column.md-sort {
+ cursor: pointer;
+}
+table.md-table th.md-column md-icon {
+ height: 16px;
+ width: 16px;
+ font-size: 16px !important;
+ line-height: 16px !important;
+}
+table.md-table th.md-column md-icon.md-sort-icon {
+ color: rgba(0, 0, 0, 0.26);
+ opacity: 0;
+ transition: -webkit-transform 0.25s, opacity 0.25s;
+ transition: transform 0.25s, opacity 0.25s;
+}
+table.md-table th.md-column md-icon.md-sort-icon.md-asc {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+}
+table.md-table th.md-column md-icon.md-sort-icon.md-desc {
+ -webkit-transform: rotate(180deg);
+ transform: rotate(180deg);
+}
+table.md-table th.md-column md-icon:not(:first-child) {
+ margin-left: 8px;
+}
+table.md-table th.md-column md-icon:not(:last-child) {
+ margin-right: 8px;
+}
+table.md-table th.md-column.md-active,
+table.md-table th.md-column.md-active md-icon {
+ color: rgba(0, 0, 0, 0.87);
+}
+table.md-table th.md-column:hover md-icon.md-sort-icon,
+table.md-table th.md-column.md-active md-icon.md-sort-icon {
+ opacity: 1;
+}
+table.md-table tr.md-row[ng\:repeat].ng-leave,
+table.md-table tr.md-row[ng-repeat].ng-leave,
+table.md-table tr.md-row[x-ng-repeat].ng-leave,
+table.md-table tr.md-row[data-ng-repeat].ng-leave {
+ display: none;
+}
+table.md-table.md-row-select tbody.md-body > tr.md-row {
+ transition: background-color 0.2s;
+}
+table.md-table.md-row-select tbody.md-body > tr.md-row:not([disabled]):hover {
+ background-color: #eeeeee !important;
+}
+table.md-table.md-row-select tbody.md-body > tr.md-row.md-selected {
+ background-color: #f5f5f5;
+}
+table.md-table.md-row-select td.md-cell:first-child,
+table.md-table.md-row-select th.md-column:first-child {
+ width: 20px;
+ padding: 0 0 0 24px;
+}
+table.md-table.md-row-select td.md-cell:nth-child(2),
+table.md-table.md-row-select th.md-column:nth-child(2) {
+ padding: 0 24px;
+}
+table.md-table.md-row-select td.md-cell:nth-child(n+3):nth-last-child(n+2),
+table.md-table.md-row-select th.md-column:nth-child(n+3):nth-last-child(n+2) {
+ padding: 0 56px 0 0;
+}
+table.md-table:not(.md-row-select) td.md-cell:first-child,
+table.md-table:not(.md-row-select) th.md-column:first-child {
+ padding: 0 24px;
+}
+table.md-table:not(.md-row-select) td.md-cell:nth-child(n+2):nth-last-child(n+2),
+table.md-table:not(.md-row-select) th.md-column:nth-child(n+2):nth-last-child(n+2) {
+ padding: 0 56px 0 0;
+}
+table.md-table td.md-cell,
+table.md-table th.md-column {
+ vertical-align: middle;
+ text-align: left;
+}
+table.md-table td.md-cell > *,
+table.md-table th.md-column > * {
+ vertical-align: middle;
+}
+table.md-table td.md-cell:last-child,
+table.md-table th.md-column:last-child {
+ padding: 0 24px 0 0;
+}
+table.md-table td.md-cell.md-clickable,
+table.md-table th.md-column.md-clickable {
+ cursor: pointer;
+}
+table.md-table td.md-cell.md-clickable:focus,
+table.md-table th.md-column.md-clickable:focus {
+ outline: none;
+}
+table.md-table td.md-cell.md-numeric,
+table.md-table th.md-column.md-numeric {
+ text-align: right;
+}
+table.md-table td.md-cell md-checkbox,
+table.md-table th.md-column md-checkbox {
+ margin: 0;
+ width: 20px;
+}
+table.md-table td.md-cell {
+ color: rgba(0, 0, 0, 0.87);
+ font-size: 13px;
+ border-top: 1px rgba(0, 0, 0, 0.12) solid;
+}
+table.md-table td.md-cell.md-numeric md-select {
+ -webkit-justify-content: flex-end;
+ -ms-flex-pack: end;
+ justify-content: flex-end;
+}
+table.md-table td.md-cell.md-numeric md-select .md-select-value {
+ -webkit-flex: 0 0 auto;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+}
+table.md-table td.md-cell.md-placeholder {
+ color: rgba(0, 0, 0, 0.26);
+}
+table.md-table td.md-cell md-select > .md-select-value > span.md-select-icon {
+ -webkit-justify-content: flex-end;
+ -ms-flex-pack: end;
+ justify-content: flex-end;
+ color: rgba(0, 0, 0, 0.54);
+ width: 18px;
+ text-align: right;
+}
+table.md-table td.md-cell md-select > .md-select-value > span.md-select-icon:after {
+ -webkit-transform: scaleY(0.4) scaleX(0.8);
+ transform: scaleY(0.4) scaleX(0.8);
+}
diff --git a/vnfmarket/common/thirdparty/angular-material-data-table/dist/md-data-table.js b/vnfmarket/common/thirdparty/angular-material-data-table/dist/md-data-table.js
new file mode 100644
index 00000000..8372a777
--- /dev/null
+++ b/vnfmarket/common/thirdparty/angular-material-data-table/dist/md-data-table.js
@@ -0,0 +1,1486 @@
+/*
+ * Angular Material Data Table
+ * https://github.com/daniel-nagy/md-data-table
+ * @license MIT
+ * v0.10.9
+ */
+(function (window, angular, undefined) {
+'use strict';
+
+angular.module('md.table.templates', ['md-table-pagination.html', 'md-table-progress.html', 'arrow-up.svg', 'navigate-before.svg', 'navigate-first.svg', 'navigate-last.svg', 'navigate-next.svg']);
+
+angular.module('md-table-pagination.html', []).run(['$templateCache', function($templateCache) {
+ $templateCache.put('md-table-pagination.html',
+ '<div class="page-select" ng-if="$pagination.showPageSelect()">\n' +
+ ' <div class="label">{{$pagination.label.page}}</div>\n' +
+ '\n' +
+ ' <md-select virtual-page-select total="{{$pagination.pages()}}" class="md-table-select" ng-model="$pagination.page" md-container-class="md-pagination-select" ng-change="$pagination.onPaginationChange()" ng-disabled="$pagination.disabled" aria-label="Page">\n' +
+ ' <md-content>\n' +
+ ' <md-option ng-repeat="page in $pageSelect.pages" ng-value="page">{{page}}</md-option>\n' +
+ ' </md-content>\n' +
+ ' </md-select>\n' +
+ '</div>\n' +
+ '\n' +
+ '<div class="limit-select" ng-if="$pagination.limitOptions">\n' +
+ ' <div class="label">{{$pagination.label.rowsPerPage}}</div>\n' +
+ '\n' +
+ ' <md-select class="md-table-select" ng-model="$pagination.limit" md-container-class="md-pagination-select" ng-disabled="$pagination.disabled" aria-label="Rows" placeholder="{{ $pagination.limitOptions[0] }}">\n' +
+ ' <md-option ng-repeat="option in $pagination.limitOptions" ng-value="option.value ? $pagination.eval(option.value) : option">{{::option.label ? option.label : option}}</md-option>\n' +
+ ' </md-select>\n' +
+ '</div>\n' +
+ '\n' +
+ '<div class="buttons">\n' +
+ ' <div class="label">{{$pagination.min()}} - {{$pagination.max()}} {{$pagination.label.of}} {{$pagination.total}}</div>\n' +
+ '\n' +
+ ' <md-button class="md-icon-button" type="button" ng-if="$pagination.showBoundaryLinks()" ng-click="$pagination.first()" ng-disabled="$pagination.disabled || !$pagination.hasPrevious()" aria-label="First">\n' +
+ ' <md-icon md-svg-icon="navigate-first.svg"></md-icon>\n' +
+ ' </md-button>\n' +
+ '\n' +
+ ' <md-button class="md-icon-button" type="button" ng-click="$pagination.previous()" ng-disabled="$pagination.disabled || !$pagination.hasPrevious()" aria-label="Previous">\n' +
+ ' <md-icon md-svg-icon="navigate-before.svg"></md-icon>\n' +
+ ' </md-button>\n' +
+ '\n' +
+ ' <md-button class="md-icon-button" type="button" ng-click="$pagination.next()" ng-disabled="$pagination.disabled || !$pagination.hasNext()" aria-label="Next">\n' +
+ ' <md-icon md-svg-icon="navigate-next.svg"></md-icon>\n' +
+ ' </md-button>\n' +
+ '\n' +
+ ' <md-button class="md-icon-button" type="button" ng-if="$pagination.showBoundaryLinks()" ng-click="$pagination.last()" ng-disabled="$pagination.disabled || !$pagination.hasNext()" aria-label="Last">\n' +
+ ' <md-icon md-svg-icon="navigate-last.svg"></md-icon>\n' +
+ ' </md-button>\n' +
+ '</div>');
+}]);
+
+angular.module('md-table-progress.html', []).run(['$templateCache', function($templateCache) {
+ $templateCache.put('md-table-progress.html',
+ '<tr>\n' +
+ ' <th colspan="{{columnCount()}}">\n' +
+ ' <md-progress-linear ng-show="deferred()" md-mode="indeterminate"></md-progress-linear>\n' +
+ ' </th>\n' +
+ '</tr>');
+}]);
+
+angular.module('arrow-up.svg', []).run(['$templateCache', function($templateCache) {
+ $templateCache.put('arrow-up.svg',
+ '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z"/></svg>');
+}]);
+
+angular.module('navigate-before.svg', []).run(['$templateCache', function($templateCache) {
+ $templateCache.put('navigate-before.svg',
+ '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/></svg>');
+}]);
+
+angular.module('navigate-first.svg', []).run(['$templateCache', function($templateCache) {
+ $templateCache.put('navigate-first.svg',
+ '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M7 6 v12 h2 v-12 h-2z M17.41 7.41L16 6l-6 6 6 6 1.41-1.41L12.83 12z"/></svg>');
+}]);
+
+angular.module('navigate-last.svg', []).run(['$templateCache', function($templateCache) {
+ $templateCache.put('navigate-last.svg',
+ '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M15 6 v12 h2 v-12 h-2z M8 6L6.59 7.41 11.17 12l-4.58 4.59L8 18l6-6z"/></svg>');
+}]);
+
+angular.module('navigate-next.svg', []).run(['$templateCache', function($templateCache) {
+ $templateCache.put('navigate-next.svg',
+ '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg>');
+}]);
+
+
+angular.module('md.data.table', ['md.table.templates']);
+
+angular.module('md.data.table').directive('mdBody', mdBody);
+
+function mdBody() {
+
+ function compile(tElement) {
+ tElement.addClass('md-body');
+ }
+
+ return {
+ compile: compile,
+ restrict: 'A'
+ };
+}
+
+angular.module('md.data.table').directive('mdCell', mdCell);
+
+function mdCell() {
+
+ function compile(tElement) {
+ var select = tElement.find('md-select');
+
+ if(select.length) {
+ select.addClass('md-table-select').attr('md-container-class', 'md-table-select');
+ }
+
+ tElement.addClass('md-cell');
+
+ return postLink;
+ }
+
+ // empty controller to be bind properties to in postLink function
+ function Controller() {
+
+ }
+
+ function postLink(scope, element, attrs, ctrls) {
+ var select = element.find('md-select');
+ var cellCtrl = ctrls.shift();
+ var tableCtrl = ctrls.shift();
+
+ if(attrs.ngClick) {
+ element.addClass('md-clickable');
+ }
+
+ if(select.length) {
+ select.on('click', function (event) {
+ event.stopPropagation();
+ });
+
+ element.addClass('md-clickable').on('click', function (event) {
+ event.stopPropagation();
+ select[0].click();
+ });
+ }
+
+ cellCtrl.getTable = tableCtrl.getElement;
+
+ function getColumn() {
+ return tableCtrl.$$columns[getIndex()];
+ }
+
+ function getIndex() {
+ return Array.prototype.indexOf.call(element.parent().children(), element[0]);
+ }
+
+ scope.$watch(getColumn, function (column) {
+ if(!column) {
+ return;
+ }
+
+ if(column.numeric) {
+ element.addClass('md-numeric');
+ } else {
+ element.removeClass('md-numeric');
+ }
+ });
+ }
+
+ return {
+ controller: Controller,
+ compile: compile,
+ require: ['mdCell', '^^mdTable'],
+ restrict: 'A'
+ };
+}
+
+angular.module('md.data.table').directive('mdColumn', mdColumn);
+
+function mdColumn($compile, $mdUtil) {
+
+ function compile(tElement) {
+ tElement.addClass('md-column');
+ return postLink;
+ }
+
+ function postLink(scope, element, attrs, ctrls) {
+ var headCtrl = ctrls.shift();
+ var tableCtrl = ctrls.shift();
+
+ function attachSortIcon() {
+ var sortIcon = angular.element('<md-icon md-svg-icon="arrow-up.svg">');
+
+ $compile(sortIcon.addClass('md-sort-icon').attr('ng-class', 'getDirection()'))(scope);
+
+ if(element.hasClass('md-numeric')) {
+ element.prepend(sortIcon);
+ } else {
+ element.append(sortIcon);
+ }
+ }
+
+ function detachSortIcon() {
+ Array.prototype.some.call(element.find('md-icon'), function (icon) {
+ return icon.classList.contains('md-sort-icon') && element[0].removeChild(icon);
+ });
+ }
+
+ function disableSorting() {
+ detachSortIcon();
+ element.removeClass('md-sort').off('click', setOrder);
+ }
+
+ function enableSorting() {
+ attachSortIcon();
+ element.addClass('md-sort').on('click', setOrder);
+ }
+
+ function getIndex() {
+ return Array.prototype.indexOf.call(element.parent().children(), element[0]);
+ }
+
+ function isActive() {
+ return scope.orderBy && (headCtrl.order === scope.orderBy || headCtrl.order === '-' + scope.orderBy);
+ }
+
+ function isNumeric() {
+ return attrs.mdNumeric === '' || scope.numeric;
+ }
+
+ function setOrder() {
+ scope.$applyAsync(function () {
+ if(isActive()) {
+ headCtrl.order = scope.getDirection() === 'md-asc' ? '-' + scope.orderBy : scope.orderBy;
+ } else {
+ headCtrl.order = scope.getDirection() === 'md-asc' ? scope.orderBy : '-' + scope.orderBy;
+ }
+
+ if(angular.isFunction(headCtrl.onReorder)) {
+ $mdUtil.nextTick(function () {
+ headCtrl.onReorder(headCtrl.order);
+ });
+ }
+ });
+ }
+
+ function updateColumn(index, column) {
+ tableCtrl.$$columns[index] = column;
+
+ if(column.numeric) {
+ element.addClass('md-numeric');
+ } else {
+ element.removeClass('md-numeric');
+ }
+ }
+
+ scope.getDirection = function () {
+ if(isActive()) {
+ return headCtrl.order.charAt(0) === '-' ? 'md-desc' : 'md-asc';
+ }
+
+ return attrs.mdDesc === '' || scope.$eval(attrs.mdDesc) ? 'md-desc' : 'md-asc';
+ };
+
+ scope.$watch(isActive, function (active) {
+ if(active) {
+ element.addClass('md-active');
+ } else {
+ element.removeClass('md-active');
+ }
+ });
+
+ scope.$watch(getIndex, function (index) {
+ updateColumn(index, {'numeric': isNumeric()});
+ });
+
+ scope.$watch(isNumeric, function (numeric) {
+ updateColumn(getIndex(), {'numeric': numeric});
+ });
+
+ scope.$watch('orderBy', function (orderBy) {
+ if(orderBy) {
+ if(!element.hasClass('md-sort')) {
+ enableSorting();
+ }
+ } else if(element.hasClass('md-sort')) {
+ disableSorting();
+ }
+ });
+ }
+
+ return {
+ compile: compile,
+ require: ['^^mdHead', '^^mdTable'],
+ restrict: 'A',
+ scope: {
+ numeric: '=?mdNumeric',
+ orderBy: '@?mdOrderBy'
+ }
+ };
+}
+
+mdColumn.$inject = ['$compile', '$mdUtil'];
+
+angular.module('md.data.table')
+ .decorator('$controller', controllerDecorator)
+ .factory('$mdEditDialog', mdEditDialog);
+
+/*
+ * A decorator for ng.$controller to optionally bind properties to the
+ * controller before invoking the constructor. Stolen from the ngMock.
+ *
+ * https://docs.angularjs.org/api/ngMock/service/$controller
+ */
+function controllerDecorator($delegate) {
+ return function(expression, locals, later, ident) {
+ if(later && typeof later === 'object') {
+ var create = $delegate(expression, locals, true, ident);
+ angular.extend(create.instance, later);
+ return create();
+ }
+ return $delegate(expression, locals, later, ident);
+ };
+}
+
+controllerDecorator.$inject = ['$delegate'];
+
+function mdEditDialog($compile, $controller, $document, $mdUtil, $q, $rootScope, $templateCache, $templateRequest, $window) {
+ /* jshint validthis: true */
+
+ var ESCAPE = 27;
+
+ var busy = false;
+ var body = angular.element($document.prop('body'));
+
+ /*
+ * bindToController
+ * controller
+ * controllerAs
+ * locals
+ * resolve
+ * scope
+ * targetEvent
+ * template
+ * templateUrl
+ */
+ var defaultOptions = {
+ clickOutsideToClose: true,
+ disableScroll: true,
+ escToClose: true,
+ focusOnOpen: true
+ };
+
+ function build(template, options) {
+ var scope = $rootScope.$new();
+ var element = $compile(template)(scope);
+ var backdrop = $mdUtil.createBackdrop(scope, 'md-edit-dialog-backdrop');
+ var controller;
+
+ if(options.controller) {
+ controller = getController(options, scope, {$element: element, $scope: scope});
+ } else {
+ angular.extend(scope, options.scope);
+ }
+
+ if(options.disableScroll) {
+ disableScroll(element);
+ }
+
+ body.prepend(backdrop).append(element.addClass('md-whiteframe-1dp'));
+
+ positionDialog(element, options.target);
+
+ if(options.focusOnOpen) {
+ focusOnOpen(element);
+ }
+
+ if(options.clickOutsideToClose) {
+ backdrop.on('click', function () {
+ element.remove();
+ });
+ }
+
+ if(options.escToClose) {
+ escToClose(element);
+ }
+
+ element.on('$destroy', function () {
+ busy = false;
+ backdrop.remove();
+ });
+
+ return controller;
+ }
+
+ function disableScroll(element) {
+ var restoreScroll = $mdUtil.disableScrollAround(element, body);
+
+ element.on('$destroy', function () {
+ restoreScroll();
+ });
+ }
+
+ function getController(options, scope, inject) {
+ if(!options.controller) {
+ return;
+ }
+
+ if(options.resolve) {
+ angular.extend(inject, options.resolve);
+ }
+
+ if(options.locals) {
+ angular.extend(inject, options.locals);
+ }
+
+ if(options.controllerAs) {
+ scope[options.controllerAs] = {};
+
+ if(options.bindToController) {
+ angular.extend(scope[options.controllerAs], options.scope);
+ } else {
+ angular.extend(scope, options.scope);
+ }
+ } else {
+ angular.extend(scope, options.scope);
+ }
+
+ if(options.bindToController) {
+ return $controller(options.controller, inject, scope[options.controllerAs]);
+ } else {
+ return $controller(options.controller, inject);
+ }
+ }
+
+ function getTemplate(options) {
+ return $q(function (resolve, reject) {
+ var template = options.template;
+
+ function illegalType(type) {
+ reject('Unexpected template value. Expected a string; received a ' + type + '.');
+ }
+
+ if(template) {
+ return angular.isString(template) ? resolve(template) : illegalType(typeof template);
+ }
+
+ if(options.templateUrl) {
+ template = $templateCache.get(options.templateUrl);
+
+ if(template) {
+ return resolve(template);
+ }
+
+ var success = function (template) {
+ return resolve(template);
+ };
+
+ var error = function () {
+ return reject('Error retrieving template from URL.');
+ };
+
+ return $templateRequest(options.templateUrl).then(success, error);
+ }
+
+ reject('Template not provided.');
+ });
+ }
+
+ function logError(error) {
+ busy = false;
+ console.error(error);
+ }
+
+ function escToClose(element) {
+ var keyup = function (event) {
+ if(event.keyCode === ESCAPE) {
+ element.remove();
+ }
+ };
+
+ body.on('keyup', keyup);
+
+ element.on('$destroy', function () {
+ body.off('keyup', keyup);
+ });
+ }
+
+ function focusOnOpen(element) {
+ $mdUtil.nextTick(function () {
+ var autofocus = $mdUtil.findFocusTarget(element);
+
+ if(autofocus) {
+ autofocus.focus();
+ }
+ }, false);
+ }
+
+ function positionDialog(element, target) {
+ var table = angular.element(target).controller('mdCell').getTable();
+
+ var getHeight = function () {
+ return element.prop('clientHeight');
+ };
+
+ var getSize = function () {
+ return {
+ width: getWidth(),
+ height: getHeight()
+ };
+ };
+
+ var getTableBounds = function () {
+ var parent = table.parent();
+
+ if(parent.prop('tagName') === 'MD-TABLE-CONTAINER') {
+ return parent[0].getBoundingClientRect();
+ } else {
+ return table[0].getBoundingClientRect();
+ }
+ };
+
+ var getWidth = function () {
+ return element.prop('clientWidth');
+ };
+
+ var reposition = function () {
+ var size = getSize();
+ var cellBounds = target.getBoundingClientRect();
+ var tableBounds = getTableBounds();
+
+ if(size.width > tableBounds.right - cellBounds.left) {
+ element.css('left', tableBounds.right - size.width + 'px');
+ } else {
+ element.css('left', cellBounds.left + 'px');
+ }
+
+ if(size.height > tableBounds.bottom - cellBounds.top) {
+ element.css('top', tableBounds.bottom - size.height + 'px');
+ } else {
+ element.css('top', cellBounds.top + 1 + 'px');
+ }
+
+ element.css('minWidth', cellBounds.width + 'px');
+ };
+
+ var watchWidth = $rootScope.$watch(getWidth, reposition);
+ var watchHeight = $rootScope.$watch(getHeight, reposition);
+
+ $window.addEventListener('resize', reposition);
+
+ element.on('$destroy', function () {
+ watchWidth();
+ watchHeight();
+
+ $window.removeEventListener('resize', reposition);
+ });
+ }
+
+ function preset(size, options) {
+
+ function getAttrs() {
+ var attrs = 'type="' + (options.type || 'text') + '"';
+
+ for(var attr in options.validators) {
+ attrs += ' ' + attr + '="' + options.validators[attr] + '"';
+ }
+
+ return attrs;
+ }
+
+ return {
+ controller: ['$element', '$q', 'save', '$scope', function ($element, $q, save, $scope) {
+ function update() {
+ if($scope.editDialog.$invalid) {
+ return $q.reject();
+ }
+
+ if(angular.isFunction(save)) {
+ return $q.when(save($scope.editDialog.input));
+ }
+
+ return $q.resolve();
+ }
+
+ this.dismiss = function () {
+ $element.remove();
+ };
+
+ this.getInput = function () {
+ return $scope.editDialog.input;
+ };
+
+ $scope.dismiss = this.dismiss;
+
+ $scope.submit = function () {
+ update().then(function () {
+ $scope.dismiss();
+ });
+ };
+ }],
+ locals: {
+ save: options.save
+ },
+ scope: {
+ cancel: options.cancel || 'Cancel',
+ messages: options.messages,
+ model: options.modelValue,
+ ok: options.ok || 'Save',
+ placeholder: options.placeholder,
+ title: options.title,
+ size: size
+ },
+ template:
+ '<md-edit-dialog>' +
+ '<div layout="column" class="md-content">' +
+ '<div ng-if="size === \'large\'" class="md-title">{{title || \'Edit\'}}</div>' +
+ '<form name="editDialog" layout="column" ng-submit="submit(model)">' +
+ '<md-input-container md-no-float>' +
+ '<input name="input" ng-model="model" md-autofocus placeholder="{{placeholder}} "' + getAttrs() + '>' +
+ '<div ng-messages="editDialog.input.$error">' +
+ '<div ng-repeat="(key, message) in messages" ng-message="{{key}}">{{message}}</div>' +
+ '</div>' +
+ '</md-input-container>' +
+ '</form>' +
+ '</div>' +
+ '<div ng-if="size === \'large\'" layout="row" layout-align="end" class="md-actions">' +
+ '<md-button class="md-primary" ng-click="dismiss()">{{cancel}}</md-button>' +
+ '<md-button class="md-primary" ng-click="submit()">{{ok}}</md-button>' +
+ '</div>' +
+ '</md-edit-dialog>'
+ };
+ }
+
+ this.show = function (options) {
+ if(busy) {
+ return $q.reject();
+ }
+
+ busy = true;
+ options = angular.extend({}, defaultOptions, options);
+
+ if(!options.targetEvent) {
+ return logError('options.targetEvent is required to align the dialog with the table cell.');
+ }
+
+ if(!options.targetEvent.currentTarget.classList.contains('md-cell')) {
+ return logError('The event target must be a table cell.');
+ }
+
+ if(options.bindToController && !options.controllerAs) {
+ return logError('You must define options.controllerAs when options.bindToController is true.');
+ }
+
+ options.target = options.targetEvent.currentTarget;
+
+ var promise = getTemplate(options);
+ var promises = [promise];
+
+ for(var prop in options.resolve) {
+ promise = options.resolve[prop];
+ promises.push($q.when(angular.isFunction(promise) ? promise() : promise));
+ }
+
+ promise = $q.all(promises);
+
+ promise['catch'](logError);
+
+ return promise.then(function (results) {
+ var template = results.shift();
+
+ for(var prop in options.resolve) {
+ options.resolve[prop] = results.shift();
+ }
+
+ return build(template, options);
+ });
+ };
+
+ this.small = function (options) {
+ return this.show(angular.extend({}, options, preset('small', options)));
+ }.bind(this);
+
+ this.large = function (options) {
+ return this.show(angular.extend({}, options, preset('large', options)));
+ }.bind(this);
+
+ return this;
+}
+
+mdEditDialog.$inject = ['$compile', '$controller', '$document', '$mdUtil', '$q', '$rootScope', '$templateCache', '$templateRequest', '$window'];
+
+
+angular.module('md.data.table').directive('mdFoot', mdFoot);
+
+function mdFoot() {
+
+ function compile(tElement) {
+ tElement.addClass('md-foot');
+ }
+
+ return {
+ compile: compile,
+ restrict: 'A'
+ };
+}
+
+angular.module('md.data.table').directive('mdHead', mdHead);
+
+function mdHead($compile) {
+
+ function compile(tElement) {
+ tElement.addClass('md-head');
+ return postLink;
+ }
+
+ // empty controller to be bind scope properties to
+ function Controller() {
+
+ }
+
+ function postLink(scope, element, attrs, tableCtrl) {
+ // because scope.$watch is unpredictable
+ var oldValue = new Array(2);
+
+ function addCheckboxColumn() {
+ element.children().prepend('<th class="md-column md-checkbox-column">');
+ }
+
+ function attatchCheckbox() {
+ element.prop('lastElementChild').firstElementChild.appendChild($compile(createCheckBox())(scope)[0]);
+ }
+
+ function createCheckBox() {
+ return angular.element('<md-checkbox>').attr({
+ 'aria-label': 'Select All',
+ 'ng-click': 'toggleAll()',
+ 'ng-checked': 'allSelected()',
+ 'ng-disabled': '!getSelectableRows().length'
+ });
+ }
+
+ function detachCheckbox() {
+ var cell = element.prop('lastElementChild').firstElementChild;
+
+ if(cell.classList.contains('md-checkbox-column')) {
+ angular.element(cell).empty();
+ }
+ }
+
+ function enableRowSelection() {
+ return tableCtrl.$$rowSelect;
+ }
+
+ function mdSelectCtrl(row) {
+ return angular.element(row).controller('mdSelect');
+ }
+
+ function removeCheckboxColumn() {
+ Array.prototype.some.call(element.find('th'), function (cell) {
+ return cell.classList.contains('md-checkbox-column') && cell.remove();
+ });
+ }
+
+ scope.allSelected = function () {
+ var rows = scope.getSelectableRows();
+
+ return rows.length && rows.every(function (row) {
+ return row.isSelected();
+ });
+ };
+
+ scope.getSelectableRows = function () {
+ return tableCtrl.getBodyRows().map(mdSelectCtrl).filter(function (ctrl) {
+ return ctrl && !ctrl.disabled;
+ });
+ };
+
+ scope.selectAll = function () {
+ tableCtrl.getBodyRows().map(mdSelectCtrl).forEach(function (ctrl) {
+ if(ctrl && !ctrl.isSelected()) {
+ ctrl.select();
+ }
+ });
+ };
+
+ scope.toggleAll = function () {
+ return scope.allSelected() ? scope.unSelectAll() : scope.selectAll();
+ };
+
+ scope.unSelectAll = function () {
+ tableCtrl.getBodyRows().map(mdSelectCtrl).forEach(function (ctrl) {
+ if(ctrl && ctrl.isSelected()) {
+ ctrl.deselect();
+ }
+ });
+ };
+
+ scope.$watchGroup([enableRowSelection, tableCtrl.enableMultiSelect], function (newValue) {
+ if(newValue[0] !== oldValue[0]) {
+ if(newValue[0]) {
+ addCheckboxColumn();
+
+ if(newValue[1]) {
+ attatchCheckbox();
+ }
+ } else {
+ removeCheckboxColumn();
+ }
+ } else if(newValue[0] && newValue[1] !== oldValue[1]) {
+ if(newValue[1]) {
+ attatchCheckbox();
+ } else {
+ detachCheckbox();
+ }
+ }
+
+ angular.copy(newValue, oldValue);
+ });
+ }
+
+ return {
+ bindToController: true,
+ compile: compile,
+ controller: Controller,
+ controllerAs: '$mdHead',
+ require: '^^mdTable',
+ restrict: 'A',
+ scope: {
+ order: '=?mdOrder',
+ onReorder: '=?mdOnReorder'
+ }
+ };
+}
+
+mdHead.$inject = ['$compile'];
+
+angular.module('md.data.table').directive('mdRow', mdRow);
+
+function mdRow() {
+
+ function compile(tElement) {
+ tElement.addClass('md-row');
+ return postLink;
+ }
+
+ function postLink(scope, element, attrs, tableCtrl) {
+ function enableRowSelection() {
+ return tableCtrl.$$rowSelect;
+ }
+
+ function isBodyRow() {
+ return tableCtrl.getBodyRows().indexOf(element[0]) !== -1;
+ }
+
+ function isChild(node) {
+ return element[0].contains(node[0]);
+ }
+
+ if(isBodyRow()) {
+ var cell = angular.element('<td class="md-cell">');
+
+ scope.$watch(enableRowSelection, function (enable) {
+ // if a row is not selectable, prepend an empty cell to it
+ if(enable && !attrs.mdSelect) {
+ if(!isChild(cell)) {
+ element.prepend(cell);
+ }
+ return;
+ }
+
+ if(isChild(cell)) {
+ cell.remove();
+ }
+ });
+ }
+ }
+
+ return {
+ compile: compile,
+ require: '^^mdTable',
+ restrict: 'A'
+ };
+}
+
+angular.module('md.data.table').directive('mdSelect', mdSelect);
+
+function mdSelect($compile, $parse) {
+
+ // empty controller to bind scope properties to
+ function Controller() {
+
+ }
+
+ function postLink(scope, element, attrs, ctrls) {
+ var self = ctrls.shift();
+ var tableCtrl = ctrls.shift();
+ var getId = $parse(attrs.mdSelectId);
+
+ self.id = getId(self.model);
+
+ if(tableCtrl.$$rowSelect && self.id) {
+ if(tableCtrl.$$hash.has(self.id)) {
+ var index = tableCtrl.selected.indexOf(tableCtrl.$$hash.get(self.id));
+
+ // if the item is no longer selected remove it
+ if(index === -1) {
+ tableCtrl.$$hash.purge(self.id);
+ }
+
+ // if the item is not a reference to the current model update the reference
+ else if(!tableCtrl.$$hash.equals(self.id, self.model)) {
+ tableCtrl.$$hash.update(self.id, self.model);
+ tableCtrl.selected.splice(index, 1, self.model);
+ }
+
+ } else {
+
+ // check if the item has been selected
+ tableCtrl.selected.some(function (item, index) {
+ if(getId(item) === self.id) {
+ tableCtrl.$$hash.update(self.id, self.model);
+ tableCtrl.selected.splice(index, 1, self.model);
+
+ return true;
+ }
+ });
+ }
+ }
+
+ self.isSelected = function () {
+ if(!tableCtrl.$$rowSelect) {
+ return false;
+ }
+
+ if(self.id) {
+ return tableCtrl.$$hash.has(self.id);
+ }
+
+ return tableCtrl.selected.indexOf(self.model) !== -1;
+ };
+
+ self.select = function () {
+ if(self.disabled) {
+ return;
+ }
+
+ if(tableCtrl.enableMultiSelect()) {
+ tableCtrl.selected.push(self.model);
+ } else {
+ tableCtrl.selected.splice(0, tableCtrl.selected.length, self.model);
+ }
+
+ if(angular.isFunction(self.onSelect)) {
+ self.onSelect(self.model);
+ }
+ };
+
+ self.deselect = function () {
+ if(self.disabled) {
+ return;
+ }
+
+ tableCtrl.selected.splice(tableCtrl.selected.indexOf(self.model), 1);
+
+ if(angular.isFunction(self.onDeselect)) {
+ self.onDeselect(self.model);
+ }
+ };
+
+ self.toggle = function (event) {
+ if(event && event.stopPropagation) {
+ event.stopPropagation();
+ }
+
+ return self.isSelected() ? self.deselect() : self.select();
+ };
+
+ function autoSelect() {
+ return attrs.mdAutoSelect === '' || self.autoSelect;
+ }
+
+ function createCheckbox() {
+ var checkbox = angular.element('<md-checkbox>').attr({
+ 'aria-label': 'Select Row',
+ 'ng-click': '$mdSelect.toggle($event)',
+ 'ng-checked': '$mdSelect.isSelected()',
+ 'ng-disabled': '$mdSelect.disabled'
+ });
+
+ return angular.element('<td class="md-cell md-checkbox-cell">').append($compile(checkbox)(scope));
+ }
+
+ function disableSelection() {
+ Array.prototype.some.call(element.children(), function (child) {
+ return child.classList.contains('md-checkbox-cell') && element[0].removeChild(child);
+ });
+
+ if(autoSelect()) {
+ element.off('click', toggle);
+ }
+ }
+
+ function enableSelection() {
+ element.prepend(createCheckbox());
+
+ if(autoSelect()) {
+ element.on('click', toggle);
+ }
+ }
+
+ function enableRowSelection() {
+ return tableCtrl.$$rowSelect;
+ }
+
+ function onSelectChange(selected) {
+ if(!self.id) {
+ return;
+ }
+
+ if(tableCtrl.$$hash.has(self.id)) {
+ // check if the item has been deselected
+ if(selected.indexOf(tableCtrl.$$hash.get(self.id)) === -1) {
+ tableCtrl.$$hash.purge(self.id);
+ }
+
+ return;
+ }
+
+ // check if the item has been selected
+ if(selected.indexOf(self.model) !== -1) {
+ tableCtrl.$$hash.update(self.id, self.model);
+ }
+ }
+
+ function toggle(event) {
+ scope.$applyAsync(function () {
+ self.toggle(event);
+ });
+ }
+
+ scope.$watch(enableRowSelection, function (enable) {
+ if(enable) {
+ enableSelection();
+ } else {
+ disableSelection();
+ }
+ });
+
+ scope.$watch(autoSelect, function (newValue, oldValue) {
+ if(newValue === oldValue) {
+ return;
+ }
+
+ if(tableCtrl.$$rowSelect && newValue) {
+ element.on('click', toggle);
+ } else {
+ element.off('click', toggle);
+ }
+ });
+
+ scope.$watch(self.isSelected, function (isSelected) {
+ return isSelected ? element.addClass('md-selected') : element.removeClass('md-selected');
+ });
+
+ scope.$watch(tableCtrl.enableMultiSelect, function (multiple) {
+ if(tableCtrl.$$rowSelect && !multiple) {
+ // remove all but the first selected item
+ tableCtrl.selected.splice(1);
+ }
+ });
+
+ tableCtrl.registerModelChangeListener(onSelectChange);
+
+ element.on('$destroy', function () {
+ tableCtrl.removeModelChangeListener(onSelectChange);
+ });
+ }
+
+ return {
+ bindToController: true,
+ controller: Controller,
+ controllerAs: '$mdSelect',
+ link: postLink,
+ require: ['mdSelect', '^^mdTable'],
+ restrict: 'A',
+ scope: {
+ model: '=mdSelect',
+ disabled: '=ngDisabled',
+ onSelect: '=?mdOnSelect',
+ onDeselect: '=?mdOnDeselect',
+ autoSelect: '=mdAutoSelect'
+ }
+ };
+}
+
+mdSelect.$inject = ['$compile', '$parse'];
+
+angular.module('md.data.table').directive('mdTable', mdTable);
+
+function Hash() {
+ var keys = {};
+
+ this.equals = function (key, item) {
+ return keys[key] === item;
+ };
+
+ this.get = function (key) {
+ return keys[key];
+ };
+
+ this.has = function (key) {
+ return keys.hasOwnProperty(key);
+ };
+
+ this.purge = function (key) {
+ delete keys[key];
+ };
+
+ this.update = function (key, item) {
+ keys[key] = item;
+ };
+}
+
+function mdTable() {
+
+ function compile(tElement, tAttrs) {
+ tElement.addClass('md-table');
+
+ if(tAttrs.hasOwnProperty('mdProgress')) {
+ var body = tElement.find('tbody')[0];
+ var progress = angular.element('<thead class="md-table-progress" md-table-progress>');
+
+ if(body) {
+ tElement[0].insertBefore(progress[0], body);
+ }
+ }
+ }
+
+ function Controller($attrs, $element, $q, $scope) {
+ var self = this;
+ var queue = [];
+ var watchListener;
+ var modelChangeListeners = [];
+
+ self.$$hash = new Hash();
+ self.$$columns = {};
+
+ function enableRowSelection() {
+ self.$$rowSelect = true;
+
+ watchListener = $scope.$watchCollection('$mdTable.selected', function (selected) {
+ modelChangeListeners.forEach(function (listener) {
+ listener(selected);
+ });
+ });
+
+ $element.addClass('md-row-select');
+ }
+
+ function disableRowSelection() {
+ self.$$rowSelect = false;
+
+ if(angular.isFunction(watchListener)) {
+ watchListener();
+ }
+
+ $element.removeClass('md-row-select');
+ }
+
+ function resolvePromises() {
+ if(!queue.length) {
+ return $scope.$applyAsync();
+ }
+
+ queue[0]['finally'](function () {
+ queue.shift();
+ resolvePromises();
+ });
+ }
+
+ function rowSelect() {
+ return $attrs.mdRowSelect === '' || self.rowSelect;
+ }
+
+ function validateModel() {
+ if(!self.selected) {
+ return console.error('Row selection: ngModel is not defined.');
+ }
+
+ if(!angular.isArray(self.selected)) {
+ return console.error('Row selection: Expected an array. Recived ' + typeof self.selected + '.');
+ }
+
+ return true;
+ }
+
+ self.columnCount = function () {
+ return self.getRows($element[0]).reduce(function (count, row) {
+ return row.cells.length > count ? row.cells.length : count;
+ }, 0);
+ };
+
+ self.getRows = function (element) {
+ return Array.prototype.filter.call(element.rows, function (row) {
+ return !row.classList.contains('ng-leave');
+ });
+ };
+
+ self.getBodyRows = function () {
+ return Array.prototype.reduce.call($element.prop('tBodies'), function (result, tbody) {
+ return result.concat(self.getRows(tbody));
+ }, []);
+ };
+
+ self.getElement = function () {
+ return $element;
+ };
+
+ self.getHeaderRows = function () {
+ return self.getRows($element.prop('tHead'));
+ };
+
+ self.enableMultiSelect = function () {
+ return $attrs.multiple === '' || $scope.$eval($attrs.multiple);
+ };
+
+ self.waitingOnPromise = function () {
+ return !!queue.length;
+ };
+
+ self.queuePromise = function (promise) {
+ if(!promise) {
+ return;
+ }
+
+ if(queue.push(angular.isArray(promise) ? $q.all(promise) : $q.when(promise)) === 1) {
+ resolvePromises();
+ }
+ };
+
+ self.registerModelChangeListener = function (listener) {
+ modelChangeListeners.push(listener);
+ };
+
+ self.removeModelChangeListener = function (listener) {
+ var index = modelChangeListeners.indexOf(listener);
+
+ if(index !== -1) {
+ modelChangeListeners.splice(index, 1);
+ }
+ };
+
+ if($attrs.hasOwnProperty('mdProgress')) {
+ $scope.$watch('$mdTable.progress', self.queuePromise);
+ }
+
+ $scope.$watch(rowSelect, function (enable) {
+ if(enable && !!validateModel()) {
+ enableRowSelection();
+ } else {
+ disableRowSelection();
+ }
+ });
+ }
+
+ Controller.$inject = ['$attrs', '$element', '$q', '$scope'];
+
+ return {
+ bindToController: true,
+ compile: compile,
+ controller: Controller,
+ controllerAs: '$mdTable',
+ restrict: 'A',
+ scope: {
+ progress: '=?mdProgress',
+ selected: '=ngModel',
+ rowSelect: '=mdRowSelect'
+ }
+ };
+}
+
+angular.module('md.data.table').directive('mdTablePagination', mdTablePagination);
+
+function mdTablePagination() {
+
+ function compile(tElement) {
+ tElement.addClass('md-table-pagination');
+ }
+
+ function Controller($attrs, $mdUtil, $scope) {
+ var self = this;
+ var defaultLabel = {
+ page: 'Page:',
+ rowsPerPage: 'Rows per page:',
+ of: 'of'
+ };
+
+ self.label = angular.copy(defaultLabel);
+
+ function isPositive(number) {
+ return parseInt(number, 10) > 0;
+ }
+
+ self.eval = function (expression) {
+ return $scope.$eval(expression);
+ };
+
+ self.first = function () {
+ self.page = 1;
+ self.onPaginationChange();
+ };
+
+ self.hasNext = function () {
+ return self.page * self.limit < self.total;
+ };
+
+ self.hasPrevious = function () {
+ return self.page > 1;
+ };
+
+ self.last = function () {
+ self.page = self.pages();
+ self.onPaginationChange();
+ };
+
+ self.max = function () {
+ return self.hasNext() ? self.page * self.limit : self.total;
+ };
+
+ self.min = function () {
+ return isPositive(self.total) ? self.page * self.limit - self.limit + 1 : 0;
+ };
+
+ self.next = function () {
+ self.page++;
+ self.onPaginationChange();
+ };
+
+ self.onPaginationChange = function () {
+ if(angular.isFunction(self.onPaginate)) {
+ $mdUtil.nextTick(function () {
+ self.onPaginate(self.page, self.limit);
+ });
+ }
+ };
+
+ self.pages = function () {
+ return isPositive(self.total) ? Math.ceil(self.total / (isPositive(self.limit) ? self.limit : 1)) : 1;
+ };
+
+ self.previous = function () {
+ self.page--;
+ self.onPaginationChange();
+ };
+
+ self.showBoundaryLinks = function () {
+ return $attrs.mdBoundaryLinks === '' || self.boundaryLinks;
+ };
+
+ self.showPageSelect = function () {
+ return $attrs.mdPageSelect === '' || self.pageSelect;
+ };
+
+ $scope.$watch('$pagination.limit', function (newValue, oldValue) {
+ if(isNaN(newValue) || isNaN(oldValue) || newValue === oldValue) {
+ return;
+ }
+
+ // find closest page from previous min
+ self.page = Math.floor(((self.page * oldValue - oldValue) + newValue) / (isPositive(newValue) ? newValue : 1));
+ self.onPaginationChange();
+ });
+
+ $attrs.$observe('mdLabel', function (label) {
+ angular.extend(self.label, defaultLabel, $scope.$eval(label));
+ });
+
+ $scope.$watch('$pagination.total', function (newValue, oldValue) {
+ if(isNaN(newValue) || newValue === oldValue) {
+ return;
+ }
+
+ if(self.page > self.pages()) {
+ self.last();
+ }
+ });
+ }
+
+ Controller.$inject = ['$attrs', '$mdUtil', '$scope'];
+
+ return {
+ bindToController: {
+ boundaryLinks: '=?mdBoundaryLinks',
+ disabled: '=ngDisabled',
+ limit: '=mdLimit',
+ page: '=mdPage',
+ pageSelect: '=?mdPageSelect',
+ onPaginate: '=?mdOnPaginate',
+ limitOptions: '=?mdLimitOptions',
+ total: '@mdTotal'
+ },
+ compile: compile,
+ controller: Controller,
+ controllerAs: '$pagination',
+ restrict: 'E',
+ scope: {},
+ templateUrl: 'md-table-pagination.html'
+ };
+}
+
+angular.module('md.data.table').directive('mdTableProgress', mdTableProgress);
+
+function mdTableProgress() {
+
+ function postLink(scope, element, attrs, tableCtrl) {
+ scope.columnCount = tableCtrl.columnCount;
+ scope.deferred = tableCtrl.waitingOnPromise;
+ }
+
+ return {
+ link: postLink,
+ require: '^^mdTable',
+ restrict: 'A',
+ scope: {},
+ templateUrl: 'md-table-progress.html'
+ };
+}
+
+angular.module('md.data.table').directive('virtualPageSelect', virtualPageSelect);
+
+function virtualPageSelect() {
+
+ function Controller($element, $scope) {
+ var self = this;
+ var content = $element.find('md-content');
+
+ self.pages = [];
+
+ function getMin(pages, total) {
+ return Math.min(pages, isFinite(total) && isPositive(total) ? total : 1);
+ }
+
+ function isPositive(number) {
+ return number > 0;
+ }
+
+ function setPages(max) {
+ if(self.pages.length > max) {
+ return self.pages.splice(max);
+ }
+
+ for(var i = self.pages.length; i < max; i++) {
+ self.pages.push(i + 1);
+ }
+ }
+
+ content.on('scroll', function () {
+ if((content.prop('clientHeight') + content.prop('scrollTop')) >= content.prop('scrollHeight')) {
+ $scope.$applyAsync(function () {
+ setPages(getMin(self.pages.length + 10, self.total));
+ });
+ }
+ });
+
+ $scope.$watch('$pageSelect.total', function (total) {
+ setPages(getMin(Math.max(self.pages.length, 10), total));
+ });
+
+ $scope.$watch('$pagination.page', function (page) {
+ for(var i = self.pages.length; i < page; i++) {
+ self.pages.push(i + 1);
+ }
+ });
+ }
+
+ Controller.$inject = ['$element', '$scope'];
+
+ return {
+ bindToController: {
+ total: '@'
+ },
+ controller: Controller,
+ controllerAs: '$pageSelect'
+ };
+}
+
+})(window, angular); \ No newline at end of file
diff --git a/vnfmarket/common/thirdparty/angular-material-data-table/dist/md-data-table.min.css b/vnfmarket/common/thirdparty/angular-material-data-table/dist/md-data-table.min.css
new file mode 100644
index 00000000..0637d003
--- /dev/null
+++ b/vnfmarket/common/thirdparty/angular-material-data-table/dist/md-data-table.min.css
@@ -0,0 +1 @@
+md-backdrop.md-edit-dialog-backdrop{z-index:80}md-edit-dialog{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;position:fixed;z-index:81;background-color:#f9f9f9;border-radius:2px;cursor:default}md-edit-dialog>.md-content{padding:16px 24px 0}md-edit-dialog>.md-content .md-title{color:rgba(0,0,0,.87);margin-bottom:8px}md-edit-dialog>.md-content md-input-container{margin:0;font-size:13px}md-edit-dialog>.md-content md-input-container input{float:none}md-edit-dialog>.md-content md-input-container .md-errors-spacer{min-height:auto;min-width:auto;color:rgba(0,0,0,.54)}md-edit-dialog>.md-content md-input-container .md-errors-spacer .md-char-counter{padding:5px 2px 5px 0}md-edit-dialog>.md-content md-input-container [ng-message]{padding:5px 0 5px 2px}md-edit-dialog>.md-actions{margin:0 16px 8px}md-edit-dialog>.md-actions .md-button{margin:0;min-width:initial}md-edit-dialog>.md-actions .md-button+.md-button{margin-left:8px}.md-table-pagination{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:flex-end;-ms-flex-pack:end;justify-content:flex-end;-webkit-flex-wrap:wrap-reverse;-ms-flex-wrap:wrap-reverse;flex-wrap:wrap-reverse;box-sizing:border-box;padding:0 24px;font-size:12px;color:rgba(0,0,0,.54);border-top:1px rgba(0,0,0,.12) solid}.md-table-pagination md-select{-webkit-justify-content:flex-end;-ms-flex-pack:end;justify-content:flex-end;min-width:64px}.md-table-pagination md-select:not([disabled]):focus .md-select-value{color:rgba(0,0,0,.54)}.md-table-pagination md-select .md-select-value{-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto}.md-table-pagination md-select .md-select-value span.md-select-icon{-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;margin-right:-6px!important}.md-table-pagination md-select .md-select-value span.md-select-icon:after{top:initial;-webkit-transform:scaleY(0.5) scaleX(1);transform:scaleY(0.5) scaleX(1)}.md-table-pagination>*{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;height:56px}.md-table-pagination>.buttons:not(:first-child),.md-table-pagination>.limit-select:not(:first-child){margin-left:32px}.md-table-pagination>.buttons{margin-right:-16px}.md-table-pagination>.buttons>.md-button.md-icon-button{margin:0}.md-table-pagination>.buttons>.label+.md-button.md-icon-button{margin-left:20px}md-select.md-table-select{margin:0}md-select.md-table-select>.md-select-value{padding:0;min-width:0;min-height:24px;border-bottom:0!important}md-select.md-table-select>.md-select-value>span{display:block;height:auto;-webkit-transform:none!important;transform:none!important}md-select.md-table-select>.md-select-value>span>.md-text{display:inherit;height:inherit;-webkit-transform:inherit;transform:inherit}md-select.md-table-select>.md-select-value>span.md-select-icon{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;height:24px;margin:0}md-select.md-table-select>.md-select-value>span.md-select-icon:after{top:initial}.md-select-menu-container.md-pagination-select,.md-select-menu-container.md-table-select{margin-left:-2px;border-radius:2px}.md-select-menu-container.md-pagination-select md-content,.md-select-menu-container.md-pagination-select md-select-menu,.md-select-menu-container.md-table-select md-content,.md-select-menu-container.md-table-select md-select-menu{border-radius:inherit}.md-select-menu-container.md-pagination-select md-content,.md-select-menu-container.md-table-select md-content{padding:0}.md-select-menu-container.md-table-select .md-text{font-size:13px}.md-select-menu-container.md-pagination-select .md-text{font-size:12px}md-toolbar.md-table-toolbar{box-shadow:none}md-toolbar.md-table-toolbar.md-default-theme:not(.md-menu-toolbar).md-default,md-toolbar.md-table-toolbar:not(.md-menu-toolbar).md-default{background-color:#fff;color:rgba(0,0,0,.87)}md-toolbar.md-table-toolbar.md-default-theme:not(.md-menu-toolbar).md-default .md-button,md-toolbar.md-table-toolbar:not(.md-menu-toolbar).md-default .md-button{color:rgba(0,0,0,.87)}@media only screen and (max-width:959px) and (min-width:0) and (orientation:landscape){md-toolbar.md-table-toolbar .md-toolbar-tools{height:64px;max-height:initial}}md-toolbar.md-table-toolbar .md-toolbar-tools{padding:0 24px}md-toolbar.md-table-toolbar .md-toolbar-tools md-icon{color:rgba(0,0,0,.54)}md-toolbar.md-table-toolbar .md-toolbar-tools>.md-button.md-icon-button{margin:0}md-toolbar.md-table-toolbar .md-toolbar-tools>.md-button.md-icon-button:first-child{margin-left:-12px}md-toolbar.md-table-toolbar .md-toolbar-tools>.md-button.md-icon-button:last-child{margin-right:-12px}md-card>md-table-container:first-child,md-card>md-toolbar.md-table-toolbar:first-child{border-top-left-radius:2px;border-top-right-radius:2px}md-card>md-table-container:last-child,md-card>md-toolbar.md-table-toolbar:last-child{border-bottom-left-radius:2px;border-bottom-right-radius:2px}md-table-container{display:block;max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}table.md-table{width:100%;border-spacing:0;overflow:hidden}table.md-table thead.md-head>tr.md-row{height:56px}table.md-table tbody.md-body>tr.md-row,table.md-table tfoot.md-foot>tr.md-row{height:48px}table.md-table thead.md-head+.md-table-progress md-progress-linear{top:-3px}table.md-table .md-table-progress th{padding:0}table.md-table .md-table-progress th md-progress-linear{height:0;transition:opacity 1s}table.md-table .md-table-progress th md-progress-linear.ng-hide{opacity:0}table.md-table .md-table-progress th md-progress-linear>.md-container{height:3px;top:0;transition:none}table.md-table .md-table-progress th md-progress-linear>.md-container>.md-bar{height:3px}table.md-table th.md-column{color:rgba(0,0,0,.54);font-size:12px;font-weight:700;white-space:nowrap}table.md-table th.md-column.md-sort{cursor:pointer}table.md-table th.md-column md-icon{height:16px;width:16px;font-size:16px!important;line-height:16px!important}table.md-table th.md-column md-icon.md-sort-icon{color:rgba(0,0,0,.26);opacity:0;transition:-webkit-transform .25s,opacity .25s;transition:transform .25s,opacity .25s}table.md-table th.md-column md-icon.md-sort-icon.md-asc{-webkit-transform:rotate(0deg);transform:rotate(0deg)}table.md-table th.md-column md-icon.md-sort-icon.md-desc{-webkit-transform:rotate(180deg);transform:rotate(180deg)}table.md-table th.md-column md-icon:not(:first-child){margin-left:8px}table.md-table th.md-column md-icon:not(:last-child){margin-right:8px}table.md-table th.md-column.md-active,table.md-table th.md-column.md-active md-icon{color:rgba(0,0,0,.87)}table.md-table th.md-column.md-active md-icon.md-sort-icon,table.md-table th.md-column:hover md-icon.md-sort-icon{opacity:1}table.md-table tr.md-row[data-ng-repeat].ng-leave,table.md-table tr.md-row[ng-repeat].ng-leave,table.md-table tr.md-row[ng\:repeat].ng-leave,table.md-table tr.md-row[x-ng-repeat].ng-leave{display:none}table.md-table.md-row-select tbody.md-body>tr.md-row{transition:background-color .2s}table.md-table.md-row-select tbody.md-body>tr.md-row:not([disabled]):hover{background-color:#eee!important}table.md-table.md-row-select tbody.md-body>tr.md-row.md-selected{background-color:#f5f5f5}table.md-table.md-row-select td.md-cell:first-child,table.md-table.md-row-select th.md-column:first-child{width:20px;padding:0 0 0 24px}table.md-table.md-row-select td.md-cell:nth-child(2),table.md-table.md-row-select th.md-column:nth-child(2){padding:0 24px}table.md-table.md-row-select td.md-cell:nth-child(n+3):nth-last-child(n+2),table.md-table.md-row-select th.md-column:nth-child(n+3):nth-last-child(n+2){padding:0 56px 0 0}table.md-table:not(.md-row-select) td.md-cell:first-child,table.md-table:not(.md-row-select) th.md-column:first-child{padding:0 24px}table.md-table:not(.md-row-select) td.md-cell:nth-child(n+2):nth-last-child(n+2),table.md-table:not(.md-row-select) th.md-column:nth-child(n+2):nth-last-child(n+2){padding:0 56px 0 0}table.md-table td.md-cell,table.md-table th.md-column{vertical-align:middle;text-align:left}table.md-table td.md-cell>*,table.md-table th.md-column>*{vertical-align:middle}table.md-table td.md-cell:last-child,table.md-table th.md-column:last-child{padding:0 24px 0 0}table.md-table td.md-cell.md-clickable,table.md-table th.md-column.md-clickable{cursor:pointer}table.md-table td.md-cell.md-clickable:focus,table.md-table th.md-column.md-clickable:focus{outline:0}table.md-table td.md-cell.md-numeric,table.md-table th.md-column.md-numeric{text-align:right}table.md-table td.md-cell md-checkbox,table.md-table th.md-column md-checkbox{margin:0;width:20px}table.md-table td.md-cell{color:rgba(0,0,0,.87);font-size:13px;border-top:1px rgba(0,0,0,.12) solid}table.md-table td.md-cell.md-numeric md-select{-webkit-justify-content:flex-end;-ms-flex-pack:end;justify-content:flex-end}table.md-table td.md-cell.md-numeric md-select .md-select-value{-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto}table.md-table td.md-cell.md-placeholder{color:rgba(0,0,0,.26)}table.md-table td.md-cell md-select>.md-select-value>span.md-select-icon{-webkit-justify-content:flex-end;-ms-flex-pack:end;justify-content:flex-end;color:rgba(0,0,0,.54);width:18px;text-align:right}table.md-table td.md-cell md-select>.md-select-value>span.md-select-icon:after{-webkit-transform:scaleY(0.4) scaleX(0.8);transform:scaleY(0.4) scaleX(0.8)} \ No newline at end of file
diff --git a/vnfmarket/common/thirdparty/angular-material-data-table/dist/md-data-table.min.js b/vnfmarket/common/thirdparty/angular-material-data-table/dist/md-data-table.min.js
new file mode 100644
index 00000000..660f3c30
--- /dev/null
+++ b/vnfmarket/common/thirdparty/angular-material-data-table/dist/md-data-table.min.js
@@ -0,0 +1 @@
+!function(a,b,c){"use strict";function d(){function a(a){a.addClass("md-body")}return{compile:a,restrict:"A"}}function e(){function a(a){var b=a.find("md-select");return b.length&&b.addClass("md-table-select").attr("md-container-class","md-table-select"),a.addClass("md-cell"),c}function b(){}function c(a,b,c,d){function e(){return i.$$columns[f()]}function f(){return Array.prototype.indexOf.call(b.parent().children(),b[0])}var g=b.find("md-select"),h=d.shift(),i=d.shift();c.ngClick&&b.addClass("md-clickable"),g.length&&(g.on("click",function(a){a.stopPropagation()}),b.addClass("md-clickable").on("click",function(a){a.stopPropagation(),g[0].click()})),h.getTable=i.getElement,a.$watch(e,function(a){a&&(a.numeric?b.addClass("md-numeric"):b.removeClass("md-numeric"))})}return{controller:b,compile:a,require:["mdCell","^^mdTable"],restrict:"A"}}function f(a,c){function d(a){return a.addClass("md-column"),e}function e(d,e,f,g){function h(){var c=b.element('<md-icon md-svg-icon="arrow-up.svg">');a(c.addClass("md-sort-icon").attr("ng-class","getDirection()"))(d),e.hasClass("md-numeric")?e.prepend(c):e.append(c)}function i(){Array.prototype.some.call(e.find("md-icon"),function(a){return a.classList.contains("md-sort-icon")&&e[0].removeChild(a)})}function j(){i(),e.removeClass("md-sort").off("click",o)}function k(){h(),e.addClass("md-sort").on("click",o)}function l(){return Array.prototype.indexOf.call(e.parent().children(),e[0])}function m(){return d.orderBy&&(q.order===d.orderBy||q.order==="-"+d.orderBy)}function n(){return""===f.mdNumeric||d.numeric}function o(){d.$applyAsync(function(){m()?q.order="md-asc"===d.getDirection()?"-"+d.orderBy:d.orderBy:q.order="md-asc"===d.getDirection()?d.orderBy:"-"+d.orderBy,b.isFunction(q.onReorder)&&c.nextTick(function(){q.onReorder(q.order)})})}function p(a,b){r.$$columns[a]=b,b.numeric?e.addClass("md-numeric"):e.removeClass("md-numeric")}var q=g.shift(),r=g.shift();d.getDirection=function(){return m()?"-"===q.order.charAt(0)?"md-desc":"md-asc":""===f.mdDesc||d.$eval(f.mdDesc)?"md-desc":"md-asc"},d.$watch(m,function(a){a?e.addClass("md-active"):e.removeClass("md-active")}),d.$watch(l,function(a){p(a,{numeric:n()})}),d.$watch(n,function(a){p(l(),{numeric:a})}),d.$watch("orderBy",function(a){a?e.hasClass("md-sort")||k():e.hasClass("md-sort")&&j()})}return{compile:d,require:["^^mdHead","^^mdTable"],restrict:"A",scope:{numeric:"=?mdNumeric",orderBy:"@?mdOrderBy"}}}function g(a){return function(c,d,e,f){if(e&&"object"==typeof e){var g=a(c,d,!0,f);return b.extend(g.instance,e),g()}return a(c,d,e,f)}}function h(a,c,d,e,f,g,h,i,j){function k(c,d){var f,h=g.$new(),i=a(c)(h),j=e.createBackdrop(h,"md-edit-dialog-backdrop");return d.controller?f=m(d,h,{$element:i,$scope:h}):b.extend(h,d.scope),d.disableScroll&&l(i),v.prepend(j).append(i.addClass("md-whiteframe-1dp")),r(i,d.target),d.focusOnOpen&&q(i),d.clickOutsideToClose&&j.on("click",function(){i.remove()}),d.escToClose&&p(i),i.on("$destroy",function(){u=!1,j.remove()}),f}function l(a){var b=e.disableScrollAround(a,v);a.on("$destroy",function(){b()})}function m(a,d,e){if(a.controller)return a.resolve&&b.extend(e,a.resolve),a.locals&&b.extend(e,a.locals),a.controllerAs?(d[a.controllerAs]={},a.bindToController?b.extend(d[a.controllerAs],a.scope):b.extend(d,a.scope)):b.extend(d,a.scope),a.bindToController?c(a.controller,e,d[a.controllerAs]):c(a.controller,e)}function n(a){return f(function(c,d){function e(a){d("Unexpected template value. Expected a string; received a "+a+".")}var f=a.template;if(f)return b.isString(f)?c(f):e(typeof f);if(a.templateUrl){if(f=h.get(a.templateUrl))return c(f);var g=function(a){return c(a)},j=function(){return d("Error retrieving template from URL.")};return i(a.templateUrl).then(g,j)}d("Template not provided.")})}function o(a){u=!1,console.error(a)}function p(a){var b=function(b){b.keyCode===t&&a.remove()};v.on("keyup",b),a.on("$destroy",function(){v.off("keyup",b)})}function q(a){e.nextTick(function(){var b=e.findFocusTarget(a);b&&b.focus()},!1)}function r(a,c){var d=b.element(c).controller("mdCell").getTable(),e=function(){return a.prop("clientHeight")},f=function(){return{width:i(),height:e()}},h=function(){var a=d.parent();return"MD-TABLE-CONTAINER"===a.prop("tagName")?a[0].getBoundingClientRect():d[0].getBoundingClientRect()},i=function(){return a.prop("clientWidth")},k=function(){var b=f(),d=c.getBoundingClientRect(),e=h();b.width>e.right-d.left?a.css("left",e.right-b.width+"px"):a.css("left",d.left+"px"),b.height>e.bottom-d.top?a.css("top",e.bottom-b.height+"px"):a.css("top",d.top+1+"px"),a.css("minWidth",d.width+"px")},l=g.$watch(i,k),m=g.$watch(e,k);j.addEventListener("resize",k),a.on("$destroy",function(){l(),m(),j.removeEventListener("resize",k)})}function s(a,c){function d(){var a='type="'+(c.type||"text")+'"';for(var b in c.validators)a+=" "+b+'="'+c.validators[b]+'"';return a}return{controller:["$element","$q","save","$scope",function(a,c,d,e){function f(){return e.editDialog.$invalid?c.reject():b.isFunction(d)?c.when(d(e.editDialog.input)):c.resolve()}this.dismiss=function(){a.remove()},this.getInput=function(){return e.editDialog.input},e.dismiss=this.dismiss,e.submit=function(){f().then(function(){e.dismiss()})}}],locals:{save:c.save},scope:{cancel:c.cancel||"Cancel",messages:c.messages,model:c.modelValue,ok:c.ok||"Save",placeholder:c.placeholder,title:c.title,size:a},template:'<md-edit-dialog><div layout="column" class="md-content"><div ng-if="size === \'large\'" class="md-title">{{title || \'Edit\'}}</div><form name="editDialog" layout="column" ng-submit="submit(model)"><md-input-container md-no-float><input name="input" ng-model="model" md-autofocus placeholder="{{placeholder}} "'+d()+'><div ng-messages="editDialog.input.$error"><div ng-repeat="(key, message) in messages" ng-message="{{key}}">{{message}}</div></div></md-input-container></form></div><div ng-if="size === \'large\'" layout="row" layout-align="end" class="md-actions"><md-button class="md-primary" ng-click="dismiss()">{{cancel}}</md-button><md-button class="md-primary" ng-click="submit()">{{ok}}</md-button></div></md-edit-dialog>'}}var t=27,u=!1,v=b.element(d.prop("body")),w={clickOutsideToClose:!0,disableScroll:!0,escToClose:!0,focusOnOpen:!0};return this.show=function(a){if(u)return f.reject();if(u=!0,a=b.extend({},w,a),!a.targetEvent)return o("options.targetEvent is required to align the dialog with the table cell.");if(!a.targetEvent.currentTarget.classList.contains("md-cell"))return o("The event target must be a table cell.");if(a.bindToController&&!a.controllerAs)return o("You must define options.controllerAs when options.bindToController is true.");a.target=a.targetEvent.currentTarget;var c=n(a),d=[c];for(var e in a.resolve)c=a.resolve[e],d.push(f.when(b.isFunction(c)?c():c));return c=f.all(d),c.catch(o),c.then(function(b){var c=b.shift();for(var d in a.resolve)a.resolve[d]=b.shift();return k(c,a)})},this.small=function(a){return this.show(b.extend({},a,s("small",a)))}.bind(this),this.large=function(a){return this.show(b.extend({},a,s("large",a)))}.bind(this),this}function i(){function a(a){a.addClass("md-foot")}return{compile:a,restrict:"A"}}function j(a){function c(a){return a.addClass("md-head"),e}function d(){}function e(c,d,e,f){function g(){d.children().prepend('<th class="md-column md-checkbox-column">')}function h(){d.prop("lastElementChild").firstElementChild.appendChild(a(i())(c)[0])}function i(){return b.element("<md-checkbox>").attr({"aria-label":"Select All","ng-click":"toggleAll()","ng-checked":"allSelected()","ng-disabled":"!getSelectableRows().length"})}function j(){var a=d.prop("lastElementChild").firstElementChild;a.classList.contains("md-checkbox-column")&&b.element(a).empty()}function k(){return f.$$rowSelect}function l(a){return b.element(a).controller("mdSelect")}function m(){Array.prototype.some.call(d.find("th"),function(a){return a.classList.contains("md-checkbox-column")&&a.remove()})}var n=new Array(2);c.allSelected=function(){var a=c.getSelectableRows();return a.length&&a.every(function(a){return a.isSelected()})},c.getSelectableRows=function(){return f.getBodyRows().map(l).filter(function(a){return a&&!a.disabled})},c.selectAll=function(){f.getBodyRows().map(l).forEach(function(a){a&&!a.isSelected()&&a.select()})},c.toggleAll=function(){return c.allSelected()?c.unSelectAll():c.selectAll()},c.unSelectAll=function(){f.getBodyRows().map(l).forEach(function(a){a&&a.isSelected()&&a.deselect()})},c.$watchGroup([k,f.enableMultiSelect],function(a){a[0]!==n[0]?a[0]?(g(),a[1]&&h()):m():a[0]&&a[1]!==n[1]&&(a[1]?h():j()),b.copy(a,n)})}return{bindToController:!0,compile:c,controller:d,controllerAs:"$mdHead",require:"^^mdTable",restrict:"A",scope:{order:"=?mdOrder",onReorder:"=?mdOnReorder"}}}function k(){function a(a){return a.addClass("md-row"),c}function c(a,c,d,e){function f(){return e.$$rowSelect}function g(){return e.getBodyRows().indexOf(c[0])!==-1}function h(a){return c[0].contains(a[0])}if(g()){var i=b.element('<td class="md-cell">');a.$watch(f,function(a){return a&&!d.mdSelect?void(h(i)||c.prepend(i)):void(h(i)&&i.remove())})}}return{compile:a,require:"^^mdTable",restrict:"A"}}function l(a,c){function d(){}function e(d,e,f,g){function h(){return""===f.mdAutoSelect||o.autoSelect}function i(){var c=b.element("<md-checkbox>").attr({"aria-label":"Select Row","ng-click":"$mdSelect.toggle($event)","ng-checked":"$mdSelect.isSelected()","ng-disabled":"$mdSelect.disabled"});return b.element('<td class="md-cell md-checkbox-cell">').append(a(c)(d))}function j(){Array.prototype.some.call(e.children(),function(a){return a.classList.contains("md-checkbox-cell")&&e[0].removeChild(a)}),h()&&e.off("click",n)}function k(){e.prepend(i()),h()&&e.on("click",n)}function l(){return p.$$rowSelect}function m(a){if(o.id)return p.$$hash.has(o.id)?void(a.indexOf(p.$$hash.get(o.id))===-1&&p.$$hash.purge(o.id)):void(a.indexOf(o.model)!==-1&&p.$$hash.update(o.id,o.model))}function n(a){d.$applyAsync(function(){o.toggle(a)})}var o=g.shift(),p=g.shift(),q=c(f.mdSelectId);if(o.id=q(o.model),p.$$rowSelect&&o.id)if(p.$$hash.has(o.id)){var r=p.selected.indexOf(p.$$hash.get(o.id));r===-1?p.$$hash.purge(o.id):p.$$hash.equals(o.id,o.model)||(p.$$hash.update(o.id,o.model),p.selected.splice(r,1,o.model))}else p.selected.some(function(a,b){if(q(a)===o.id)return p.$$hash.update(o.id,o.model),p.selected.splice(b,1,o.model),!0});o.isSelected=function(){return!!p.$$rowSelect&&(o.id?p.$$hash.has(o.id):p.selected.indexOf(o.model)!==-1)},o.select=function(){o.disabled||(p.enableMultiSelect()?p.selected.push(o.model):p.selected.splice(0,p.selected.length,o.model),b.isFunction(o.onSelect)&&o.onSelect(o.model))},o.deselect=function(){o.disabled||(p.selected.splice(p.selected.indexOf(o.model),1),b.isFunction(o.onDeselect)&&o.onDeselect(o.model))},o.toggle=function(a){return a&&a.stopPropagation&&a.stopPropagation(),o.isSelected()?o.deselect():o.select()},d.$watch(l,function(a){a?k():j()}),d.$watch(h,function(a,b){a!==b&&(p.$$rowSelect&&a?e.on("click",n):e.off("click",n))}),d.$watch(o.isSelected,function(a){return a?e.addClass("md-selected"):e.removeClass("md-selected")}),d.$watch(p.enableMultiSelect,function(a){p.$$rowSelect&&!a&&p.selected.splice(1)}),p.registerModelChangeListener(m),e.on("$destroy",function(){p.removeModelChangeListener(m)})}return{bindToController:!0,controller:d,controllerAs:"$mdSelect",link:e,require:["mdSelect","^^mdTable"],restrict:"A",scope:{model:"=mdSelect",disabled:"=ngDisabled",onSelect:"=?mdOnSelect",onDeselect:"=?mdOnDeselect",autoSelect:"=mdAutoSelect"}}}function m(){var a={};this.equals=function(b,c){return a[b]===c},this.get=function(b){return a[b]},this.has=function(b){return a.hasOwnProperty(b)},this.purge=function(b){delete a[b]},this.update=function(b,c){a[b]=c}}function n(){function a(a,c){if(a.addClass("md-table"),c.hasOwnProperty("mdProgress")){var d=a.find("tbody")[0],e=b.element('<thead class="md-table-progress" md-table-progress>');d&&a[0].insertBefore(e[0],d)}}function c(a,c,d,e){function f(){l.$$rowSelect=!0,k=e.$watchCollection("$mdTable.selected",function(a){o.forEach(function(b){b(a)})}),c.addClass("md-row-select")}function g(){l.$$rowSelect=!1,b.isFunction(k)&&k(),c.removeClass("md-row-select")}function h(){return n.length?void n[0].finally(function(){n.shift(),h()}):e.$applyAsync()}function i(){return""===a.mdRowSelect||l.rowSelect}function j(){return l.selected?!!b.isArray(l.selected)||console.error("Row selection: Expected an array. Recived "+typeof l.selected+"."):console.error("Row selection: ngModel is not defined.")}var k,l=this,n=[],o=[];l.$$hash=new m,l.$$columns={},l.columnCount=function(){return l.getRows(c[0]).reduce(function(a,b){return b.cells.length>a?b.cells.length:a},0)},l.getRows=function(a){return Array.prototype.filter.call(a.rows,function(a){return!a.classList.contains("ng-leave")})},l.getBodyRows=function(){return Array.prototype.reduce.call(c.prop("tBodies"),function(a,b){return a.concat(l.getRows(b))},[])},l.getElement=function(){return c},l.getHeaderRows=function(){return l.getRows(c.prop("tHead"))},l.enableMultiSelect=function(){return""===a.multiple||e.$eval(a.multiple)},l.waitingOnPromise=function(){return!!n.length},l.queuePromise=function(a){a&&1===n.push(b.isArray(a)?d.all(a):d.when(a))&&h()},l.registerModelChangeListener=function(a){o.push(a)},l.removeModelChangeListener=function(a){var b=o.indexOf(a);b!==-1&&o.splice(b,1)},a.hasOwnProperty("mdProgress")&&e.$watch("$mdTable.progress",l.queuePromise),e.$watch(i,function(a){a&&j()?f():g()})}return c.$inject=["$attrs","$element","$q","$scope"],{bindToController:!0,compile:a,controller:c,controllerAs:"$mdTable",restrict:"A",scope:{progress:"=?mdProgress",selected:"=ngModel",rowSelect:"=mdRowSelect"}}}function o(){function a(a){a.addClass("md-table-pagination")}function c(a,c,d){function e(a){return parseInt(a,10)>0}var f=this,g={page:"Page:",rowsPerPage:"Rows per page:",of:"of"};f.label=b.copy(g),f.eval=function(a){return d.$eval(a)},f.first=function(){f.page=1,f.onPaginationChange()},f.hasNext=function(){return f.page*f.limit<f.total},f.hasPrevious=function(){return f.page>1},f.last=function(){f.page=f.pages(),f.onPaginationChange()},f.max=function(){return f.hasNext()?f.page*f.limit:f.total},f.min=function(){return e(f.total)?f.page*f.limit-f.limit+1:0},f.next=function(){f.page++,f.onPaginationChange()},f.onPaginationChange=function(){b.isFunction(f.onPaginate)&&c.nextTick(function(){f.onPaginate(f.page,f.limit)})},f.pages=function(){return e(f.total)?Math.ceil(f.total/(e(f.limit)?f.limit:1)):1},f.previous=function(){f.page--,f.onPaginationChange()},f.showBoundaryLinks=function(){return""===a.mdBoundaryLinks||f.boundaryLinks},f.showPageSelect=function(){return""===a.mdPageSelect||f.pageSelect},d.$watch("$pagination.limit",function(a,b){isNaN(a)||isNaN(b)||a===b||(f.page=Math.floor((f.page*b-b+a)/(e(a)?a:1)),f.onPaginationChange())}),a.$observe("mdLabel",function(a){b.extend(f.label,g,d.$eval(a))}),d.$watch("$pagination.total",function(a,b){isNaN(a)||a===b||f.page>f.pages()&&f.last()})}return c.$inject=["$attrs","$mdUtil","$scope"],{bindToController:{boundaryLinks:"=?mdBoundaryLinks",disabled:"=ngDisabled",limit:"=mdLimit",page:"=mdPage",pageSelect:"=?mdPageSelect",onPaginate:"=?mdOnPaginate",limitOptions:"=?mdLimitOptions",total:"@mdTotal"},compile:a,controller:c,controllerAs:"$pagination",restrict:"E",scope:{},templateUrl:"md-table-pagination.html"}}function p(){function a(a,b,c,d){a.columnCount=d.columnCount,a.deferred=d.waitingOnPromise}return{link:a,require:"^^mdTable",restrict:"A",scope:{},templateUrl:"md-table-progress.html"}}function q(){function a(a,b){function c(a,b){return Math.min(a,isFinite(b)&&d(b)?b:1)}function d(a){return a>0}function e(a){if(f.pages.length>a)return f.pages.splice(a);for(var b=f.pages.length;b<a;b++)f.pages.push(b+1)}var f=this,g=a.find("md-content");f.pages=[],g.on("scroll",function(){g.prop("clientHeight")+g.prop("scrollTop")>=g.prop("scrollHeight")&&b.$applyAsync(function(){e(c(f.pages.length+10,f.total))})}),b.$watch("$pageSelect.total",function(a){e(c(Math.max(f.pages.length,10),a))}),b.$watch("$pagination.page",function(a){for(var b=f.pages.length;b<a;b++)f.pages.push(b+1)})}return a.$inject=["$element","$scope"],{bindToController:{total:"@"},controller:a,controllerAs:"$pageSelect"}}b.module("md.table.templates",["md-table-pagination.html","md-table-progress.html","arrow-up.svg","navigate-before.svg","navigate-first.svg","navigate-last.svg","navigate-next.svg"]),b.module("md-table-pagination.html",[]).run(["$templateCache",function(a){a.put("md-table-pagination.html",'<div class="page-select" ng-if="$pagination.showPageSelect()">\n <div class="label">{{$pagination.label.page}}</div>\n\n <md-select virtual-page-select total="{{$pagination.pages()}}" class="md-table-select" ng-model="$pagination.page" md-container-class="md-pagination-select" ng-change="$pagination.onPaginationChange()" ng-disabled="$pagination.disabled" aria-label="Page">\n <md-content>\n <md-option ng-repeat="page in $pageSelect.pages" ng-value="page">{{page}}</md-option>\n </md-content>\n </md-select>\n</div>\n\n<div class="limit-select" ng-if="$pagination.limitOptions">\n <div class="label">{{$pagination.label.rowsPerPage}}</div>\n\n <md-select class="md-table-select" ng-model="$pagination.limit" md-container-class="md-pagination-select" ng-disabled="$pagination.disabled" aria-label="Rows" placeholder="{{ $pagination.limitOptions[0] }}">\n <md-option ng-repeat="option in $pagination.limitOptions" ng-value="option.value ? $pagination.eval(option.value) : option">{{::option.label ? option.label : option}}</md-option>\n </md-select>\n</div>\n\n<div class="buttons">\n <div class="label">{{$pagination.min()}} - {{$pagination.max()}} {{$pagination.label.of}} {{$pagination.total}}</div>\n\n <md-button class="md-icon-button" type="button" ng-if="$pagination.showBoundaryLinks()" ng-click="$pagination.first()" ng-disabled="$pagination.disabled || !$pagination.hasPrevious()" aria-label="First">\n <md-icon md-svg-icon="navigate-first.svg"></md-icon>\n </md-button>\n\n <md-button class="md-icon-button" type="button" ng-click="$pagination.previous()" ng-disabled="$pagination.disabled || !$pagination.hasPrevious()" aria-label="Previous">\n <md-icon md-svg-icon="navigate-before.svg"></md-icon>\n </md-button>\n\n <md-button class="md-icon-button" type="button" ng-click="$pagination.next()" ng-disabled="$pagination.disabled || !$pagination.hasNext()" aria-label="Next">\n <md-icon md-svg-icon="navigate-next.svg"></md-icon>\n </md-button>\n\n <md-button class="md-icon-button" type="button" ng-if="$pagination.showBoundaryLinks()" ng-click="$pagination.last()" ng-disabled="$pagination.disabled || !$pagination.hasNext()" aria-label="Last">\n <md-icon md-svg-icon="navigate-last.svg"></md-icon>\n </md-button>\n</div>')}]),b.module("md-table-progress.html",[]).run(["$templateCache",function(a){a.put("md-table-progress.html",'<tr>\n <th colspan="{{columnCount()}}">\n <md-progress-linear ng-show="deferred()" md-mode="indeterminate"></md-progress-linear>\n </th>\n</tr>')}]),b.module("arrow-up.svg",[]).run(["$templateCache",function(a){a.put("arrow-up.svg",'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z"/></svg>')}]),b.module("navigate-before.svg",[]).run(["$templateCache",function(a){a.put("navigate-before.svg",'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/></svg>')}]),b.module("navigate-first.svg",[]).run(["$templateCache",function(a){a.put("navigate-first.svg",'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M7 6 v12 h2 v-12 h-2z M17.41 7.41L16 6l-6 6 6 6 1.41-1.41L12.83 12z"/></svg>')}]),b.module("navigate-last.svg",[]).run(["$templateCache",function(a){a.put("navigate-last.svg",'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M15 6 v12 h2 v-12 h-2z M8 6L6.59 7.41 11.17 12l-4.58 4.59L8 18l6-6z"/></svg>')}]),b.module("navigate-next.svg",[]).run(["$templateCache",function(a){a.put("navigate-next.svg",'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg>')}]),b.module("md.data.table",["md.table.templates"]),b.module("md.data.table").directive("mdBody",d),b.module("md.data.table").directive("mdCell",e),b.module("md.data.table").directive("mdColumn",f),f.$inject=["$compile","$mdUtil"],b.module("md.data.table").decorator("$controller",g).factory("$mdEditDialog",h),g.$inject=["$delegate"],h.$inject=["$compile","$controller","$document","$mdUtil","$q","$rootScope","$templateCache","$templateRequest","$window"],b.module("md.data.table").directive("mdFoot",i),b.module("md.data.table").directive("mdHead",j),j.$inject=["$compile"],b.module("md.data.table").directive("mdRow",k),b.module("md.data.table").directive("mdSelect",l),l.$inject=["$compile","$parse"],b.module("md.data.table").directive("mdTable",n),b.module("md.data.table").directive("mdTablePagination",o),b.module("md.data.table").directive("mdTableProgress",p),b.module("md.data.table").directive("virtualPageSelect",q)}(window,angular); \ No newline at end of file
diff --git a/vnfmarket/common/thirdparty/angular-material-data-table/index.js b/vnfmarket/common/thirdparty/angular-material-data-table/index.js
new file mode 100644
index 00000000..cd908453
--- /dev/null
+++ b/vnfmarket/common/thirdparty/angular-material-data-table/index.js
@@ -0,0 +1,6 @@
+// support for Browserify
+
+require('angular-material');
+require('./dist/md-data-table');
+
+module.exports = 'md.data.table';
diff --git a/vnfmarket/common/thirdparty/angular-material-data-table/package.json b/vnfmarket/common/thirdparty/angular-material-data-table/package.json
new file mode 100644
index 00000000..a66713b9
--- /dev/null
+++ b/vnfmarket/common/thirdparty/angular-material-data-table/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "angular-material-data-table",
+ "version": "0.10.9",
+ "description": "Material Design data table.",
+ "license": "MIT",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/daniel-nagy/md-data-table.git"
+ },
+ "main": "index.js",
+ "devDependencies": {
+ "bower": "^1.3.9",
+ "grunt": "^0.4.5",
+ "grunt-autoprefixer": "^2.1.0",
+ "grunt-contrib-clean": "^0.6.0",
+ "grunt-contrib-concat": "^0.5.0",
+ "grunt-contrib-connect": "^0.8.0",
+ "grunt-contrib-cssmin": "^0.10.0",
+ "grunt-contrib-jshint": "^0.10.0",
+ "grunt-contrib-less": "^0.11.4",
+ "grunt-contrib-uglify": "^0.5.1",
+ "grunt-contrib-watch": "^0.6.1",
+ "grunt-html2js": "^0.3.2",
+ "grunt-processhtml": "^0.3.7",
+ "jshint-stylish": "^1.0.0",
+ "load-grunt-tasks": "^0.6.0"
+ },
+ "peerDependencies": {
+ "angular": "^1.4.0",
+ "angular-material": "^1.0.0"
+ }
+}