added missing vimeo urls to existing talks
This commit is contained in:
parent
542d9e753a
commit
66c59cc269
118 changed files with 44678 additions and 20411 deletions
85
_site/bower_components/isotope/README.md
vendored
Normal file
85
_site/bower_components/isotope/README.md
vendored
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
# Isotope
|
||||
|
||||
_Filter & sort magical layouts_
|
||||
|
||||
See [isotope.metafizzy.co](http://isotope.metafizzy.co) for complete docs and demos.
|
||||
|
||||
## Install
|
||||
|
||||
### Download
|
||||
|
||||
+ [isotope.pkgd.js](https://npmcdn.com/isotope-layout@3/dist/isotope.pkgd.js) un-minified, or
|
||||
+ [isotope.pkgd.min.js](https://npmcdn.com/isotope-layout@3/dist/isotope.pkgd.min.js) minified
|
||||
|
||||
### CDN
|
||||
|
||||
Link directly to Isotope files on [npmcdn](https://npmcdn.com).
|
||||
|
||||
``` html
|
||||
<script src="https://npmcdn.com/isotope-layout@3.0/dist/isotope.pkgd.min.js"></script>
|
||||
<!-- or -->
|
||||
<script src="https://npmcdn.com/isotope-layout@3.0/dist/isotope.pkgd.js"></script>
|
||||
```
|
||||
|
||||
### Package managers
|
||||
|
||||
npm: `npm install isotope-layout --save`
|
||||
|
||||
Bower: `bower install isotope --save`
|
||||
|
||||
## License
|
||||
|
||||
### Commercial license
|
||||
|
||||
If you want to use Isotope to develop commercial sites, themes, projects, and applications, the Commercial license is the appropriate license. With this option, your source code is kept proprietary. Purchase an Isotope Commercial License at [isotope.metafizzy.co](http://isotope.metafizzy.co/#commercial-license)
|
||||
|
||||
### Open source license
|
||||
|
||||
If you are creating an open source application under a license compatible with the [GNU GPL license v3](https://www.gnu.org/licenses/gpl-3.0.html), you may use Isotope under the terms of the GPLv3.
|
||||
|
||||
[Read more about Isotope's license](http://isotope.metafizzy.co/license.html).
|
||||
|
||||
## Initialize
|
||||
|
||||
With jQuery
|
||||
|
||||
``` js
|
||||
$('.grid').isotope({
|
||||
// options...
|
||||
itemSelector: '.grid-item',
|
||||
masonry: {
|
||||
columnWidth: 200
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
With vanilla JavaScript
|
||||
|
||||
``` js
|
||||
// vanilla JS
|
||||
var grid = document.querySelector('.grid');
|
||||
var iso = new Isotope( grid, {
|
||||
// options...
|
||||
itemSelector: '.grid-item',
|
||||
masonry: {
|
||||
columnWidth: 200
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
With HTML
|
||||
|
||||
Add a `data-isotope` attribute to your element. Options can be set in JSON in the value.
|
||||
|
||||
``` html
|
||||
<div class="grid"
|
||||
data-isotope='{ "itemSelector": ".grid-item", "masonry": { "columnWidth": 200 } }'>
|
||||
<div class="grid-item"></div>
|
||||
<div class="grid-item"></div>
|
||||
...
|
||||
</div>
|
||||
```
|
||||
|
||||
* * *
|
||||
|
||||
By [Metafizzy](http://metafizzy.co), 2010–2016
|
||||
44
_site/bower_components/isotope/bower.json
vendored
Normal file
44
_site/bower_components/isotope/bower.json
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"name": "isotope",
|
||||
"description": "Filter and sort magical layouts",
|
||||
"main": "js/isotope.js",
|
||||
"dependencies": {
|
||||
"desandro-matches-selector": "^2.0.0",
|
||||
"fizzy-ui-utils": "^2.0.0",
|
||||
"get-size": "^2.0.0",
|
||||
"masonry": "^4.1.0",
|
||||
"outlayer": "^2.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jquery": "2 < 4",
|
||||
"jquery-bridget": "^2",
|
||||
"qunit": "^1.15"
|
||||
},
|
||||
"ignore": [
|
||||
"test/",
|
||||
"sandbox/",
|
||||
"**/.*",
|
||||
"package.json",
|
||||
"notes.md",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"homepage": "http://isotope.metafizzy.co",
|
||||
"authors": [
|
||||
"David DeSandro"
|
||||
],
|
||||
"moduleType": [
|
||||
"amd",
|
||||
"globals",
|
||||
"node"
|
||||
],
|
||||
"keywords": [
|
||||
"filter",
|
||||
"sort",
|
||||
"masonry",
|
||||
"jquery-plugin"
|
||||
],
|
||||
"license": "GPL-3.0"
|
||||
}
|
||||
3515
_site/bower_components/isotope/dist/isotope.pkgd.js
vendored
Normal file
3515
_site/bower_components/isotope/dist/isotope.pkgd.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
12
_site/bower_components/isotope/dist/isotope.pkgd.min.js
vendored
Normal file
12
_site/bower_components/isotope/dist/isotope.pkgd.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
142
_site/bower_components/isotope/gulpfile.js
vendored
Normal file
142
_site/bower_components/isotope/gulpfile.js
vendored
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/*jshint node: true, strict: false */
|
||||
|
||||
var fs = require('fs');
|
||||
var gulp = require('gulp');
|
||||
var rename = require('gulp-rename');
|
||||
var replace = require('gulp-replace');
|
||||
|
||||
// ----- hint ----- //
|
||||
|
||||
var jshint = require('gulp-jshint');
|
||||
|
||||
gulp.task( 'hint-js', function() {
|
||||
return gulp.src('js/*.js')
|
||||
.pipe( jshint() )
|
||||
.pipe( jshint.reporter('default') );
|
||||
});
|
||||
|
||||
gulp.task( 'hint-test', function() {
|
||||
return gulp.src('test/unit/*.js')
|
||||
.pipe( jshint() )
|
||||
.pipe( jshint.reporter('default') );
|
||||
});
|
||||
|
||||
gulp.task( 'hint-task', function() {
|
||||
return gulp.src('gulpfile.js')
|
||||
.pipe( jshint() )
|
||||
.pipe( jshint.reporter('default') );
|
||||
});
|
||||
|
||||
var jsonlint = require('gulp-json-lint');
|
||||
|
||||
gulp.task( 'jsonlint', function() {
|
||||
return gulp.src( '*.json' )
|
||||
.pipe( jsonlint() )
|
||||
.pipe( jsonlint.report('verbose') );
|
||||
});
|
||||
|
||||
gulp.task( 'hint', [ 'hint-js', 'hint-test', 'hint-task', 'jsonlint' ]);
|
||||
|
||||
// -------------------------- make pkgd -------------------------- //
|
||||
|
||||
// regex for banner comment
|
||||
var reBannerComment = new RegExp('^\\s*(?:\\/\\*[\\s\\S]*?\\*\\/)\\s*');
|
||||
|
||||
function getBanner() {
|
||||
var src = fs.readFileSync( 'js/isotope.js', 'utf8' );
|
||||
var matches = src.match( reBannerComment );
|
||||
var banner = matches[0].replace( 'Isotope', 'Isotope PACKAGED' );
|
||||
return banner;
|
||||
}
|
||||
|
||||
function addBanner( str ) {
|
||||
return replace( /^/, str );
|
||||
}
|
||||
|
||||
var rjsOptimize = require('gulp-requirejs-optimize');
|
||||
|
||||
gulp.task( 'requirejs', function() {
|
||||
var definitionRE = /define\(\s*'isotope\/isotope'(.|\n)+\],/;
|
||||
var banner = getBanner();
|
||||
// HACK src is not needed
|
||||
// should refactor rjsOptimize to produce src
|
||||
return gulp.src('js/isotope.js')
|
||||
.pipe( rjsOptimize({
|
||||
baseUrl: 'bower_components',
|
||||
optimize: 'none',
|
||||
include: [
|
||||
'jquery-bridget/jquery-bridget',
|
||||
'isotope/isotope'
|
||||
],
|
||||
paths: {
|
||||
isotope: '../js/',
|
||||
jquery: 'empty:'
|
||||
}
|
||||
}) )
|
||||
// munge AMD definition
|
||||
.pipe( replace( definitionRE, function( definition ) {
|
||||
// remove named module
|
||||
return definition.replace( "'isotope/isotope',", '' )
|
||||
// use explicit file paths, './item' -> 'isotope/js/item'
|
||||
.replace( /'.\//g, "'isotope/js/" );
|
||||
}) )
|
||||
.pipe( replace( "define( 'isotope/", "define( 'isotope/js/" ) )
|
||||
// add banner
|
||||
.pipe( addBanner( banner ) )
|
||||
.pipe( rename('isotope.pkgd.js') )
|
||||
.pipe( gulp.dest('dist') );
|
||||
});
|
||||
|
||||
|
||||
// ----- uglify ----- //
|
||||
|
||||
var uglify = require('gulp-uglify');
|
||||
|
||||
gulp.task( 'uglify', [ 'requirejs' ], function() {
|
||||
var banner = getBanner();
|
||||
gulp.src('dist/isotope.pkgd.js')
|
||||
.pipe( uglify() )
|
||||
// add banner
|
||||
.pipe( addBanner( banner ) )
|
||||
.pipe( rename('isotope.pkgd.min.js') )
|
||||
.pipe( gulp.dest('dist') );
|
||||
});
|
||||
|
||||
// ----- version ----- //
|
||||
|
||||
// set version in source files
|
||||
|
||||
var minimist = require('minimist');
|
||||
var gutil = require('gulp-util');
|
||||
var chalk = require('chalk');
|
||||
|
||||
// use gulp version -t 1.2.3
|
||||
gulp.task( 'version', function() {
|
||||
var args = minimist( process.argv.slice(3) );
|
||||
var version = args.t;
|
||||
if ( !version || !/^\d\.\d+\.\d+/.test( version ) ) {
|
||||
gutil.log( 'invalid version: ' + chalk.red( version ) );
|
||||
return;
|
||||
}
|
||||
gutil.log( 'ticking version to ' + chalk.green( version ) );
|
||||
|
||||
gulp.src('js/isotope.js')
|
||||
.pipe( replace( /Packery v\d\.\d+\.\d+/, 'Isotope v' + version ) )
|
||||
.pipe( gulp.dest('js') );
|
||||
|
||||
gulp.src( [ 'package.json' ] )
|
||||
.pipe( replace( /"version": "\d\.\d+\.\d+"/, '"version": "' + version + '"' ) )
|
||||
.pipe( gulp.dest('.') );
|
||||
// replace CDN links in README
|
||||
var minorVersion = version.match( /^\d\.\d+/ )[0];
|
||||
gulp.src('README.md')
|
||||
.pipe( replace( /isotope-layout@\d\.\d+/g, 'isotope-layout@' + minorVersion ))
|
||||
.pipe( gulp.dest('.') );
|
||||
});
|
||||
|
||||
// ----- default ----- //
|
||||
|
||||
gulp.task( 'default', [
|
||||
'hint',
|
||||
'uglify'
|
||||
]);
|
||||
613
_site/bower_components/isotope/js/isotope.js
vendored
Normal file
613
_site/bower_components/isotope/js/isotope.js
vendored
Normal file
|
|
@ -0,0 +1,613 @@
|
|||
/*!
|
||||
* Isotope v3.0.1
|
||||
*
|
||||
* Licensed GPLv3 for open source use
|
||||
* or Isotope Commercial License for commercial use
|
||||
*
|
||||
* http://isotope.metafizzy.co
|
||||
* Copyright 2016 Metafizzy
|
||||
*/
|
||||
|
||||
( function( window, factory ) {
|
||||
// universal module definition
|
||||
/* jshint strict: false */ /*globals define, module, require */
|
||||
if ( typeof define == 'function' && define.amd ) {
|
||||
// AMD
|
||||
define( [
|
||||
'outlayer/outlayer',
|
||||
'get-size/get-size',
|
||||
'desandro-matches-selector/matches-selector',
|
||||
'fizzy-ui-utils/utils',
|
||||
'./item',
|
||||
'./layout-mode',
|
||||
// include default layout modes
|
||||
'./layout-modes/masonry',
|
||||
'./layout-modes/fit-rows',
|
||||
'./layout-modes/vertical'
|
||||
],
|
||||
function( Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ) {
|
||||
return factory( window, Outlayer, getSize, matchesSelector, utils, Item, LayoutMode );
|
||||
});
|
||||
} else if ( typeof module == 'object' && module.exports ) {
|
||||
// CommonJS
|
||||
module.exports = factory(
|
||||
window,
|
||||
require('outlayer'),
|
||||
require('get-size'),
|
||||
require('desandro-matches-selector'),
|
||||
require('fizzy-ui-utils'),
|
||||
require('./item'),
|
||||
require('./layout-mode'),
|
||||
// include default layout modes
|
||||
require('./layout-modes/masonry'),
|
||||
require('./layout-modes/fit-rows'),
|
||||
require('./layout-modes/vertical')
|
||||
);
|
||||
} else {
|
||||
// browser global
|
||||
window.Isotope = factory(
|
||||
window,
|
||||
window.Outlayer,
|
||||
window.getSize,
|
||||
window.matchesSelector,
|
||||
window.fizzyUIUtils,
|
||||
window.Isotope.Item,
|
||||
window.Isotope.LayoutMode
|
||||
);
|
||||
}
|
||||
|
||||
}( window, function factory( window, Outlayer, getSize, matchesSelector, utils,
|
||||
Item, LayoutMode ) {
|
||||
|
||||
'use strict';
|
||||
|
||||
// -------------------------- vars -------------------------- //
|
||||
|
||||
var jQuery = window.jQuery;
|
||||
|
||||
// -------------------------- helpers -------------------------- //
|
||||
|
||||
var trim = String.prototype.trim ?
|
||||
function( str ) {
|
||||
return str.trim();
|
||||
} :
|
||||
function( str ) {
|
||||
return str.replace( /^\s+|\s+$/g, '' );
|
||||
};
|
||||
|
||||
// -------------------------- isotopeDefinition -------------------------- //
|
||||
|
||||
// create an Outlayer layout class
|
||||
var Isotope = Outlayer.create( 'isotope', {
|
||||
layoutMode: 'masonry',
|
||||
isJQueryFiltering: true,
|
||||
sortAscending: true
|
||||
});
|
||||
|
||||
Isotope.Item = Item;
|
||||
Isotope.LayoutMode = LayoutMode;
|
||||
|
||||
var proto = Isotope.prototype;
|
||||
|
||||
proto._create = function() {
|
||||
this.itemGUID = 0;
|
||||
// functions that sort items
|
||||
this._sorters = {};
|
||||
this._getSorters();
|
||||
// call super
|
||||
Outlayer.prototype._create.call( this );
|
||||
|
||||
// create layout modes
|
||||
this.modes = {};
|
||||
// start filteredItems with all items
|
||||
this.filteredItems = this.items;
|
||||
// keep of track of sortBys
|
||||
this.sortHistory = [ 'original-order' ];
|
||||
// create from registered layout modes
|
||||
for ( var name in LayoutMode.modes ) {
|
||||
this._initLayoutMode( name );
|
||||
}
|
||||
};
|
||||
|
||||
proto.reloadItems = function() {
|
||||
// reset item ID counter
|
||||
this.itemGUID = 0;
|
||||
// call super
|
||||
Outlayer.prototype.reloadItems.call( this );
|
||||
};
|
||||
|
||||
proto._itemize = function() {
|
||||
var items = Outlayer.prototype._itemize.apply( this, arguments );
|
||||
// assign ID for original-order
|
||||
for ( var i=0; i < items.length; i++ ) {
|
||||
var item = items[i];
|
||||
item.id = this.itemGUID++;
|
||||
}
|
||||
this._updateItemsSortData( items );
|
||||
return items;
|
||||
};
|
||||
|
||||
|
||||
// -------------------------- layout -------------------------- //
|
||||
|
||||
proto._initLayoutMode = function( name ) {
|
||||
var Mode = LayoutMode.modes[ name ];
|
||||
// set mode options
|
||||
// HACK extend initial options, back-fill in default options
|
||||
var initialOpts = this.options[ name ] || {};
|
||||
this.options[ name ] = Mode.options ?
|
||||
utils.extend( Mode.options, initialOpts ) : initialOpts;
|
||||
// init layout mode instance
|
||||
this.modes[ name ] = new Mode( this );
|
||||
};
|
||||
|
||||
|
||||
proto.layout = function() {
|
||||
// if first time doing layout, do all magic
|
||||
if ( !this._isLayoutInited && this._getOption('initLayout') ) {
|
||||
this.arrange();
|
||||
return;
|
||||
}
|
||||
this._layout();
|
||||
};
|
||||
|
||||
// private method to be used in layout() & magic()
|
||||
proto._layout = function() {
|
||||
// don't animate first layout
|
||||
var isInstant = this._getIsInstant();
|
||||
// layout flow
|
||||
this._resetLayout();
|
||||
this._manageStamps();
|
||||
this.layoutItems( this.filteredItems, isInstant );
|
||||
|
||||
// flag for initalized
|
||||
this._isLayoutInited = true;
|
||||
};
|
||||
|
||||
// filter + sort + layout
|
||||
proto.arrange = function( opts ) {
|
||||
// set any options pass
|
||||
this.option( opts );
|
||||
this._getIsInstant();
|
||||
// filter, sort, and layout
|
||||
|
||||
// filter
|
||||
var filtered = this._filter( this.items );
|
||||
this.filteredItems = filtered.matches;
|
||||
|
||||
this._bindArrangeComplete();
|
||||
|
||||
if ( this._isInstant ) {
|
||||
this._noTransition( this._hideReveal, [ filtered ] );
|
||||
} else {
|
||||
this._hideReveal( filtered );
|
||||
}
|
||||
|
||||
this._sort();
|
||||
this._layout();
|
||||
};
|
||||
// alias to _init for main plugin method
|
||||
proto._init = proto.arrange;
|
||||
|
||||
proto._hideReveal = function( filtered ) {
|
||||
this.reveal( filtered.needReveal );
|
||||
this.hide( filtered.needHide );
|
||||
};
|
||||
|
||||
// HACK
|
||||
// Don't animate/transition first layout
|
||||
// Or don't animate/transition other layouts
|
||||
proto._getIsInstant = function() {
|
||||
var isLayoutInstant = this._getOption('layoutInstant');
|
||||
var isInstant = isLayoutInstant !== undefined ? isLayoutInstant :
|
||||
!this._isLayoutInited;
|
||||
this._isInstant = isInstant;
|
||||
return isInstant;
|
||||
};
|
||||
|
||||
// listen for layoutComplete, hideComplete and revealComplete
|
||||
// to trigger arrangeComplete
|
||||
proto._bindArrangeComplete = function() {
|
||||
// listen for 3 events to trigger arrangeComplete
|
||||
var isLayoutComplete, isHideComplete, isRevealComplete;
|
||||
var _this = this;
|
||||
function arrangeParallelCallback() {
|
||||
if ( isLayoutComplete && isHideComplete && isRevealComplete ) {
|
||||
_this.dispatchEvent( 'arrangeComplete', null, [ _this.filteredItems ] );
|
||||
}
|
||||
}
|
||||
this.once( 'layoutComplete', function() {
|
||||
isLayoutComplete = true;
|
||||
arrangeParallelCallback();
|
||||
});
|
||||
this.once( 'hideComplete', function() {
|
||||
isHideComplete = true;
|
||||
arrangeParallelCallback();
|
||||
});
|
||||
this.once( 'revealComplete', function() {
|
||||
isRevealComplete = true;
|
||||
arrangeParallelCallback();
|
||||
});
|
||||
};
|
||||
|
||||
// -------------------------- filter -------------------------- //
|
||||
|
||||
proto._filter = function( items ) {
|
||||
var filter = this.options.filter;
|
||||
filter = filter || '*';
|
||||
var matches = [];
|
||||
var hiddenMatched = [];
|
||||
var visibleUnmatched = [];
|
||||
|
||||
var test = this._getFilterTest( filter );
|
||||
|
||||
// test each item
|
||||
for ( var i=0; i < items.length; i++ ) {
|
||||
var item = items[i];
|
||||
if ( item.isIgnored ) {
|
||||
continue;
|
||||
}
|
||||
// add item to either matched or unmatched group
|
||||
var isMatched = test( item );
|
||||
// item.isFilterMatched = isMatched;
|
||||
// add to matches if its a match
|
||||
if ( isMatched ) {
|
||||
matches.push( item );
|
||||
}
|
||||
// add to additional group if item needs to be hidden or revealed
|
||||
if ( isMatched && item.isHidden ) {
|
||||
hiddenMatched.push( item );
|
||||
} else if ( !isMatched && !item.isHidden ) {
|
||||
visibleUnmatched.push( item );
|
||||
}
|
||||
}
|
||||
|
||||
// return collections of items to be manipulated
|
||||
return {
|
||||
matches: matches,
|
||||
needReveal: hiddenMatched,
|
||||
needHide: visibleUnmatched
|
||||
};
|
||||
};
|
||||
|
||||
// get a jQuery, function, or a matchesSelector test given the filter
|
||||
proto._getFilterTest = function( filter ) {
|
||||
if ( jQuery && this.options.isJQueryFiltering ) {
|
||||
// use jQuery
|
||||
return function( item ) {
|
||||
return jQuery( item.element ).is( filter );
|
||||
};
|
||||
}
|
||||
if ( typeof filter == 'function' ) {
|
||||
// use filter as function
|
||||
return function( item ) {
|
||||
return filter( item.element );
|
||||
};
|
||||
}
|
||||
// default, use filter as selector string
|
||||
return function( item ) {
|
||||
return matchesSelector( item.element, filter );
|
||||
};
|
||||
};
|
||||
|
||||
// -------------------------- sorting -------------------------- //
|
||||
|
||||
/**
|
||||
* @params {Array} elems
|
||||
* @public
|
||||
*/
|
||||
proto.updateSortData = function( elems ) {
|
||||
// get items
|
||||
var items;
|
||||
if ( elems ) {
|
||||
elems = utils.makeArray( elems );
|
||||
items = this.getItems( elems );
|
||||
} else {
|
||||
// update all items if no elems provided
|
||||
items = this.items;
|
||||
}
|
||||
|
||||
this._getSorters();
|
||||
this._updateItemsSortData( items );
|
||||
};
|
||||
|
||||
proto._getSorters = function() {
|
||||
var getSortData = this.options.getSortData;
|
||||
for ( var key in getSortData ) {
|
||||
var sorter = getSortData[ key ];
|
||||
this._sorters[ key ] = mungeSorter( sorter );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @params {Array} items - of Isotope.Items
|
||||
* @private
|
||||
*/
|
||||
proto._updateItemsSortData = function( items ) {
|
||||
// do not update if no items
|
||||
var len = items && items.length;
|
||||
|
||||
for ( var i=0; len && i < len; i++ ) {
|
||||
var item = items[i];
|
||||
item.updateSortData();
|
||||
}
|
||||
};
|
||||
|
||||
// ----- munge sorter ----- //
|
||||
|
||||
// encapsulate this, as we just need mungeSorter
|
||||
// other functions in here are just for munging
|
||||
var mungeSorter = ( function() {
|
||||
// add a magic layer to sorters for convienent shorthands
|
||||
// `.foo-bar` will use the text of .foo-bar querySelector
|
||||
// `[foo-bar]` will use attribute
|
||||
// you can also add parser
|
||||
// `.foo-bar parseInt` will parse that as a number
|
||||
function mungeSorter( sorter ) {
|
||||
// if not a string, return function or whatever it is
|
||||
if ( typeof sorter != 'string' ) {
|
||||
return sorter;
|
||||
}
|
||||
// parse the sorter string
|
||||
var args = trim( sorter ).split(' ');
|
||||
var query = args[0];
|
||||
// check if query looks like [an-attribute]
|
||||
var attrMatch = query.match( /^\[(.+)\]$/ );
|
||||
var attr = attrMatch && attrMatch[1];
|
||||
var getValue = getValueGetter( attr, query );
|
||||
// use second argument as a parser
|
||||
var parser = Isotope.sortDataParsers[ args[1] ];
|
||||
// parse the value, if there was a parser
|
||||
sorter = parser ? function( elem ) {
|
||||
return elem && parser( getValue( elem ) );
|
||||
} :
|
||||
// otherwise just return value
|
||||
function( elem ) {
|
||||
return elem && getValue( elem );
|
||||
};
|
||||
|
||||
return sorter;
|
||||
}
|
||||
|
||||
// get an attribute getter, or get text of the querySelector
|
||||
function getValueGetter( attr, query ) {
|
||||
// if query looks like [foo-bar], get attribute
|
||||
if ( attr ) {
|
||||
return function getAttribute( elem ) {
|
||||
return elem.getAttribute( attr );
|
||||
};
|
||||
}
|
||||
|
||||
// otherwise, assume its a querySelector, and get its text
|
||||
return function getChildText( elem ) {
|
||||
var child = elem.querySelector( query );
|
||||
return child && child.textContent;
|
||||
};
|
||||
}
|
||||
|
||||
return mungeSorter;
|
||||
})();
|
||||
|
||||
// parsers used in getSortData shortcut strings
|
||||
Isotope.sortDataParsers = {
|
||||
'parseInt': function( val ) {
|
||||
return parseInt( val, 10 );
|
||||
},
|
||||
'parseFloat': function( val ) {
|
||||
return parseFloat( val );
|
||||
}
|
||||
};
|
||||
|
||||
// ----- sort method ----- //
|
||||
|
||||
// sort filteredItem order
|
||||
proto._sort = function() {
|
||||
var sortByOpt = this.options.sortBy;
|
||||
if ( !sortByOpt ) {
|
||||
return;
|
||||
}
|
||||
// concat all sortBy and sortHistory
|
||||
var sortBys = [].concat.apply( sortByOpt, this.sortHistory );
|
||||
// sort magic
|
||||
var itemSorter = getItemSorter( sortBys, this.options.sortAscending );
|
||||
this.filteredItems.sort( itemSorter );
|
||||
// keep track of sortBy History
|
||||
if ( sortByOpt != this.sortHistory[0] ) {
|
||||
// add to front, oldest goes in last
|
||||
this.sortHistory.unshift( sortByOpt );
|
||||
}
|
||||
};
|
||||
|
||||
// returns a function used for sorting
|
||||
function getItemSorter( sortBys, sortAsc ) {
|
||||
return function sorter( itemA, itemB ) {
|
||||
// cycle through all sortKeys
|
||||
for ( var i = 0; i < sortBys.length; i++ ) {
|
||||
var sortBy = sortBys[i];
|
||||
var a = itemA.sortData[ sortBy ];
|
||||
var b = itemB.sortData[ sortBy ];
|
||||
if ( a > b || a < b ) {
|
||||
// if sortAsc is an object, use the value given the sortBy key
|
||||
var isAscending = sortAsc[ sortBy ] !== undefined ? sortAsc[ sortBy ] : sortAsc;
|
||||
var direction = isAscending ? 1 : -1;
|
||||
return ( a > b ? 1 : -1 ) * direction;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
// -------------------------- methods -------------------------- //
|
||||
|
||||
// get layout mode
|
||||
proto._mode = function() {
|
||||
var layoutMode = this.options.layoutMode;
|
||||
var mode = this.modes[ layoutMode ];
|
||||
if ( !mode ) {
|
||||
// TODO console.error
|
||||
throw new Error( 'No layout mode: ' + layoutMode );
|
||||
}
|
||||
// HACK sync mode's options
|
||||
// any options set after init for layout mode need to be synced
|
||||
mode.options = this.options[ layoutMode ];
|
||||
return mode;
|
||||
};
|
||||
|
||||
proto._resetLayout = function() {
|
||||
// trigger original reset layout
|
||||
Outlayer.prototype._resetLayout.call( this );
|
||||
this._mode()._resetLayout();
|
||||
};
|
||||
|
||||
proto._getItemLayoutPosition = function( item ) {
|
||||
return this._mode()._getItemLayoutPosition( item );
|
||||
};
|
||||
|
||||
proto._manageStamp = function( stamp ) {
|
||||
this._mode()._manageStamp( stamp );
|
||||
};
|
||||
|
||||
proto._getContainerSize = function() {
|
||||
return this._mode()._getContainerSize();
|
||||
};
|
||||
|
||||
proto.needsResizeLayout = function() {
|
||||
return this._mode().needsResizeLayout();
|
||||
};
|
||||
|
||||
// -------------------------- adding & removing -------------------------- //
|
||||
|
||||
// HEADS UP overwrites default Outlayer appended
|
||||
proto.appended = function( elems ) {
|
||||
var items = this.addItems( elems );
|
||||
if ( !items.length ) {
|
||||
return;
|
||||
}
|
||||
// filter, layout, reveal new items
|
||||
var filteredItems = this._filterRevealAdded( items );
|
||||
// add to filteredItems
|
||||
this.filteredItems = this.filteredItems.concat( filteredItems );
|
||||
};
|
||||
|
||||
// HEADS UP overwrites default Outlayer prepended
|
||||
proto.prepended = function( elems ) {
|
||||
var items = this._itemize( elems );
|
||||
if ( !items.length ) {
|
||||
return;
|
||||
}
|
||||
// start new layout
|
||||
this._resetLayout();
|
||||
this._manageStamps();
|
||||
// filter, layout, reveal new items
|
||||
var filteredItems = this._filterRevealAdded( items );
|
||||
// layout previous items
|
||||
this.layoutItems( this.filteredItems );
|
||||
// add to items and filteredItems
|
||||
this.filteredItems = filteredItems.concat( this.filteredItems );
|
||||
this.items = items.concat( this.items );
|
||||
};
|
||||
|
||||
proto._filterRevealAdded = function( items ) {
|
||||
var filtered = this._filter( items );
|
||||
this.hide( filtered.needHide );
|
||||
// reveal all new items
|
||||
this.reveal( filtered.matches );
|
||||
// layout new items, no transition
|
||||
this.layoutItems( filtered.matches, true );
|
||||
return filtered.matches;
|
||||
};
|
||||
|
||||
/**
|
||||
* Filter, sort, and layout newly-appended item elements
|
||||
* @param {Array or NodeList or Element} elems
|
||||
*/
|
||||
proto.insert = function( elems ) {
|
||||
var items = this.addItems( elems );
|
||||
if ( !items.length ) {
|
||||
return;
|
||||
}
|
||||
// append item elements
|
||||
var i, item;
|
||||
var len = items.length;
|
||||
for ( i=0; i < len; i++ ) {
|
||||
item = items[i];
|
||||
this.element.appendChild( item.element );
|
||||
}
|
||||
// filter new stuff
|
||||
var filteredInsertItems = this._filter( items ).matches;
|
||||
// set flag
|
||||
for ( i=0; i < len; i++ ) {
|
||||
items[i].isLayoutInstant = true;
|
||||
}
|
||||
this.arrange();
|
||||
// reset flag
|
||||
for ( i=0; i < len; i++ ) {
|
||||
delete items[i].isLayoutInstant;
|
||||
}
|
||||
this.reveal( filteredInsertItems );
|
||||
};
|
||||
|
||||
var _remove = proto.remove;
|
||||
proto.remove = function( elems ) {
|
||||
elems = utils.makeArray( elems );
|
||||
var removeItems = this.getItems( elems );
|
||||
// do regular thing
|
||||
_remove.call( this, elems );
|
||||
// bail if no items to remove
|
||||
var len = removeItems && removeItems.length;
|
||||
// remove elems from filteredItems
|
||||
for ( var i=0; len && i < len; i++ ) {
|
||||
var item = removeItems[i];
|
||||
// remove item from collection
|
||||
utils.removeFrom( this.filteredItems, item );
|
||||
}
|
||||
};
|
||||
|
||||
proto.shuffle = function() {
|
||||
// update random sortData
|
||||
for ( var i=0; i < this.items.length; i++ ) {
|
||||
var item = this.items[i];
|
||||
item.sortData.random = Math.random();
|
||||
}
|
||||
this.options.sortBy = 'random';
|
||||
this._sort();
|
||||
this._layout();
|
||||
};
|
||||
|
||||
/**
|
||||
* trigger fn without transition
|
||||
* kind of hacky to have this in the first place
|
||||
* @param {Function} fn
|
||||
* @param {Array} args
|
||||
* @returns ret
|
||||
* @private
|
||||
*/
|
||||
proto._noTransition = function( fn, args ) {
|
||||
// save transitionDuration before disabling
|
||||
var transitionDuration = this.options.transitionDuration;
|
||||
// disable transition
|
||||
this.options.transitionDuration = 0;
|
||||
// do it
|
||||
var returnValue = fn.apply( this, args );
|
||||
// re-enable transition for reveal
|
||||
this.options.transitionDuration = transitionDuration;
|
||||
return returnValue;
|
||||
};
|
||||
|
||||
// ----- helper methods ----- //
|
||||
|
||||
/**
|
||||
* getter method for getting filtered item elements
|
||||
* @returns {Array} elems - collection of item elements
|
||||
*/
|
||||
proto.getFilteredItemElements = function() {
|
||||
return this.filteredItems.map( function( item ) {
|
||||
return item.element;
|
||||
});
|
||||
};
|
||||
|
||||
// ----- ----- //
|
||||
|
||||
return Isotope;
|
||||
|
||||
}));
|
||||
77
_site/bower_components/isotope/js/item.js
vendored
Normal file
77
_site/bower_components/isotope/js/item.js
vendored
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/**
|
||||
* Isotope Item
|
||||
**/
|
||||
|
||||
( function( window, factory ) {
|
||||
// universal module definition
|
||||
/* jshint strict: false */ /*globals define, module, require */
|
||||
if ( typeof define == 'function' && define.amd ) {
|
||||
// AMD
|
||||
define( [
|
||||
'outlayer/outlayer'
|
||||
],
|
||||
factory );
|
||||
} else if ( typeof module == 'object' && module.exports ) {
|
||||
// CommonJS
|
||||
module.exports = factory(
|
||||
require('outlayer')
|
||||
);
|
||||
} else {
|
||||
// browser global
|
||||
window.Isotope = window.Isotope || {};
|
||||
window.Isotope.Item = factory(
|
||||
window.Outlayer
|
||||
);
|
||||
}
|
||||
|
||||
}( window, function factory( Outlayer ) {
|
||||
'use strict';
|
||||
|
||||
// -------------------------- Item -------------------------- //
|
||||
|
||||
// sub-class Outlayer Item
|
||||
function Item() {
|
||||
Outlayer.Item.apply( this, arguments );
|
||||
}
|
||||
|
||||
var proto = Item.prototype = Object.create( Outlayer.Item.prototype );
|
||||
|
||||
var _create = proto._create;
|
||||
proto._create = function() {
|
||||
// assign id, used for original-order sorting
|
||||
this.id = this.layout.itemGUID++;
|
||||
_create.call( this );
|
||||
this.sortData = {};
|
||||
};
|
||||
|
||||
proto.updateSortData = function() {
|
||||
if ( this.isIgnored ) {
|
||||
return;
|
||||
}
|
||||
// default sorters
|
||||
this.sortData.id = this.id;
|
||||
// for backward compatibility
|
||||
this.sortData['original-order'] = this.id;
|
||||
this.sortData.random = Math.random();
|
||||
// go thru getSortData obj and apply the sorters
|
||||
var getSortData = this.layout.options.getSortData;
|
||||
var sorters = this.layout._sorters;
|
||||
for ( var key in getSortData ) {
|
||||
var sorter = sorters[ key ];
|
||||
this.sortData[ key ] = sorter( this.element, this );
|
||||
}
|
||||
};
|
||||
|
||||
var _destroy = proto.destroy;
|
||||
proto.destroy = function() {
|
||||
// call super
|
||||
_destroy.apply( this, arguments );
|
||||
// reset display, #741
|
||||
this.css({
|
||||
display: ''
|
||||
});
|
||||
};
|
||||
|
||||
return Item;
|
||||
|
||||
}));
|
||||
157
_site/bower_components/isotope/js/layout-mode.js
vendored
Normal file
157
_site/bower_components/isotope/js/layout-mode.js
vendored
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
/**
|
||||
* Isotope LayoutMode
|
||||
*/
|
||||
|
||||
( function( window, factory ) {
|
||||
// universal module definition
|
||||
/* jshint strict: false */ /*globals define, module, require */
|
||||
if ( typeof define == 'function' && define.amd ) {
|
||||
// AMD
|
||||
define( [
|
||||
'get-size/get-size',
|
||||
'outlayer/outlayer'
|
||||
],
|
||||
factory );
|
||||
} else if ( typeof module == 'object' && module.exports ) {
|
||||
// CommonJS
|
||||
module.exports = factory(
|
||||
require('get-size'),
|
||||
require('outlayer')
|
||||
);
|
||||
} else {
|
||||
// browser global
|
||||
window.Isotope = window.Isotope || {};
|
||||
window.Isotope.LayoutMode = factory(
|
||||
window.getSize,
|
||||
window.Outlayer
|
||||
);
|
||||
}
|
||||
|
||||
}( window, function factory( getSize, Outlayer ) {
|
||||
'use strict';
|
||||
|
||||
// layout mode class
|
||||
function LayoutMode( isotope ) {
|
||||
this.isotope = isotope;
|
||||
// link properties
|
||||
if ( isotope ) {
|
||||
this.options = isotope.options[ this.namespace ];
|
||||
this.element = isotope.element;
|
||||
this.items = isotope.filteredItems;
|
||||
this.size = isotope.size;
|
||||
}
|
||||
}
|
||||
|
||||
var proto = LayoutMode.prototype;
|
||||
|
||||
/**
|
||||
* some methods should just defer to default Outlayer method
|
||||
* and reference the Isotope instance as `this`
|
||||
**/
|
||||
var facadeMethods = [
|
||||
'_resetLayout',
|
||||
'_getItemLayoutPosition',
|
||||
'_manageStamp',
|
||||
'_getContainerSize',
|
||||
'_getElementOffset',
|
||||
'needsResizeLayout',
|
||||
'_getOption'
|
||||
];
|
||||
|
||||
facadeMethods.forEach( function( methodName ) {
|
||||
proto[ methodName ] = function() {
|
||||
return Outlayer.prototype[ methodName ].apply( this.isotope, arguments );
|
||||
};
|
||||
});
|
||||
|
||||
// ----- ----- //
|
||||
|
||||
// for horizontal layout modes, check vertical size
|
||||
proto.needsVerticalResizeLayout = function() {
|
||||
// don't trigger if size did not change
|
||||
var size = getSize( this.isotope.element );
|
||||
// check that this.size and size are there
|
||||
// IE8 triggers resize on body size change, so they might not be
|
||||
var hasSizes = this.isotope.size && size;
|
||||
return hasSizes && size.innerHeight != this.isotope.size.innerHeight;
|
||||
};
|
||||
|
||||
// ----- measurements ----- //
|
||||
|
||||
proto._getMeasurement = function() {
|
||||
this.isotope._getMeasurement.apply( this, arguments );
|
||||
};
|
||||
|
||||
proto.getColumnWidth = function() {
|
||||
this.getSegmentSize( 'column', 'Width' );
|
||||
};
|
||||
|
||||
proto.getRowHeight = function() {
|
||||
this.getSegmentSize( 'row', 'Height' );
|
||||
};
|
||||
|
||||
/**
|
||||
* get columnWidth or rowHeight
|
||||
* segment: 'column' or 'row'
|
||||
* size 'Width' or 'Height'
|
||||
**/
|
||||
proto.getSegmentSize = function( segment, size ) {
|
||||
var segmentName = segment + size;
|
||||
var outerSize = 'outer' + size;
|
||||
// columnWidth / outerWidth // rowHeight / outerHeight
|
||||
this._getMeasurement( segmentName, outerSize );
|
||||
// got rowHeight or columnWidth, we can chill
|
||||
if ( this[ segmentName ] ) {
|
||||
return;
|
||||
}
|
||||
// fall back to item of first element
|
||||
var firstItemSize = this.getFirstItemSize();
|
||||
this[ segmentName ] = firstItemSize && firstItemSize[ outerSize ] ||
|
||||
// or size of container
|
||||
this.isotope.size[ 'inner' + size ];
|
||||
};
|
||||
|
||||
proto.getFirstItemSize = function() {
|
||||
var firstItem = this.isotope.filteredItems[0];
|
||||
return firstItem && firstItem.element && getSize( firstItem.element );
|
||||
};
|
||||
|
||||
// ----- methods that should reference isotope ----- //
|
||||
|
||||
proto.layout = function() {
|
||||
this.isotope.layout.apply( this.isotope, arguments );
|
||||
};
|
||||
|
||||
proto.getSize = function() {
|
||||
this.isotope.getSize();
|
||||
this.size = this.isotope.size;
|
||||
};
|
||||
|
||||
// -------------------------- create -------------------------- //
|
||||
|
||||
LayoutMode.modes = {};
|
||||
|
||||
LayoutMode.create = function( namespace, options ) {
|
||||
|
||||
function Mode() {
|
||||
LayoutMode.apply( this, arguments );
|
||||
}
|
||||
|
||||
Mode.prototype = Object.create( proto );
|
||||
Mode.prototype.constructor = Mode;
|
||||
|
||||
// default options
|
||||
if ( options ) {
|
||||
Mode.options = options;
|
||||
}
|
||||
|
||||
Mode.prototype.namespace = namespace;
|
||||
// register in Isotope
|
||||
LayoutMode.modes[ namespace ] = Mode;
|
||||
|
||||
return Mode;
|
||||
};
|
||||
|
||||
return LayoutMode;
|
||||
|
||||
}));
|
||||
68
_site/bower_components/isotope/js/layout-modes/fit-rows.js
vendored
Normal file
68
_site/bower_components/isotope/js/layout-modes/fit-rows.js
vendored
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/**
|
||||
* fitRows layout mode
|
||||
*/
|
||||
|
||||
( function( window, factory ) {
|
||||
// universal module definition
|
||||
/* jshint strict: false */ /*globals define, module, require */
|
||||
if ( typeof define == 'function' && define.amd ) {
|
||||
// AMD
|
||||
define( [
|
||||
'../layout-mode'
|
||||
],
|
||||
factory );
|
||||
} else if ( typeof exports == 'object' ) {
|
||||
// CommonJS
|
||||
module.exports = factory(
|
||||
require('../layout-mode')
|
||||
);
|
||||
} else {
|
||||
// browser global
|
||||
factory(
|
||||
window.Isotope.LayoutMode
|
||||
);
|
||||
}
|
||||
|
||||
}( window, function factory( LayoutMode ) {
|
||||
'use strict';
|
||||
|
||||
var FitRows = LayoutMode.create('fitRows');
|
||||
|
||||
var proto = FitRows.prototype;
|
||||
|
||||
proto._resetLayout = function() {
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.maxY = 0;
|
||||
this._getMeasurement( 'gutter', 'outerWidth' );
|
||||
};
|
||||
|
||||
proto._getItemLayoutPosition = function( item ) {
|
||||
item.getSize();
|
||||
|
||||
var itemWidth = item.size.outerWidth + this.gutter;
|
||||
// if this element cannot fit in the current row
|
||||
var containerWidth = this.isotope.size.innerWidth + this.gutter;
|
||||
if ( this.x !== 0 && itemWidth + this.x > containerWidth ) {
|
||||
this.x = 0;
|
||||
this.y = this.maxY;
|
||||
}
|
||||
|
||||
var position = {
|
||||
x: this.x,
|
||||
y: this.y
|
||||
};
|
||||
|
||||
this.maxY = Math.max( this.maxY, this.y + item.size.outerHeight );
|
||||
this.x += itemWidth;
|
||||
|
||||
return position;
|
||||
};
|
||||
|
||||
proto._getContainerSize = function() {
|
||||
return { height: this.maxY };
|
||||
};
|
||||
|
||||
return FitRows;
|
||||
|
||||
}));
|
||||
74
_site/bower_components/isotope/js/layout-modes/masonry.js
vendored
Normal file
74
_site/bower_components/isotope/js/layout-modes/masonry.js
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/*!
|
||||
* Masonry layout mode
|
||||
* sub-classes Masonry
|
||||
* http://masonry.desandro.com
|
||||
*/
|
||||
|
||||
( function( window, factory ) {
|
||||
// universal module definition
|
||||
/* jshint strict: false */ /*globals define, module, require */
|
||||
if ( typeof define == 'function' && define.amd ) {
|
||||
// AMD
|
||||
define( [
|
||||
'../layout-mode',
|
||||
'masonry/masonry'
|
||||
],
|
||||
factory );
|
||||
} else if ( typeof module == 'object' && module.exports ) {
|
||||
// CommonJS
|
||||
module.exports = factory(
|
||||
require('../layout-mode'),
|
||||
require('masonry-layout')
|
||||
);
|
||||
} else {
|
||||
// browser global
|
||||
factory(
|
||||
window.Isotope.LayoutMode,
|
||||
window.Masonry
|
||||
);
|
||||
}
|
||||
|
||||
}( window, function factory( LayoutMode, Masonry ) {
|
||||
'use strict';
|
||||
|
||||
// -------------------------- masonryDefinition -------------------------- //
|
||||
|
||||
// create an Outlayer layout class
|
||||
var MasonryMode = LayoutMode.create('masonry');
|
||||
|
||||
var proto = MasonryMode.prototype;
|
||||
|
||||
var keepModeMethods = {
|
||||
_getElementOffset: true,
|
||||
layout: true,
|
||||
_getMeasurement: true
|
||||
};
|
||||
|
||||
// inherit Masonry prototype
|
||||
for ( var method in Masonry.prototype ) {
|
||||
// do not inherit mode methods
|
||||
if ( !keepModeMethods[ method ] ) {
|
||||
proto[ method ] = Masonry.prototype[ method ];
|
||||
}
|
||||
}
|
||||
|
||||
var measureColumns = proto.measureColumns;
|
||||
proto.measureColumns = function() {
|
||||
// set items, used if measuring first item
|
||||
this.items = this.isotope.filteredItems;
|
||||
measureColumns.call( this );
|
||||
};
|
||||
|
||||
// point to mode options for fitWidth
|
||||
var _getOption = proto._getOption;
|
||||
proto._getOption = function( option ) {
|
||||
if ( option == 'fitWidth' ) {
|
||||
return this.options.isFitWidth !== undefined ?
|
||||
this.options.isFitWidth : this.options.fitWidth;
|
||||
}
|
||||
return _getOption.apply( this.isotope, arguments );
|
||||
};
|
||||
|
||||
return MasonryMode;
|
||||
|
||||
}));
|
||||
54
_site/bower_components/isotope/js/layout-modes/vertical.js
vendored
Normal file
54
_site/bower_components/isotope/js/layout-modes/vertical.js
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
* vertical layout mode
|
||||
*/
|
||||
|
||||
( function( window, factory ) {
|
||||
// universal module definition
|
||||
/* jshint strict: false */ /*globals define, module, require */
|
||||
if ( typeof define == 'function' && define.amd ) {
|
||||
// AMD
|
||||
define( [
|
||||
'../layout-mode'
|
||||
],
|
||||
factory );
|
||||
} else if ( typeof module == 'object' && module.exports ) {
|
||||
// CommonJS
|
||||
module.exports = factory(
|
||||
require('../layout-mode')
|
||||
);
|
||||
} else {
|
||||
// browser global
|
||||
factory(
|
||||
window.Isotope.LayoutMode
|
||||
);
|
||||
}
|
||||
|
||||
}( window, function factory( LayoutMode ) {
|
||||
'use strict';
|
||||
|
||||
var Vertical = LayoutMode.create( 'vertical', {
|
||||
horizontalAlignment: 0
|
||||
});
|
||||
|
||||
var proto = Vertical.prototype;
|
||||
|
||||
proto._resetLayout = function() {
|
||||
this.y = 0;
|
||||
};
|
||||
|
||||
proto._getItemLayoutPosition = function( item ) {
|
||||
item.getSize();
|
||||
var x = ( this.isotope.size.innerWidth - item.size.outerWidth ) *
|
||||
this.options.horizontalAlignment;
|
||||
var y = this.y;
|
||||
this.y += item.size.outerHeight;
|
||||
return { x: x, y: y };
|
||||
};
|
||||
|
||||
proto._getContainerSize = function() {
|
||||
return { height: this.y };
|
||||
};
|
||||
|
||||
return Vertical;
|
||||
|
||||
}));
|
||||
Loading…
Add table
Add a link
Reference in a new issue