Commit fdc1c9de786afaa8a7a7713135eaac19fefd2f8f

Authored by Yarik
1 parent 8b9f2521

test

common/components/UserStore.php 0 → 100644
  1 +<?php
  2 +namespace common\components;
  3 +
  4 +use yii\base\Exception;
  5 +
  6 +class UserStore {
  7 +
  8 + private $users = [];
  9 +
  10 + function addUser( $name, $email, $pass){
  11 + if(isset($this->users[$email])){
  12 + throw new Exception("Пользователь {$email} уже зарегистрирован");
  13 + }
  14 +
  15 + if (strlen($pass) < 5 ){
  16 + throw new Exception(
  17 + "Длинна пароля должна быть больше 5 символов"
  18 + );
  19 + }
  20 +
  21 + $this->users[$email] = [
  22 + 'pass' => $pass,
  23 + 'email' => $email,
  24 + 'name' => $name
  25 + ];
  26 +
  27 + return true;
  28 + }
  29 +
  30 + function notifyPasswordFailure($email){
  31 + if(isset($this->users[$email])){
  32 + $this->users[$email]['failed'] = time();
  33 + }
  34 + }
  35 +
  36 + function getUser($email){
  37 + return ($this->users[$email]);
  38 + }
  39 +
  40 +
  41 +
  42 +}
0 43 \ No newline at end of file
... ...
common/components/Validator.php 0 → 100644
  1 +<?php
  2 +namespace common\components;
  3 +
  4 +
  5 +class Validator {
  6 + private $store;
  7 +
  8 + public function __construct(UserStore $store){
  9 + $this->store = $store;
  10 + }
  11 +
  12 + public function validateUser($email, $pass){
  13 + if(!is_array($user = $this->store->getUser($email))){
  14 + return false;
  15 + }
  16 +
  17 + if($user['pass'] == $pass){
  18 + return true;
  19 + }
  20 +
  21 + $this->store->notifyPasswordFailure($email);
  22 +
  23 + return false;
  24 + }
  25 +
  26 +
  27 +}
0 28 \ No newline at end of file
... ...
common/models/Portfolio.php
... ... @@ -187,4 +187,9 @@
187 187 {
188 188 return $this->hasOne(Gallery::className(), [ 'gallery_id' => 'gallery_id' ]);
189 189 }
  190 +
  191 + public function getPortfolioUsers()
  192 + {
  193 + return $this->hasMany(PortfolioUser::className(), ['portfolio_id' => 'portfolio_id'])->with('user');
  194 + }
190 195 }
... ...
common/models/PortfolioUser.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace common\models;
  4 +
  5 +use Yii;
  6 +
  7 +/**
  8 + * This is the model class for table "portfolio_user".
  9 + *
  10 + * @property integer $portfolio_user_id
  11 + * @property integer $portfolio_id
  12 + * @property integer $user_id
  13 + * @property string $position
  14 + * @property integer $time
  15 + * @property integer $status
  16 + *
  17 + * @property Portfolio $portfolio
  18 + * @property User $user
  19 + */
  20 +class PortfolioUser extends \yii\db\ActiveRecord
  21 +{
  22 + /**
  23 + * @inheritdoc
  24 + */
  25 + public static function tableName()
  26 + {
  27 + return 'portfolio_user';
  28 + }
  29 +
  30 + /**
  31 + * @inheritdoc
  32 + */
  33 + public function rules()
  34 + {
  35 + return [
  36 + [['portfolio_id', 'user_id'], 'required'],
  37 + [['portfolio_id', 'user_id', 'time'], 'integer'],
  38 + [['position'], 'string', 'max' => 255],
  39 + [['portfolio_id', 'user_id'], 'unique', 'targetAttribute' => ['portfolio_id', 'user_id'], 'message' => 'The combination of Portfolio ID and User ID has already been taken.'],
  40 + [['portfolio_id'], 'exist', 'skipOnError' => true, 'targetClass' => Portfolio::className(), 'targetAttribute' => ['portfolio_id' => 'portfolio_id']],
  41 + [['user_id'], 'exist', 'skipOnError' => true, 'targetClass' => User::className(), 'targetAttribute' => ['user_id' => 'id']],
  42 + ];
  43 + }
  44 +
  45 + /**
  46 + * @inheritdoc
  47 + */
  48 + public function attributeLabels()
  49 + {
  50 + return [
  51 + 'portfolio_user_id' => Yii::t('app', 'Portfolio User ID'),
  52 + 'portfolio_id' => Yii::t('app', 'Portfolio ID'),
  53 + 'user_id' => Yii::t('app', 'User ID'),
  54 + 'position' => Yii::t('app', 'Position'),
  55 + 'time' => Yii::t('app', 'Time'),
  56 + 'status' => Yii::t('app', 'Status'),
  57 + ];
  58 + }
  59 +
  60 + /**
  61 + * @return \yii\db\ActiveQuery
  62 + */
  63 + public function getPortfolio()
  64 + {
  65 + return $this->hasOne(Portfolio::className(), ['portfolio_id' => 'portfolio_id']);
  66 + }
  67 +
  68 + /**
  69 + * @return \yii\db\ActiveQuery
  70 + */
  71 + public function getUser()
  72 + {
  73 + return $this->hasOne(User::className(), ['id' => 'user_id']);
  74 + }
  75 +}
... ...
common/models/UserSearch.php 0 → 100644
  1 +<?php
  2 +
  3 + namespace common\models;
  4 +
  5 + use Yii;
  6 + use yii\base\Model;
  7 + use yii\data\ActiveDataProvider;
  8 + use yii\data\Pagination;
  9 + use yii\data\Sort;
  10 +
  11 + /**
  12 + * UserSearch represents the model behind the search form about `common\models\User`.
  13 + */
  14 + class UserSearch extends User
  15 + {
  16 +
  17 + public $name_search;
  18 +
  19 + public $surname_search;
  20 +
  21 + public $specialization;
  22 +
  23 + /**
  24 + * @inheritdoc
  25 + */
  26 + public function rules()
  27 + {
  28 + return [
  29 + [
  30 + [ 'id' ],
  31 + 'integer',
  32 + 'min' => 1,
  33 + ],
  34 + [
  35 + [
  36 + 'name_search',
  37 + 'surname_search',
  38 + 'specialization',
  39 + ],
  40 + 'safe',
  41 + ],
  42 + ];
  43 + }
  44 +
  45 + /**
  46 + * @inheritdoc
  47 + */
  48 + public function scenarios()
  49 + {
  50 + return Model::scenarios();
  51 + }
  52 +
  53 + /**
  54 + * Creates data provider instance with search query applied
  55 + *
  56 + * @param array $params
  57 + *
  58 + * @return ActiveDataProvider
  59 + */
  60 + public function search($params)
  61 + {
  62 + $query = User::find()
  63 + ->joinWith('userInfo');
  64 +
  65 + $dataProvider = new ActiveDataProvider([
  66 + 'query' => $query,
  67 + 'pagination' => new Pagination([
  68 + 'pageSize' => 10,
  69 + ]),
  70 + 'sort' => new Sort([
  71 + 'defaultOrder' => [
  72 + 'id' => SORT_ASC,
  73 + ],
  74 + ]),
  75 + ]);
  76 +
  77 + $this->load($params);
  78 +
  79 + if(!$this->validate()) {
  80 + // uncomment the following line if you do not want to return any records when validation fails
  81 + // $query->where('0=1');
  82 + return $dataProvider;
  83 + }
  84 +
  85 + if(!empty( $this->specialization )) {
  86 + $specialization_id = User::find()
  87 + ->joinWith('specializations')
  88 + ->select(['user.id'], 'DISTINCT')
  89 + ->where([
  90 + 'like',
  91 + 'LOWER(specialization.specialization_name)',
  92 + mb_strtolower($this->specialization),
  93 + ])
  94 + ->asArray()
  95 + ->column();
  96 + $query->andWhere(['user.id' => $specialization_id]);
  97 + }
  98 +
  99 + $query->andFilterWhere([
  100 + 'id' => $this->id,
  101 + ]);
  102 +
  103 + $query->andFilterWhere([
  104 + 'like',
  105 + 'LOWER(firstname)',
  106 + mb_strtolower($this->name_search),
  107 + ])
  108 + ->andFilterWhere([
  109 + 'like',
  110 + 'LOWER(lastname)',
  111 + mb_strtolower($this->surname_search),
  112 + ]);
  113 +
  114 + return $dataProvider;
  115 + }
  116 + }
... ...
common/modules/comment/assets/CommentAsset.php
... ... @@ -3,6 +3,7 @@
3 3  
4 4 class CommentAsset extends \yii\web\AssetBundle
5 5 {
  6 +
6 7 public $sourcePath = '@common/modules/comment/resources';
7 8  
8 9 public $css = [
... ... @@ -18,4 +19,8 @@
18 19 '\yii\web\JqueryAsset',
19 20 ];
20 21  
  22 + public $jsOptions = [
  23 + 'position' => \yii\web\View::POS_READY,
  24 + ];
  25 +
21 26 }
22 27 \ No newline at end of file
... ...
common/modules/comment/models/Comment.php
... ... @@ -133,6 +133,9 @@
133 133 parent::afterSave($insert, $changedAttributes);
134 134 }
135 135  
  136 + /**
  137 + * @inheritdoc
  138 + */
136 139 public static function tableName()
137 140 {
138 141 return '{{%comment}}';
... ...
composer.json
... ... @@ -29,7 +29,9 @@
29 29 "kartik-v/yii2-widget-colorinput": "*",
30 30 "2amigos/yii2-transliterator-helper": "*",
31 31 "rmrevin/yii2-comments": "1.4.*",
32   - "codeception/codeception":"*"
  32 + "codeception/codeception":"*",
  33 + "yiisoft/yii2-codeception": "~2.0.0",
  34 + "bower-asset/fancybox": "^2.1"
33 35 },
34 36 "require-dev": {
35 37 "yiisoft/yii2-debug": "*",
... ...
composer.lock
... ... @@ -4,8 +4,8 @@
4 4 "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5 5 "This file is @generated automatically"
6 6 ],
7   - "hash": "339705c7dacfdc2f67cc7fccc576934b",
8   - "content-hash": "a1a45a52bb26fe4e63dfccd69d0a3991",
  7 + "hash": "663167525967cc58c1d361d1e98c002f",
  8 + "content-hash": "f093c935fec42d8be127e4a2cf8fe95f",
9 9 "packages": [
10 10 {
11 11 "name": "2amigos/yii2-transliterator-helper",
... ... @@ -199,6 +199,22 @@
199 199 ]
200 200 },
201 201 {
  202 + "name": "bower-asset/fancybox",
  203 + "version": "v2.1.5",
  204 + "source": {
  205 + "type": "git",
  206 + "url": "https://github.com/fancyapps/fancyBox.git",
  207 + "reference": "e2248f468dc4b45f5b1ef1776bde958b2b52775d"
  208 + },
  209 + "dist": {
  210 + "type": "zip",
  211 + "url": "https://api.github.com/repos/fancyapps/fancyBox/zipball/e2248f468dc4b45f5b1ef1776bde958b2b52775d",
  212 + "reference": "e2248f468dc4b45f5b1ef1776bde958b2b52775d",
  213 + "shasum": ""
  214 + },
  215 + "type": "bower-asset-library"
  216 + },
  217 + {
202 218 "name": "bower-asset/fontawesome",
203 219 "version": "v4.5.0",
204 220 "source": {
... ... @@ -413,7 +429,8 @@
413 429 },
414 430 "license": [
415 431 "MIT"
416   - ]
  432 + ],
  433 + "time": "2015-12-31 08:33:51"
417 434 },
418 435 {
419 436 "name": "cebe/markdown",
... ... @@ -524,12 +541,12 @@
524 541 "source": {
525 542 "type": "git",
526 543 "url": "https://github.com/Codeception/Codeception.git",
527   - "reference": "a04ceaea52d2a050d8df19df1a85fb1b24456477"
  544 + "reference": "8d4d11c900effead558d6b474ca5a9e1b651722e"
528 545 },
529 546 "dist": {
530 547 "type": "zip",
531   - "url": "https://api.github.com/repos/Codeception/Codeception/zipball/a04ceaea52d2a050d8df19df1a85fb1b24456477",
532   - "reference": "a04ceaea52d2a050d8df19df1a85fb1b24456477",
  548 + "url": "https://api.github.com/repos/Codeception/Codeception/zipball/8d4d11c900effead558d6b474ca5a9e1b651722e",
  549 + "reference": "8d4d11c900effead558d6b474ca5a9e1b651722e",
533 550 "shasum": ""
534 551 },
535 552 "require": {
... ... @@ -601,7 +618,7 @@
601 618 "functional testing",
602 619 "unit testing"
603 620 ],
604   - "time": "2016-03-26 21:39:36"
  621 + "time": "2016-04-04 08:29:59"
605 622 },
606 623 {
607 624 "name": "developeruz/yii2-db-rbac",
... ... @@ -704,12 +721,12 @@
704 721 "source": {
705 722 "type": "git",
706 723 "url": "https://github.com/doctrine/instantiator.git",
707   - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
  724 + "reference": "416fb8ad1d095a87f1d21bc40711843cd122fd4a"
708 725 },
709 726 "dist": {
710 727 "type": "zip",
711   - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
712   - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
  728 + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/416fb8ad1d095a87f1d21bc40711843cd122fd4a",
  729 + "reference": "416fb8ad1d095a87f1d21bc40711843cd122fd4a",
713 730 "shasum": ""
714 731 },
715 732 "require": {
... ... @@ -750,7 +767,7 @@
750 767 "constructor",
751 768 "instantiate"
752 769 ],
753   - "time": "2015-06-14 21:17:01"
  770 + "time": "2016-03-31 10:24:22"
754 771 },
755 772 {
756 773 "name": "ezyang/htmlpurifier",
... ... @@ -845,12 +862,12 @@
845 862 "source": {
846 863 "type": "git",
847 864 "url": "https://github.com/guzzle/guzzle.git",
848   - "reference": "d094e337976dff9d8e2424e8485872194e768662"
  865 + "reference": "8e4e5ef9fbcc6ced335f398b32dcf2a0e4a24acb"
849 866 },
850 867 "dist": {
851 868 "type": "zip",
852   - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/d094e337976dff9d8e2424e8485872194e768662",
853   - "reference": "d094e337976dff9d8e2424e8485872194e768662",
  869 + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/8e4e5ef9fbcc6ced335f398b32dcf2a0e4a24acb",
  870 + "reference": "8e4e5ef9fbcc6ced335f398b32dcf2a0e4a24acb",
854 871 "shasum": ""
855 872 },
856 873 "require": {
... ... @@ -899,7 +916,7 @@
899 916 "rest",
900 917 "web service"
901 918 ],
902   - "time": "2016-03-21 20:02:09"
  919 + "time": "2016-04-01 05:52:09"
903 920 },
904 921 {
905 922 "name": "guzzlehttp/promises",
... ... @@ -1389,6 +1406,48 @@
1389 1406 "time": "2015-07-03 07:08:52"
1390 1407 },
1391 1408 {
  1409 + "name": "myclabs/deep-copy",
  1410 + "version": "1.5.0",
  1411 + "source": {
  1412 + "type": "git",
  1413 + "url": "https://github.com/myclabs/DeepCopy.git",
  1414 + "reference": "e3abefcd7f106677fd352cd7c187d6c969aa9ddc"
  1415 + },
  1416 + "dist": {
  1417 + "type": "zip",
  1418 + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/e3abefcd7f106677fd352cd7c187d6c969aa9ddc",
  1419 + "reference": "e3abefcd7f106677fd352cd7c187d6c969aa9ddc",
  1420 + "shasum": ""
  1421 + },
  1422 + "require": {
  1423 + "php": ">=5.4.0"
  1424 + },
  1425 + "require-dev": {
  1426 + "doctrine/collections": "1.*",
  1427 + "phpunit/phpunit": "~4.1"
  1428 + },
  1429 + "type": "library",
  1430 + "autoload": {
  1431 + "psr-4": {
  1432 + "DeepCopy\\": "src/DeepCopy/"
  1433 + }
  1434 + },
  1435 + "notification-url": "https://packagist.org/downloads/",
  1436 + "license": [
  1437 + "MIT"
  1438 + ],
  1439 + "description": "Create deep copies (clones) of your objects",
  1440 + "homepage": "https://github.com/myclabs/DeepCopy",
  1441 + "keywords": [
  1442 + "clone",
  1443 + "copy",
  1444 + "duplicate",
  1445 + "object",
  1446 + "object graph"
  1447 + ],
  1448 + "time": "2015-11-07 22:20:37"
  1449 + },
  1450 + {
1392 1451 "name": "nodge/lightopenid",
1393 1452 "version": "1.1.2",
1394 1453 "source": {
... ... @@ -1600,29 +1659,30 @@
1600 1659 },
1601 1660 {
1602 1661 "name": "phpunit/php-code-coverage",
1603   - "version": "2.2.x-dev",
  1662 + "version": "dev-master",
1604 1663 "source": {
1605 1664 "type": "git",
1606 1665 "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
1607   - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
  1666 + "reference": "9b2a050b8ee982bf4132fa5c8b381f33c7416f2b"
1608 1667 },
1609 1668 "dist": {
1610 1669 "type": "zip",
1611   - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
1612   - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
  1670 + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/9b2a050b8ee982bf4132fa5c8b381f33c7416f2b",
  1671 + "reference": "9b2a050b8ee982bf4132fa5c8b381f33c7416f2b",
1613 1672 "shasum": ""
1614 1673 },
1615 1674 "require": {
1616   - "php": ">=5.3.3",
  1675 + "php": "^5.6 || ^7.0",
1617 1676 "phpunit/php-file-iterator": "~1.3",
1618 1677 "phpunit/php-text-template": "~1.2",
1619   - "phpunit/php-token-stream": "~1.3",
  1678 + "phpunit/php-token-stream": "^1.4.2",
  1679 + "sebastian/code-unit-reverse-lookup": "~1.0",
1620 1680 "sebastian/environment": "^1.3.2",
1621   - "sebastian/version": "~1.0"
  1681 + "sebastian/version": "~1.0|~2.0"
1622 1682 },
1623 1683 "require-dev": {
1624 1684 "ext-xdebug": ">=2.1.4",
1625   - "phpunit/phpunit": "~4"
  1685 + "phpunit/phpunit": "~5"
1626 1686 },
1627 1687 "suggest": {
1628 1688 "ext-dom": "*",
... ... @@ -1632,7 +1692,7 @@
1632 1692 "type": "library",
1633 1693 "extra": {
1634 1694 "branch-alias": {
1635   - "dev-master": "2.2.x-dev"
  1695 + "dev-master": "3.3.x-dev"
1636 1696 }
1637 1697 },
1638 1698 "autoload": {
... ... @@ -1658,7 +1718,7 @@
1658 1718 "testing",
1659 1719 "xunit"
1660 1720 ],
1661   - "time": "2015-10-06 15:47:00"
  1721 + "time": "2016-03-09 13:32:21"
1662 1722 },
1663 1723 {
1664 1724 "name": "phpunit/php-file-iterator",
... ... @@ -1750,7 +1810,7 @@
1750 1810 },
1751 1811 {
1752 1812 "name": "phpunit/php-timer",
1753   - "version": "dev-master",
  1813 + "version": "1.0.7",
1754 1814 "source": {
1755 1815 "type": "git",
1756 1816 "url": "https://github.com/sebastianbergmann/php-timer.git",
... ... @@ -1840,16 +1900,16 @@
1840 1900 },
1841 1901 {
1842 1902 "name": "phpunit/phpunit",
1843   - "version": "4.8.x-dev",
  1903 + "version": "dev-master",
1844 1904 "source": {
1845 1905 "type": "git",
1846 1906 "url": "https://github.com/sebastianbergmann/phpunit.git",
1847   - "reference": "1a1b63266c046e1856fd03812a4e0ac2b51aa2d5"
  1907 + "reference": "1206dd340c6f02b1322025bfaa2a3c2b244e874f"
1848 1908 },
1849 1909 "dist": {
1850 1910 "type": "zip",
1851   - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1a1b63266c046e1856fd03812a4e0ac2b51aa2d5",
1852   - "reference": "1a1b63266c046e1856fd03812a4e0ac2b51aa2d5",
  1911 + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/beb7683ca88fd9901dccf296806d1e484bd00d11",
  1912 + "reference": "1206dd340c6f02b1322025bfaa2a3c2b244e874f",
1853 1913 "shasum": ""
1854 1914 },
1855 1915 "require": {
... ... @@ -1858,19 +1918,22 @@
1858 1918 "ext-pcre": "*",
1859 1919 "ext-reflection": "*",
1860 1920 "ext-spl": "*",
1861   - "php": ">=5.3.3",
  1921 + "myclabs/deep-copy": "~1.3",
  1922 + "php": "^5.6 || ^7.0",
1862 1923 "phpspec/prophecy": "^1.3.1",
1863   - "phpunit/php-code-coverage": "~2.1",
  1924 + "phpunit/php-code-coverage": "^3.3.0",
1864 1925 "phpunit/php-file-iterator": "~1.4",
1865 1926 "phpunit/php-text-template": "~1.2",
1866   - "phpunit/php-timer": ">=1.0.6",
1867   - "phpunit/phpunit-mock-objects": "~2.3",
  1927 + "phpunit/php-timer": "^1.0.6",
  1928 + "phpunit/phpunit-mock-objects": "^3.1",
1868 1929 "sebastian/comparator": "~1.1",
1869 1930 "sebastian/diff": "~1.2",
1870 1931 "sebastian/environment": "~1.3",
1871 1932 "sebastian/exporter": "~1.2",
1872 1933 "sebastian/global-state": "~1.0",
1873   - "sebastian/version": "~1.0",
  1934 + "sebastian/object-enumerator": "~1.0",
  1935 + "sebastian/resource-operations": "~1.0",
  1936 + "sebastian/version": "~1.0|~2.0",
1874 1937 "symfony/yaml": "~2.1|~3.0"
1875 1938 },
1876 1939 "suggest": {
... ... @@ -1882,7 +1945,7 @@
1882 1945 "type": "library",
1883 1946 "extra": {
1884 1947 "branch-alias": {
1885   - "dev-master": "4.8.x-dev"
  1948 + "dev-master": "5.4.x-dev"
1886 1949 }
1887 1950 },
1888 1951 "autoload": {
... ... @@ -1908,30 +1971,30 @@
1908 1971 "testing",
1909 1972 "xunit"
1910 1973 ],
1911   - "time": "2016-03-14 15:10:21"
  1974 + "time": "2016-04-04 14:34:35"
1912 1975 },
1913 1976 {
1914 1977 "name": "phpunit/phpunit-mock-objects",
1915   - "version": "2.3.x-dev",
  1978 + "version": "dev-master",
1916 1979 "source": {
1917 1980 "type": "git",
1918 1981 "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
1919   - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
  1982 + "reference": "7b18bbdad9880e09740959e90eec4b91c35a4aa9"
1920 1983 },
1921 1984 "dist": {
1922 1985 "type": "zip",
1923   - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
1924   - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
  1986 + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/7b18bbdad9880e09740959e90eec4b91c35a4aa9",
  1987 + "reference": "7b18bbdad9880e09740959e90eec4b91c35a4aa9",
1925 1988 "shasum": ""
1926 1989 },
1927 1990 "require": {
1928 1991 "doctrine/instantiator": "^1.0.2",
1929   - "php": ">=5.3.3",
  1992 + "php": ">=5.6",
1930 1993 "phpunit/php-text-template": "~1.2",
1931 1994 "sebastian/exporter": "~1.2"
1932 1995 },
1933 1996 "require-dev": {
1934   - "phpunit/phpunit": "~4.4"
  1997 + "phpunit/phpunit": "~5"
1935 1998 },
1936 1999 "suggest": {
1937 2000 "ext-soap": "*"
... ... @@ -1939,7 +2002,7 @@
1939 2002 "type": "library",
1940 2003 "extra": {
1941 2004 "branch-alias": {
1942   - "dev-master": "2.3.x-dev"
  2005 + "dev-master": "3.1.x-dev"
1943 2006 }
1944 2007 },
1945 2008 "autoload": {
... ... @@ -1964,7 +2027,7 @@
1964 2027 "mock",
1965 2028 "xunit"
1966 2029 ],
1967   - "time": "2015-10-02 06:51:40"
  2030 + "time": "2016-03-24 06:24:17"
1968 2031 },
1969 2032 {
1970 2033 "name": "psr/http-message",
... ... @@ -2119,6 +2182,51 @@
2119 2182 "time": "2015-11-26 15:24:53"
2120 2183 },
2121 2184 {
  2185 + "name": "sebastian/code-unit-reverse-lookup",
  2186 + "version": "dev-master",
  2187 + "source": {
  2188 + "type": "git",
  2189 + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
  2190 + "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe"
  2191 + },
  2192 + "dist": {
  2193 + "type": "zip",
  2194 + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/c36f5e7cfce482fde5bf8d10d41a53591e0198fe",
  2195 + "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe",
  2196 + "shasum": ""
  2197 + },
  2198 + "require": {
  2199 + "php": ">=5.6"
  2200 + },
  2201 + "require-dev": {
  2202 + "phpunit/phpunit": "~5"
  2203 + },
  2204 + "type": "library",
  2205 + "extra": {
  2206 + "branch-alias": {
  2207 + "dev-master": "1.0.x-dev"
  2208 + }
  2209 + },
  2210 + "autoload": {
  2211 + "classmap": [
  2212 + "src/"
  2213 + ]
  2214 + },
  2215 + "notification-url": "https://packagist.org/downloads/",
  2216 + "license": [
  2217 + "BSD-3-Clause"
  2218 + ],
  2219 + "authors": [
  2220 + {
  2221 + "name": "Sebastian Bergmann",
  2222 + "email": "sebastian@phpunit.de"
  2223 + }
  2224 + ],
  2225 + "description": "Looks up which function or method a line of code belongs to",
  2226 + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
  2227 + "time": "2016-02-13 06:45:14"
  2228 + },
  2229 + {
2122 2230 "name": "sebastian/comparator",
2123 2231 "version": "dev-master",
2124 2232 "source": {
... ... @@ -2403,6 +2511,52 @@
2403 2511 "time": "2015-10-12 03:26:01"
2404 2512 },
2405 2513 {
  2514 + "name": "sebastian/object-enumerator",
  2515 + "version": "dev-master",
  2516 + "source": {
  2517 + "type": "git",
  2518 + "url": "https://github.com/sebastianbergmann/object-enumerator.git",
  2519 + "reference": "d4ca2fb70344987502567bc50081c03e6192fb26"
  2520 + },
  2521 + "dist": {
  2522 + "type": "zip",
  2523 + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/d4ca2fb70344987502567bc50081c03e6192fb26",
  2524 + "reference": "d4ca2fb70344987502567bc50081c03e6192fb26",
  2525 + "shasum": ""
  2526 + },
  2527 + "require": {
  2528 + "php": ">=5.6",
  2529 + "sebastian/recursion-context": "~1.0"
  2530 + },
  2531 + "require-dev": {
  2532 + "phpunit/phpunit": "~5"
  2533 + },
  2534 + "type": "library",
  2535 + "extra": {
  2536 + "branch-alias": {
  2537 + "dev-master": "1.0.x-dev"
  2538 + }
  2539 + },
  2540 + "autoload": {
  2541 + "classmap": [
  2542 + "src/"
  2543 + ]
  2544 + },
  2545 + "notification-url": "https://packagist.org/downloads/",
  2546 + "license": [
  2547 + "BSD-3-Clause"
  2548 + ],
  2549 + "authors": [
  2550 + {
  2551 + "name": "Sebastian Bergmann",
  2552 + "email": "sebastian@phpunit.de"
  2553 + }
  2554 + ],
  2555 + "description": "Traverses array structures and object graphs to enumerate all referenced objects",
  2556 + "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
  2557 + "time": "2016-01-28 13:25:10"
  2558 + },
  2559 + {
2406 2560 "name": "sebastian/recursion-context",
2407 2561 "version": "dev-master",
2408 2562 "source": {
... ... @@ -2456,20 +2610,70 @@
2456 2610 "time": "2016-01-28 05:39:29"
2457 2611 },
2458 2612 {
  2613 + "name": "sebastian/resource-operations",
  2614 + "version": "dev-master",
  2615 + "source": {
  2616 + "type": "git",
  2617 + "url": "https://github.com/sebastianbergmann/resource-operations.git",
  2618 + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52"
  2619 + },
  2620 + "dist": {
  2621 + "type": "zip",
  2622 + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
  2623 + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
  2624 + "shasum": ""
  2625 + },
  2626 + "require": {
  2627 + "php": ">=5.6.0"
  2628 + },
  2629 + "type": "library",
  2630 + "extra": {
  2631 + "branch-alias": {
  2632 + "dev-master": "1.0.x-dev"
  2633 + }
  2634 + },
  2635 + "autoload": {
  2636 + "classmap": [
  2637 + "src/"
  2638 + ]
  2639 + },
  2640 + "notification-url": "https://packagist.org/downloads/",
  2641 + "license": [
  2642 + "BSD-3-Clause"
  2643 + ],
  2644 + "authors": [
  2645 + {
  2646 + "name": "Sebastian Bergmann",
  2647 + "email": "sebastian@phpunit.de"
  2648 + }
  2649 + ],
  2650 + "description": "Provides a list of PHP built-in functions that operate on resources",
  2651 + "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
  2652 + "time": "2015-07-28 20:34:47"
  2653 + },
  2654 + {
2459 2655 "name": "sebastian/version",
2460   - "version": "1.0.6",
  2656 + "version": "dev-master",
2461 2657 "source": {
2462 2658 "type": "git",
2463 2659 "url": "https://github.com/sebastianbergmann/version.git",
2464   - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
  2660 + "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5"
2465 2661 },
2466 2662 "dist": {
2467 2663 "type": "zip",
2468   - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
2469   - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
  2664 + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5",
  2665 + "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5",
2470 2666 "shasum": ""
2471 2667 },
  2668 + "require": {
  2669 + "php": ">=5.6"
  2670 + },
2472 2671 "type": "library",
  2672 + "extra": {
  2673 + "branch-alias": {
  2674 + "dev-master": "2.0.x-dev"
  2675 + }
  2676 + },
2473 2677 "autoload": {
2474 2678 "classmap": [
2475 2679 "src/"
... ... @@ -2488,7 +2692,7 @@
2488 2692 ],
2489 2693 "description": "Library that helps with managing the version number of Git-hosted PHP projects",
2490 2694 "homepage": "https://github.com/sebastianbergmann/version",
2491   - "time": "2015-06-21 13:59:46"
  2695 + "time": "2016-02-04 12:56:52"
2492 2696 },
2493 2697 {
2494 2698 "name": "swiftmailer/swiftmailer",
... ... @@ -2992,12 +3196,12 @@
2992 3196 "source": {
2993 3197 "type": "git",
2994 3198 "url": "https://github.com/yiisoft/yii2-framework.git",
2995   - "reference": "bcc317666439a8ec1dc28874e0577b860b6dd6b3"
  3199 + "reference": "3fa8254dd475aa0979e1ab2a4a7d83aaf5acdfc8"
2996 3200 },
2997 3201 "dist": {
2998 3202 "type": "zip",
2999   - "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/bcc317666439a8ec1dc28874e0577b860b6dd6b3",
3000   - "reference": "bcc317666439a8ec1dc28874e0577b860b6dd6b3",
  3203 + "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/4efd28591c92be5f16d3456bbb5e1f1ea5ca96c0",
  3204 + "reference": "3fa8254dd475aa0979e1ab2a4a7d83aaf5acdfc8",
3001 3205 "shasum": ""
3002 3206 },
3003 3207 "require": {
... ... @@ -3078,7 +3282,7 @@
3078 3282 "framework",
3079 3283 "yii2"
3080 3284 ],
3081   - "time": "2016-03-30 14:53:41"
  3285 + "time": "2016-04-05 09:54:22"
3082 3286 },
3083 3287 {
3084 3288 "name": "yiisoft/yii2-bootstrap",
... ... @@ -3131,6 +3335,51 @@
3131 3335 "time": "2016-03-30 22:44:25"
3132 3336 },
3133 3337 {
  3338 + "name": "yiisoft/yii2-codeception",
  3339 + "version": "dev-master",
  3340 + "source": {
  3341 + "type": "git",
  3342 + "url": "https://github.com/yiisoft/yii2-codeception.git",
  3343 + "reference": "e01b3c46917b3f00c42f6a4aabf612cc36d792e6"
  3344 + },
  3345 + "dist": {
  3346 + "type": "zip",
  3347 + "url": "https://api.github.com/repos/yiisoft/yii2-codeception/zipball/e01b3c46917b3f00c42f6a4aabf612cc36d792e6",
  3348 + "reference": "e01b3c46917b3f00c42f6a4aabf612cc36d792e6",
  3349 + "shasum": ""
  3350 + },
  3351 + "require": {
  3352 + "yiisoft/yii2": ">=2.0.4"
  3353 + },
  3354 + "type": "yii2-extension",
  3355 + "extra": {
  3356 + "branch-alias": {
  3357 + "dev-master": "2.0.x-dev"
  3358 + }
  3359 + },
  3360 + "autoload": {
  3361 + "psr-4": {
  3362 + "yii\\codeception\\": ""
  3363 + }
  3364 + },
  3365 + "notification-url": "https://packagist.org/downloads/",
  3366 + "license": [
  3367 + "BSD-3-Clause"
  3368 + ],
  3369 + "authors": [
  3370 + {
  3371 + "name": "Mark Jebri",
  3372 + "email": "mark.github@yandex.ru"
  3373 + }
  3374 + ],
  3375 + "description": "The Codeception integration for the Yii framework",
  3376 + "keywords": [
  3377 + "codeception",
  3378 + "yii2"
  3379 + ],
  3380 + "time": "2016-03-21 19:11:26"
  3381 + },
  3382 + {
3134 3383 "name": "yiisoft/yii2-composer",
3135 3384 "version": "dev-master",
3136 3385 "source": {
... ... @@ -3538,12 +3787,12 @@
3538 3787 "source": {
3539 3788 "type": "git",
3540 3789 "url": "https://github.com/yiisoft/yii2-gii.git",
3541   - "reference": "989d6c52c92e51f0d562729c329ee1012191cba2"
  3790 + "reference": "0d93a9dbd55f2d0921b8e153554379bb213a2c7f"
3542 3791 },
3543 3792 "dist": {
3544 3793 "type": "zip",
3545   - "url": "https://api.github.com/repos/yiisoft/yii2-gii/zipball/989d6c52c92e51f0d562729c329ee1012191cba2",
3546   - "reference": "989d6c52c92e51f0d562729c329ee1012191cba2",
  3794 + "url": "https://api.github.com/repos/yiisoft/yii2-gii/zipball/0d93a9dbd55f2d0921b8e153554379bb213a2c7f",
  3795 + "reference": "0d93a9dbd55f2d0921b8e153554379bb213a2c7f",
3547 3796 "shasum": ""
3548 3797 },
3549 3798 "require": {
... ... @@ -3583,7 +3832,7 @@
3583 3832 "gii",
3584 3833 "yii2"
3585 3834 ],
3586   - "time": "2016-03-21 19:13:26"
  3835 + "time": "2016-04-05 09:53:13"
3587 3836 }
3588 3837 ],
3589 3838 "aliases": [],
... ...
frontend/assets/AppAsset.php
... ... @@ -17,9 +17,10 @@ class AppAsset extends AssetBundle
17 17 public $basePath = '@webroot';
18 18 public $baseUrl = '@web';
19 19 public $css = [
20   - 'css/style.css',
  20 + '/css/style.css',
21 21 '/admin/css/flags32.css',
22 22 'https://fonts.googleapis.com/css?family=Roboto:400,700&subset=cyrillic,latin',
  23 + '/css/owl.carousel.css'
23 24 ];
24 25 public $js = [
25 26 '/js/script.js',
... ... @@ -33,10 +34,13 @@ class AppAsset extends AssetBundle
33 34 '/js/autoresize.jquery.js',
34 35 '/js/jquery.MultiFile.js',
35 36 '/js/myGallery_min.js',
36   - 'js/fieldWidget.js'
  37 + '/js/fieldWidget.js',
  38 + '/js/owl.carousel.min.js',
37 39 ];
38 40 public $depends = [
39 41 'yii\web\YiiAsset',
  42 + 'yii\web\JqueryAsset',
  43 + 'frontend\assets\FancyboxAsset',
40 44 ];
41 45 public $jsOptions = array(
42 46 'position' => \yii\web\View::POS_HEAD
... ...
frontend/controllers/AccountsController.php
... ... @@ -18,6 +18,7 @@
18 18 use common\models\Portfolio;
19 19 use common\models\PortfolioSearch;
20 20 use common\models\PortfolioSpecialization;
  21 + use common\models\PortfolioUser;
21 22 use common\models\Project;
22 23 use common\models\ProjectSearch;
23 24 use common\models\Specialization;
... ... @@ -234,8 +235,8 @@
234 235 $user_info->load($post);
235 236 $user_info->save();
236 237 $job = [ ];
237   - foreach($post['Job'] as $index => $value) {
238   - $job[$index] = new Job([
  238 + foreach($post[ 'Job' ] as $index => $value) {
  239 + $job[ $index ] = new Job([
239 240 'user_id' => \Yii::$app->user->getId(),
240 241 'current' => 0,
241 242 ]);
... ... @@ -478,6 +479,7 @@
478 479 {
479 480 $user = \Yii::$app->user->identity;
480 481 $portfolio = new Portfolio();
  482 +
481 483 $specializations = Specialization::find()
482 484 ->where([ 'specialization_pid' => 0 ])
483 485 ->orderBy('specialization_id')
... ... @@ -491,6 +493,7 @@
491 493 ->indexBy('gallery_id')
492 494 ->column();
493 495 $post = \Yii::$app->request->post();
  496 + $portfolioUsers = $portfolio->portfolioUsers;
494 497 if(!empty( $post )) {
495 498 $portfolio->load($post);
496 499 $portfolio->validate();
... ... @@ -500,13 +503,30 @@
500 503 foreach($portfolio->specializationInput as $one_specialization) {
501 504 $portfolio->link('specializations', Specialization::findOne($one_specialization));
502 505 }
503   - return $this->redirect('portfolio');
  506 + $portfolio->unlinkAll('portfolioUsers', true);
  507 + $success = true;
  508 + if(!empty( $post[ 'PortfolioUser' ] )) {
  509 + $portfolioUsers = [ ];
  510 + foreach($post[ 'PortfolioUser' ] as $index => $item) {
  511 + $portfolioUsers[ $index ] = new PortfolioUser([ 'portfolio_id' => $portfolio->portfolio_id ]);
  512 + }
  513 + $success = (PortfolioUser::loadMultiple($portfolioUsers, $post) && PortfolioUser::validateMultiple($portfolioUsers));
  514 + if($success) {
  515 + foreach($portfolioUsers as $index => $portfolioUser) {
  516 + $portfolioUser->save(false);
  517 + }
  518 + }
  519 + }
  520 + if($success) {
  521 + return $this->redirect('portfolio');
  522 + }
504 523 }
505 524 }
506 525 return $this->render('_portfolio_form', [
507 526 'portfolio' => $portfolio,
508 527 'specializations' => $specializations,
509 528 'galleries' => $galleries,
  529 + 'portfolioUsers' => $portfolioUsers,
510 530 ]);
511 531 }
512 532  
... ... @@ -523,6 +543,7 @@
523 543 $user = \Yii::$app->user->identity;
524 544 $portfolio = $user->getPortfolios()
525 545 ->where([ 'portfolio_id' => $id ])
  546 + ->with('portfolioUsers.user')
526 547 ->one();
527 548 $galleries = $user->getGalleries()
528 549 ->select([
... ... @@ -535,13 +556,13 @@
535 556 if(!$portfolio instanceof ActiveRecord) {
536 557 throw new NotFoundHttpException('Запись не найдена');
537 558 }
538   -
539 559 $specializations = Specialization::find()
540 560 ->where([ 'specialization_pid' => 0 ])
541 561 ->orderBy('specialization_id')
542 562 ->all();
543 563  
544 564 $post = \Yii::$app->request->post();
  565 + $portfolioUsers = $portfolio->portfolioUsers;
545 566  
546 567 if(!empty( $post )) {
547 568 $portfolio->load($post);
... ... @@ -552,7 +573,23 @@
552 573 foreach($portfolio->specializationInput as $one_specialization) {
553 574 $portfolio->link('specializations', Specialization::findOne($one_specialization));
554 575 }
555   - return $this->redirect('portfolio');
  576 + $portfolio->unlinkAll('portfolioUsers', true);
  577 + $success = true;
  578 + if(!empty( $post[ 'PortfolioUser' ] )) {
  579 + $portfolioUsers = [ ];
  580 + foreach($post[ 'PortfolioUser' ] as $index => $item) {
  581 + $portfolioUsers[ $index ] = new PortfolioUser([ 'portfolio_id' => $portfolio->portfolio_id ]);
  582 + }
  583 + $success = (PortfolioUser::loadMultiple($portfolioUsers, $post) && PortfolioUser::validateMultiple($portfolioUsers));
  584 + if($success) {
  585 + foreach($portfolioUsers as $index => $portfolioUser) {
  586 + $portfolioUser->save(false);
  587 + }
  588 + }
  589 + }
  590 + if($success) {
  591 + return $this->redirect('portfolio');
  592 + }
556 593 }
557 594 }
558 595  
... ... @@ -560,6 +597,7 @@
560 597 'portfolio' => $portfolio,
561 598 'specializations' => $specializations,
562 599 'galleries' => $galleries,
  600 + 'portfolioUsers' => $portfolioUsers,
563 601 ]);
564 602 }
565 603  
... ...
frontend/controllers/AjaxController.php 0 → 100644
  1 +<?php
  2 + namespace frontend\controllers;
  3 +
  4 + use common\models\User;
  5 + use common\models\UserSearch;
  6 + use yii\db\ActiveRecord;
  7 + use yii\web\Controller;
  8 +
  9 + /**
  10 + * Site controller
  11 + */
  12 + class AjaxController extends Controller
  13 + {
  14 +
  15 + public $enableCsrfValidation = false;
  16 +
  17 + public function behaviors()
  18 + {
  19 + return [
  20 +
  21 + ];
  22 + }
  23 +
  24 + public function actionProjectUser()
  25 + {
  26 + $ids = json_decode(\Yii::$app->request->get('ids'));
  27 + $model = new UserSearch();
  28 + $dataProvider = $model->search(\Yii::$app->request->queryParams);
  29 + $dataProvider->query->andFilterWhere(['not in', 'id', $ids]);
  30 + $dataProvider->query->andWhere([
  31 + 'user_info.is_freelancer' => 1,
  32 + 'type' => 1,
  33 + ]);
  34 + $dataProvider->query->with('specializations');
  35 + return $this->renderAjax('users', [
  36 + 'model' => $model,
  37 + 'dataProvider' => $dataProvider,
  38 + ]);
  39 + }
  40 +
  41 + public function actionUserInput()
  42 + {
  43 + /**
  44 + * @var ActiveRecord $model
  45 + */
  46 + $request = \Yii::$app->request;
  47 + $response = \Yii::$app->response;
  48 + $response->format = $response::FORMAT_JSON;
  49 + $user_id = $request->get('id');
  50 + $model = $request->get('model');
  51 + $component = $request->get('component');
  52 + if(empty( $user_id )) {
  53 + return [ 'error' => 'User ID must be set' ];
  54 + } elseif(empty( $model )) {
  55 + return [ 'error' => 'Model must be set' ];
  56 + }
  57 + $user = User::find()
  58 + ->where([
  59 + 'id' => $user_id,
  60 + 'type' => 1,
  61 + 'user_info.is_freelancer' => 1,
  62 + ])
  63 + ->joinWith('userInfo')
  64 + ->one();
  65 + if(empty( $user )) {
  66 + return [ 'error' => 'User not found' ];
  67 + }
  68 + if(!class_exists($model)) {
  69 + return [ 'error' => 'Class not found' ];
  70 + }
  71 + $model = new $model();
  72 + if(!$model instanceof ActiveRecord) {
  73 + return [ 'error' => 'Class must extend ActiveRecord' ];
  74 + }
  75 + if(!$model->hasAttribute('user_id')) {
  76 + return [ 'error' => 'Class must have user_id attribute' ];
  77 + }
  78 + $html = $this->renderPartial('project_user', [
  79 + 'model' => $model,
  80 + 'user' => $user,
  81 + ]);
  82 + return [
  83 + 'result' => [
  84 + 'html' => $html,
  85 + 'id' => $user->id,
  86 + 'firstname' => $user->firstname,
  87 + 'lastname' => $user->lastname,
  88 + 'component' => $component,
  89 + ],
  90 + ];
  91 + }
  92 +
  93 + }
... ...
frontend/test/UserFixture.php 0 → 100644
  1 +<?php
  2 +
  3 + namespace frontend\test;
  4 +
  5 + use yii\test\ActiveFixture;
  6 +
  7 + class UserFixture extends ActiveFixture
  8 + {
  9 + public $modelClass = 'common\models\User';
  10 + }
0 11 \ No newline at end of file
... ...
frontend/test/UserInfoFixture.php 0 → 100644
  1 +<?php
  2 +
  3 + namespace frontend\test;
  4 +
  5 + use yii\test\ActiveFixture;
  6 +
  7 + class UserInfoFixture extends ActiveFixture
  8 + {
  9 +
  10 + public $modelClass = 'common\models\UserInfo';
  11 +
  12 + public $depends = [
  13 + 'frontend\test\UserFixture',
  14 + ];
  15 + }
0 16 \ No newline at end of file
... ...
frontend/test/data/user.php 0 → 100644
  1 +<?php
  2 + return [
  3 + 'user1' => [
  4 + 'username' => 'lmayert',
  5 + 'email' => 'strosin.vernice@jerde.com',
  6 + 'auth_key' => 'K3nF70it7tzNsHddEiq0BZ0i-OU8S3xV',
  7 + 'password_hash' => '$2y$13$WSyE5hHsG1rWN2jV8LRHzubilrCLI5Ev/iK0r3jRuwQEs2ldRu.a2',
  8 + ],
  9 + 'user2' => [
  10 + 'username' => 'napoleon69',
  11 + 'email' => 'aileen.barton@heaneyschumm.com',
  12 + 'auth_key' => 'dZlXsVnIDgIzFgX4EduAqkEPuphhOh9q',
  13 + 'password_hash' => '$2y$13$kkgpvJ8lnjKo8RuoR30ay.RjDf15bMcHIF7Vz1zz/6viYG5xJExU6',
  14 + ],
  15 + ];
0 16 \ No newline at end of file
... ...
frontend/test/unit/models/UserInfoTest.php 0 → 100644
  1 +<?php
  2 +
  3 + namespace frontend\test\unit\models;
  4 +
  5 + use frontend\test\UserInfoFixture;
  6 + use yii\codeception\DbTestCase;
  7 +
  8 + class UserInfoTest extends DbTestCase
  9 + {
  10 + public function fixtures()
  11 + {
  12 + return [
  13 + 'infos' => UserInfoFixture::className(),
  14 + ];
  15 + }
  16 + }
0 17 \ No newline at end of file
... ...
frontend/views/accounts/_portfolio_form.php
1 1 <?php
2 2 /**
  3 + * @var View $this
3 4 * @var Portfolio $portfolio
4 5 * @var integer[] $specializations
5 6 * @var string[] $galleries
... ... @@ -9,10 +10,11 @@
9 10 use common\models\Portfolio;
10 11 use common\models\Specialization;
11 12 use common\modules\file\widgets\ImageUploader;
12   -use common\modules\file\widgets\ImageUploaderInput;
13   -use mihaildev\ckeditor\CKEditor;
  13 + use common\modules\file\widgets\ImageUploaderInput;
  14 + use mihaildev\ckeditor\CKEditor;
14 15 use yii\helpers\ArrayHelper;
15 16 use yii\helpers\Html;
  17 + use yii\web\View;
16 18 use yii\widgets\ActiveForm;
17 19 use \common\widgets\MultiLangForm;
18 20 use kartik\select2\Select2;
... ... @@ -20,7 +22,6 @@ use mihaildev\ckeditor\CKEditor;
20 22  
21 23 $this->title = 'Портфолио';
22 24 $this->params[ 'breadcrumbs' ][] = $this->title;
23   - var_dump($portfolio->getErrors());
24 25 ?>
25 26 <div class="login-left-column-title"><?= $this->title ?></div>
26 27  
... ... @@ -41,7 +42,6 @@ use mihaildev\ckeditor\CKEditor;
41 42 </div>
42 43  
43 44  
44   -
45 45 <div class="input-blocks-wrapper admin-menu-list">
46 46 <div class="input-blocks" style="width: 100%; margin-bottom: 5px">
47 47 <label>Специализации</label>
... ... @@ -65,15 +65,15 @@ use mihaildev\ckeditor\CKEditor;
65 65 <li>
66 66 <a href="#" title="<?= $child_second->specialization_name ?>">
67 67 <?= $form->field($portfolio, "specializationInput[{$child_second->specialization_id}]", [
68   - 'template' => '{input}{label}{hint}{error}',
  68 + 'template' => '{input}{label}{hint}{error}',
69 69 ])
70   - ->label('<span></span>' . $child_second->specialization_name)
71   - ->checkbox([
72   - 'value' => $child_second->specialization_id,
73   - 'label' => NULL,
74   - 'uncheck' => NULL,
75   - 'class' => 'custom-check',
76   - ], false) ?>
  70 + ->label('<span></span>' . $child_second->specialization_name)
  71 + ->checkbox([
  72 + 'value' => $child_second->specialization_id,
  73 + 'label' => NULL,
  74 + 'uncheck' => NULL,
  75 + 'class' => 'custom-check',
  76 + ], false) ?>
77 77 </a>
78 78 </li>
79 79 <?php endif; ?>
... ... @@ -94,33 +94,36 @@ use mihaildev\ckeditor\CKEditor;
94 94 </div>
95 95 </div>
96 96  
97   - <div class="admin-specialization-selected style"><ul></ul></div>
  97 + <div class="admin-specialization-selected style">
  98 + <ul></ul>
  99 + </div>
98 100  
99 101 <div class="input-blocks-wrapper admin-avatar admin-blog-min-img admin-portfolio-foto">
100 102 <div style="font-size: 13px;color: inherit;font-weight: 700;">Фото главное</div>
101   - <?= $form->field($portfolio, 'cover')->widget(ImageUploaderInput::className(),[
102   - 'size' => [
103   - [
104   - 'width' => 720,
105   - 'height' => 280,
106   - ],
107   - [
108   - 'width' => 318,
109   - 'height' => 228,
110   - ],
111   - [
112   - 'width' => 152,
113   - 'height' => 108,
114   - ],
115   - [
116   - 'width' => 210,
117   - 'height' => 150,
118   - ]
119   - ],
120   - 'multi' => false,
121   - 'gallery' => $portfolio->cover,
122   - 'name' => 'Загрузить фото',
123   - ]); ?>
  103 + <?= $form->field($portfolio, 'cover')
  104 + ->widget(ImageUploaderInput::className(), [
  105 + 'size' => [
  106 + [
  107 + 'width' => 720,
  108 + 'height' => 280,
  109 + ],
  110 + [
  111 + 'width' => 318,
  112 + 'height' => 228,
  113 + ],
  114 + [
  115 + 'width' => 152,
  116 + 'height' => 108,
  117 + ],
  118 + [
  119 + 'width' => 210,
  120 + 'height' => 150,
  121 + ],
  122 + ],
  123 + 'multi' => false,
  124 + 'gallery' => $portfolio->cover,
  125 + 'name' => 'Загрузить фото',
  126 + ]); ?>
124 127 </div>
125 128  
126 129 <div class="input-blocks-wrapper">
... ... @@ -179,6 +182,84 @@ use mihaildev\ckeditor\CKEditor;
179 182 </div>
180 183 </div>
181 184  
  185 + <div class="clearfix"></div>
  186 +
  187 + <div class="add_project_user_wrapper" id="<?= $form->id ?>_project_user">
  188 + <p>Добавить пользователя</p>
  189 + <p><?= Html::a('Добавить', false, [ 'class' => 'add_project_user_link' ]) ?></p>
  190 + <div class="add_project_user_list">
  191 + <?php
  192 + foreach($portfolioUsers as $portfolioUser) {
  193 + echo $this->render('@frontend/views/ajax/project_user', ['model' => $portfolioUser, 'user' => $portfolioUser->user]);
  194 + }
  195 + ?>
  196 + </div>
  197 + </div>
  198 + <script>
  199 + $(
  200 + function()
  201 + {
  202 + $(document).on(
  203 + 'click', '.add_project_user_link', function()
  204 + {
  205 + var component = $(this).parents('.add_project_user_wrapper').attr('id');
  206 + var ids = [];
  207 + $.each(
  208 + $('#' + component).find('.project_user_wrapper'), function(i, val)
  209 + {
  210 + if(ids.indexOf($(val).data('id')) < 0)
  211 + {
  212 + ids.push($(val).data('id'));
  213 + }
  214 + }
  215 + );
  216 + $.fancybox.open(
  217 + {href : 'http://mfp.dev/ajax/project-user'}, {
  218 + type : 'ajax', maxWidth : 750,
  219 + ajax : {dataType : 'html', data : {ids : JSON.stringify(ids)}},
  220 + tpl : {wrap : '<div class="fancybox-wrap" tabIndex="-1" data-model="common\\models\\PortfolioUser" data-component="' + component + '"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>'}
  221 + }
  222 + );
  223 + }
  224 + );
  225 + $(document).on(
  226 + 'click', '.user_search_modal_tick', function()
  227 + {
  228 + var user_id = $(this).parents('.user_search_modal_row').data('key');
  229 + var model = $(this).parents('.fancybox-wrap').data('model');
  230 + var component = $(this).parents('.fancybox-wrap').data('component');
  231 + var result;
  232 + $.fancybox.close();
  233 + $.fancybox.showLoading();
  234 + $.get(
  235 + '/ajax/user-input', {
  236 + id : user_id, model : model, component : component
  237 + }, function(data)
  238 + {
  239 + if(data.result.component !== undefined)
  240 + {
  241 + $('#' + data.result.component).find('.add_project_user_list')
  242 + .append(data.result.html);
  243 + }
  244 + }
  245 + ).always(
  246 + function()
  247 + {
  248 + $.fancybox.hideLoading();
  249 + }
  250 + );
  251 + }
  252 + );
  253 + $(document).on(
  254 + 'click', '.project_user_remove', function()
  255 + {
  256 + $(this).parents('.project_user_wrapper').remove();
  257 + }
  258 + );
  259 + }
  260 + );
  261 + </script>
  262 +
182 263 </div>
183 264  
184 265 <div class="input-blocks-wrapper">
... ... @@ -193,7 +274,7 @@ use mihaildev\ckeditor\CKEditor;
193 274 ], [
194 275 'title' => Yii::t('app', 'delete'),
195 276 'aria-label' => Yii::t('app', 'delete'),
196   - 'data-confirm' => Yii::t('app', 'delete_confirm'),
  277 + 'data-confirm' => Yii::t('app', 'delete_confirm'),
197 278 'data-method' => 'post',
198 279 'data-pjax' => 0,
199 280 ]);
... ... @@ -202,7 +283,7 @@ use mihaildev\ckeditor\CKEditor;
202 283 </div>
203 284  
204 285 <div class="admin-back-note">
205   - <?= Html::a('вернуться', Request::getIsLocal(\Yii::$app->request->referrer)?\Yii::$app->request->referrer:['accounts/portfolio' ]) ?>
  286 + <?= Html::a('вернуться', Request::getIsLocal(\Yii::$app->request->referrer) ? \Yii::$app->request->referrer : [ 'accounts/portfolio' ]) ?>
206 287 </div>
207 288 </div>
208 289 </div>
... ... @@ -214,29 +295,43 @@ use mihaildev\ckeditor\CKEditor;
214 295 function()
215 296 {
216 297 bottomButton()
217   - function bottomButton(){
218   - if( ($('.admin-portfolio-foto .admin-avatar-pattern img').length)>0 ) {
  298 + function bottomButton()
  299 + {
  300 + if(($('.admin-portfolio-foto .admin-avatar-pattern img').length) > 0)
  301 + {
219 302  
220   - } else {
221   - $('.admin-portfolio-foto .tst').css({marginBottom:0})
  303 + } else
  304 + {
  305 + $('.admin-portfolio-foto .tst').css({marginBottom : 0})
222 306 }
223 307 }
224   - $('body').on('click', '.admin-portfolio-foto #cover_remove_img',function(){
225   - bottomButton()
226   - })
227 308  
  309 + $('body').on(
  310 + 'click', '.admin-portfolio-foto #cover_remove_img', function()
  311 + {
  312 + bottomButton()
  313 + }
  314 + )
228 315  
229   - $('#portfolio-gallery_id').change(function(){
230   - var gallery_id = $(this).val();
231   - $.post( "/accounts/gallery-cover", {gallery_id:gallery_id}, function( data ) {
232   - if(!($('#cover_old_img').val().length)){
233   - $('#cover_picture_link').val(data);
234   - var newimg=document.createElement("img");
235   - newimg.setAttribute("src",data);
  316 + $('#portfolio-gallery_id').change(
  317 + function()
  318 + {
  319 + var gallery_id = $(this).val();
  320 + $.post(
  321 + "/accounts/gallery-cover", {gallery_id : gallery_id}, function(data)
  322 + {
  323 + if(!($('#cover_old_img').val().length))
  324 + {
  325 + $('#cover_picture_link').val(data);
  326 + var newimg = document.createElement("img");
  327 + newimg.setAttribute("src", data);
236 328  
237   - $('#cover_img_block .admin-avatar-pattern').append(newimg);
238   - }
239   - });
240   - });
241   - });
  329 + $('#cover_img_block .admin-avatar-pattern').append(newimg);
  330 + }
  331 + }
  332 + );
  333 + }
  334 + );
  335 + }
  336 + );
242 337 </script>
... ...
frontend/views/ajax/project_user.php 0 → 100644
  1 +<?php
  2 + /**
  3 + * @var View $this
  4 + * @var User $user
  5 + * @var PortfolioUser $model
  6 + */
  7 + use common\models\PortfolioUser;
  8 + use common\models\User;
  9 + use yii\helpers\Html;
  10 + use yii\web\View;
  11 +
  12 +?>
  13 +<div class="form-inline project_user_wrapper" data-id="<?=$user->id?>">
  14 + <div class="error-summary">
  15 + <?=Html::errorSummary($model)?>
  16 + </div>
  17 + <div class="form-group" style="display: inline-block">
  18 + <label class="sr-only">User name</label>
  19 + <p class="form-control-static"><?=Html::a($user->name, ['performer/common', 'performer_id' => $user->id], ['target' => '_blank'])?></p>
  20 + <?=Html::activeHiddenInput($model, "[{$user->id}]user_id", ['value' => $user->id])?>
  21 + </div>
  22 + <div class="form-group" style="display: inline-block">
  23 + <?=Html::activeLabel($model, 'position', ['label' => Yii::t('app', 'Должность: ')])?>
  24 + <?=Html::activeTextInput($model, "[{$user->id}]position", ['class' => 'form-control'])?>
  25 + </div>
  26 + <div class="form-group" style="display: inline-block">
  27 + <?=Html::activeLabel($model, 'time', ['label' => Yii::t('app', 'Часы: ')])?>
  28 + <?=Html::activeInput('number', $model, "[{$user->id}]time", ['class' => 'form-control'])?>
  29 + </div>
  30 + <div class="form-group" style="display:inline-block">
  31 + <span class="project_user_remove" style="background: url('/images/delete-ico.png'); width: 15px; height: 15px; display: block; background-size: cover; cursor:pointer"></span>
  32 + </div>
  33 +</div>
... ...
frontend/views/ajax/users.php 0 → 100644
  1 +<?php
  2 + use backend\models\UserSearch;
  3 + use common\models\User;
  4 + use yii\bootstrap\BootstrapAsset;
  5 + use yii\bootstrap\BootstrapPluginAsset;
  6 + use yii\bootstrap\BootstrapThemeAsset;
  7 + use yii\data\ActiveDataProvider;
  8 + use yii\grid\ActionColumn;
  9 + use yii\grid\GridView;
  10 + use yii\helpers\ArrayHelper;
  11 + use yii\helpers\Html;
  12 + use yii\web\View;
  13 + use yii\widgets\Pjax;
  14 +
  15 + /**
  16 + * @var View $this
  17 + * @var ActiveDataProvider $dataProvider
  18 + * @var UserSearch $model
  19 + */
  20 +?>
  21 +<?php
  22 + BootstrapPluginAsset::register($this);
  23 + $pjax = Pjax::begin([
  24 + 'enablePushState' => false,
  25 + 'id' => 'pjax-user',
  26 + ]);
  27 + $js = "$('.user_search_modal_input').tooltip({placement: 'top', title: function() { return $(this).data('error'); }, trigger: 'manual'});
  28 + $('.user_search_modal_input').tooltip('show');";
  29 + $this->registerJs($js);
  30 + echo GridView::widget([
  31 + 'id' => 'grid-user',
  32 + 'dataProvider' => $dataProvider,
  33 + 'filterModel' => $model,
  34 + 'summary' => 'Найдено пользователей: {totalCount}',
  35 + 'rowOptions' => [
  36 + 'class' => 'user_search_modal_row',
  37 + ],
  38 + 'columns' => [
  39 + [
  40 + 'attribute' => 'id',
  41 + 'filter' => Html::activeInput('number', $model, 'id', [
  42 + 'class' => 'user_search_modal_input user_search_modal_input_id',
  43 + 'data-error' => $model->hasErrors('id') ? $model->getFirstError('id') : '',
  44 + ]),
  45 + ],
  46 + [
  47 + 'attribute' => 'userInfo.image',
  48 + 'content' => function($model, $key, $index, $column) {
  49 + /**
  50 + * @var User $model
  51 + */
  52 + if(!empty( $model->userInfo->image )) {
  53 + return Html::tag('div', Html::img($model->userInfo->image, [ 'width' => '100px' ]), [ 'class' => 'user_search_modal_item_image' ]);
  54 + } else {
  55 + return Html::tag('div', Html::img('/images/avatar-bg.png', [ 'width' => '100px' ]), [ 'class' => 'user_search_modal_item_image' ]);
  56 + }
  57 + },
  58 + ],
  59 + [
  60 + 'attribute' => 'firstname',
  61 + 'filter' => Html::activeInput('text', $model, 'name_search'),
  62 + ],
  63 + [
  64 + 'attribute' => 'lastname',
  65 + 'filter' => Html::activeInput('text', $model, 'surname_search'),
  66 + ],
  67 + [
  68 + 'attribute' => 'specialization',
  69 + 'content' => function($model, $key, $index, $column) {
  70 + if(!empty($model->specializations)) {
  71 + return implode(', ', ArrayHelper::getColumn($model->specializations, 'specialization_name'));
  72 + } else {
  73 + return false;
  74 + }
  75 + },
  76 + 'filterOptions' => [
  77 + 'class' => 'user_search_modal_specialization',
  78 + ],
  79 + 'label' => Yii::t('app', 'Специализация'),
  80 + ],
  81 + [
  82 + 'class' => ActionColumn::className(),
  83 + 'buttons' => [
  84 + 'apply' => function($url, $model, $key) {
  85 + return Html::tag('span', '', ['class' => 'user_search_modal_tick']);
  86 + }
  87 + ],
  88 + 'template' => '{apply}',
  89 + ]
  90 + ],
  91 + 'options' => [
  92 + 'class' => 'grid-view user_search_modal_grid',
  93 + ],
  94 + ]);
  95 + Pjax::end();
  96 +?>
... ...
frontend/views/company/portfolio-view.php
1 1 <?php
2   -
  2 +
3 3 use common\models\Portfolio;
4 4 use common\models\User;
5 5 use yii\helpers\Html;
6 6 use yii\web\ViewAction;
7   -
  7 +
8 8 /**
9 9 * @var ViewAction $this
10 10 * @var User $user
11 11 * @var Portfolio $portfolio
12 12 */
13 13 $this->params[ 'company' ] = $user;
14   -
  14 +
15 15 $this->title = 'My Yii Application';
16 16 ?>
17 17 <div class="portfolio-new-page-wrapper style">
... ... @@ -53,7 +53,7 @@
53 53 </div>
54 54 </div>
55 55 </div>
56   -
  56 +
57 57 <div class="new-portf-slider-wr style">
58 58 <div class="new-portf-slider-title"><?= $portfolio->name ?></div>
59 59 <?php
... ... @@ -64,12 +64,15 @@
64 64 <div id="demo5" class="scroll-img">
65 65 <ul>
66 66 <?php
67   - foreach( explode(',', $portfolio->gallery->photo) as $one_photo ) {
68   - ?>
69   - <li><img src="<?= $one_photo ?>" alt=""/>
70   - <?php
  67 + foreach(explode(',', $portfolio->gallery->photo) as $one_photo) {
  68 + if(empty( $one_photo )) {
  69 + continue;
71 70 }
72   - ?>
  71 + ?>
  72 + <li><img src="<?= $one_photo ?>" alt=""/></li>
  73 + <?php
  74 + }
  75 + ?>
73 76 </ul>
74 77 </div>
75 78 <div id="demo5-btn" class="text-center">
... ... @@ -82,7 +85,31 @@
82 85 }
83 86 ?>
84 87 </div>
85   -
  88 + <div style="clear: both"></div>
  89 + <style>
  90 + .project-gallery-owl {
  91 + width: calc(100% - 100px);
  92 + margin: 0 50px;
  93 + }
  94 + </style>
  95 + <div class="project-gallery-owl">
  96 + <?php
  97 + for($i = 0; $i < 3; $i++) {
  98 + foreach(explode(',', $portfolio->gallery->photo) as $one_photo) {
  99 + if(empty( $one_photo )) {
  100 + continue;
  101 + }
  102 + ?>
  103 + <div class="item" style="background:url(<?=$one_photo?>);height:130px;width:180px;background-size:cover"></div>
  104 + <?php
  105 + }
  106 + }
  107 + ?>
  108 + </div>
  109 + <script>
  110 + $('.project-gallery-owl').owlCarousel({loop:true, margin:10, nav:true, items: 3});
  111 + </script>
  112 +
86 113 <div class="new-portfolio-txt-wrapper style">
87 114 <div class="new-portfolio-excerpt style">
88 115 <div class="new-portfolio-editor">
... ... @@ -109,17 +136,17 @@
109 136 }
110 137 ?>
111 138 </div>
112   -
  139 +
113 140 <?php
114 141 echo \common\modules\comment\widgets\CommentWidget::widget([
115   - 'context' => $this,
  142 + 'context' => $this,
116 143 'model' => $portfolio->className(),
117 144 'model_id' => $portfolio->portfolio_id,
118 145 'comment_class' => \common\modules\comment\models\Comment::className(),
119 146 'rating_class' => \common\modules\comment\models\Rating::className(),
120 147 'class_options' => [
121   - 'scenario' => is_int(\Yii::$app->user->getId()) ? \common\modules\comment\models\Comment::SCENARIO_USER : \common\modules\comment\models\Comment::SCENARIO_GUEST,
122   - 'user_id' => \Yii::$app->user->getId(),
  148 + 'scenario' => is_int(\Yii::$app->user->getId()) ? \common\modules\comment\models\Comment::SCENARIO_USER : \common\modules\comment\models\Comment::SCENARIO_GUEST,
  149 + 'user_id' => \Yii::$app->user->getId(),
123 150 'guestComment' => true,
124 151 'status' => \common\modules\comment\models\Comment::STATUS_ACTIVE,
125 152 ],
... ... @@ -127,7 +154,7 @@
127 154 'view' => 'list-comment',
128 155 ],
129 156 'form_options' => [
130   - 'view' => 'form-comment',
  157 + 'view' => 'form-comment',
131 158 'tag' => 'div',
132 159 'class' => 'artbox_comment_form',
133 160 ],
... ... @@ -136,188 +163,188 @@
136 163 ],
137 164 ]);
138 165 ?>
139   -
  166 +
140 167 <?php
141   - /*
142   - ?>
143   - <div class="new-portf-comments-wr style">
144   - <div class="new-portf-comm-count">Комментарии: 3</div>
145   - <div class="new-portf-add-comm style">
146   -
147   - <form action="">
148   - <div class="input-blocks-comm">
149   - <label for="input-txt-5">Имя</label>
150   - <input class="custom-input-4" id="input-txt-5" type="text">
151   - </div>
152   - <div class="input-blocks-comm">
153   -
154   - <label for="input-txt-6">e-mail</label>
155   - <input class="custom-input-4" id="input-txt-6" type="text">
156   - </div>
157   - <div class="input-blocks-comm area-comm">
158   - <label for="input-txt-7">Комментарий</label>
159   - <textarea class="custom-area-4" id="input-txt-7"></textarea>
160   - </div>
161   - <div class="input-blocks-comm-button style">
162   - <button type="submit" class="">Добавить комментраий</button>
163   - </div>
164   - </form>
165   -
166   - </div>
167   -
168   - <div class="new-portf-comm-read-wr style">
169   - <div class="new-portf-comm-read">
170   - <div class="style">
171   - <div class="header-cabinet-foto">
172   - <img src="/images/ded-ico.png" alt="">
  168 + /*
  169 + ?>
  170 + <div class="new-portf-comments-wr style">
  171 + <div class="new-portf-comm-count">Комментарии: 3</div>
  172 + <div class="new-portf-add-comm style">
  173 +
  174 + <form action="">
  175 + <div class="input-blocks-comm">
  176 + <label for="input-txt-5">Имя</label>
  177 + <input class="custom-input-4" id="input-txt-5" type="text">
173 178 </div>
174   - <div class="new-prof-wrapper-read">
175   - <div class="new-portf-comm-read-title"><a href="#">Петер Цумтор</a></div>
176   - <div class="new-portf-comm-read-rating">
177   - <div class="rating">
178   - <!--оценка-->
179   - <input type="hidden" class="val" value="3"/>
180   - <!--количество голосов-->
181   - <input type="hidden" class="votes" value="12"/>
  179 + <div class="input-blocks-comm">
  180 +
  181 + <label for="input-txt-6">e-mail</label>
  182 + <input class="custom-input-4" id="input-txt-6" type="text">
  183 + </div>
  184 + <div class="input-blocks-comm area-comm">
  185 + <label for="input-txt-7">Комментарий</label>
  186 + <textarea class="custom-area-4" id="input-txt-7"></textarea>
  187 + </div>
  188 + <div class="input-blocks-comm-button style">
  189 + <button type="submit" class="">Добавить комментраий</button>
  190 + </div>
  191 + </form>
  192 +
  193 + </div>
  194 +
  195 + <div class="new-portf-comm-read-wr style">
  196 + <div class="new-portf-comm-read">
  197 + <div class="style">
  198 + <div class="header-cabinet-foto">
  199 + <img src="/images/ded-ico.png" alt="">
  200 + </div>
  201 + <div class="new-prof-wrapper-read">
  202 + <div class="new-portf-comm-read-title"><a href="#">Петер Цумтор</a></div>
  203 + <div class="new-portf-comm-read-rating">
  204 + <div class="rating">
  205 + <!--оценка-->
  206 + <input type="hidden" class="val" value="3"/>
  207 + <!--количество голосов-->
  208 + <input type="hidden" class="votes" value="12"/>
  209 + </div>
  210 + </div>
  211 + <div class="blog-post-date">
  212 + <span></span>
  213 + <p>22.09.2015</p>
182 214 </div>
183 215 </div>
184   - <div class="blog-post-date">
185   - <span></span>
186   - <p>22.09.2015</p>
  216 +
  217 + <div class="new-portf-answer">
  218 + <p>Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p>
  219 + <p>Евровагонка — удобная в монтаже фасонная доска, которая позволяет создать обшивку из плотно пригнанных элементов с качественно обработанной поверхностью. Толщина евровагонки составляет 125 мм, общая ширина (с гребнем) 960 мм, рабочая ширина 880 мм.Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p>
187 220 </div>
  221 +
188 222 </div>
189   -
190   - <div class="new-portf-answer">
191   - <p>Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p>
192   - <p>Евровагонка — удобная в монтаже фасонная доска, которая позволяет создать обшивку из плотно пригнанных элементов с качественно обработанной поверхностью. Толщина евровагонки составляет 125 мм, общая ширина (с гребнем) 960 мм, рабочая ширина 880 мм.Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p>
193   - </div>
194   -
  223 + <div class="style"></div>
195 224 </div>
196   - <div class="style"></div>
197   - </div>
198   -
199   - <div class="new-portf-comm-read">
200   - <div class="style">
201   - <div class="header-cabinet-foto">
202   - <img src="/images/ded-ico.png" alt="">
203   - </div>
204   - <div class="new-prof-wrapper-read">
205   - <div class="new-portf-comm-read-title"><a href="#">Петер Цумтор</a></div>
206   - <div class="new-portf-comm-read-rating">
207   - <div class="rating">
208   - <!--оценка-->
209   - <input type="hidden" class="val" value="4"/>
210   - <!--количество голосов-->
211   - <input type="hidden" class="votes" value="12"/>
  225 +
  226 + <div class="new-portf-comm-read">
  227 + <div class="style">
  228 + <div class="header-cabinet-foto">
  229 + <img src="/images/ded-ico.png" alt="">
  230 + </div>
  231 + <div class="new-prof-wrapper-read">
  232 + <div class="new-portf-comm-read-title"><a href="#">Петер Цумтор</a></div>
  233 + <div class="new-portf-comm-read-rating">
  234 + <div class="rating">
  235 + <!--оценка-->
  236 + <input type="hidden" class="val" value="4"/>
  237 + <!--количество голосов-->
  238 + <input type="hidden" class="votes" value="12"/>
  239 + </div>
  240 + </div>
  241 + <div class="blog-post-date">
  242 + <span></span>
  243 + <p>22.09.2015</p>
212 244 </div>
213 245 </div>
214   - <div class="blog-post-date">
215   - <span></span>
216   - <p>22.09.2015</p>
  246 +
  247 + <div class="new-portf-answer">
  248 + <p>Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p>
  249 + <p>Евровагонка — удобная в монтаже фасонная доска, которая позволяет создать обшивку из плотно пригнанных элементов с качественно обработанной поверхностью. Толщина евровагонки составляет 125 мм, общая ширина (с гребнем) 960 мм, рабочая ширина 880 мм.Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p>
217 250 </div>
  251 +
218 252 </div>
219   -
220   - <div class="new-portf-answer">
221   - <p>Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p>
222   - <p>Евровагонка — удобная в монтаже фасонная доска, которая позволяет создать обшивку из плотно пригнанных элементов с качественно обработанной поверхностью. Толщина евровагонки составляет 125 мм, общая ширина (с гребнем) 960 мм, рабочая ширина 880 мм.Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p>
223   - </div>
224   -
  253 + <div class="style"></div>
225 254 </div>
226   - <div class="style"></div>
227   - </div>
228   -
229   - <div class="new-portf-comm-read">
230   - <div class="style">
231   - <div class="header-cabinet-foto">
232   - <img src="/images/ded-ico.png" alt="">
233   - </div>
234   - <div class="new-prof-wrapper-read">
235   - <div class="new-portf-comm-read-title"><a href="#">Петер Цумтор</a></div>
236   - <div class="new-portf-comm-read-rating">
237   - <div class="rating">
238   - <!--оценка-->
239   - <input type="hidden" class="val" value="5"/>
240   - <!--количество голосов-->
241   - <input type="hidden" class="votes" value="12"/>
  255 +
  256 + <div class="new-portf-comm-read">
  257 + <div class="style">
  258 + <div class="header-cabinet-foto">
  259 + <img src="/images/ded-ico.png" alt="">
  260 + </div>
  261 + <div class="new-prof-wrapper-read">
  262 + <div class="new-portf-comm-read-title"><a href="#">Петер Цумтор</a></div>
  263 + <div class="new-portf-comm-read-rating">
  264 + <div class="rating">
  265 + <!--оценка-->
  266 + <input type="hidden" class="val" value="5"/>
  267 + <!--количество голосов-->
  268 + <input type="hidden" class="votes" value="12"/>
  269 + </div>
  270 + </div>
  271 + <div class="blog-post-date">
  272 + <span></span>
  273 + <p>22.09.2015</p>
242 274 </div>
243 275 </div>
244   - <div class="blog-post-date">
245   - <span></span>
246   - <p>22.09.2015</p>
  276 +
  277 + <div class="new-portf-answer">
  278 + <p>Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p>
  279 + <p>Евровагонка — удобная в монтаже фасонная доска, которая позволяет создать обшивку из плотно пригнанных элементов с качественно обработанной поверхностью. Толщина евровагонки составляет 125 мм, общая ширина (с гребнем) 960 мм, рабочая ширина 880 мм.Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p>
247 280 </div>
  281 +
248 282 </div>
249   -
250   - <div class="new-portf-answer">
251   - <p>Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p>
252   - <p>Евровагонка — удобная в монтаже фасонная доска, которая позволяет создать обшивку из плотно пригнанных элементов с качественно обработанной поверхностью. Толщина евровагонки составляет 125 мм, общая ширина (с гребнем) 960 мм, рабочая ширина 880 мм.Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p>
253   - </div>
254   -
  283 + <div class="style"></div>
255 284 </div>
256   - <div class="style"></div>
257   - </div>
258   -
259   - <div class="new-portf-comm-read">
260   - <div class="style">
261   - <div class="header-cabinet-foto">
262   - <img src="/images/ded-ico.png" alt="">
263   - </div>
264   - <div class="new-prof-wrapper-read">
265   - <div class="new-portf-comm-read-title"><a href="#">Петер Цумтор</a></div>
266   - <div class="new-portf-comm-read-rating">
267   - <div class="rating">
268   - <!--оценка-->
269   - <input type="hidden" class="val" value="1"/>
270   - <!--количество голосов-->
271   - <input type="hidden" class="votes" value="12"/>
  285 +
  286 + <div class="new-portf-comm-read">
  287 + <div class="style">
  288 + <div class="header-cabinet-foto">
  289 + <img src="/images/ded-ico.png" alt="">
  290 + </div>
  291 + <div class="new-prof-wrapper-read">
  292 + <div class="new-portf-comm-read-title"><a href="#">Петер Цумтор</a></div>
  293 + <div class="new-portf-comm-read-rating">
  294 + <div class="rating">
  295 + <!--оценка-->
  296 + <input type="hidden" class="val" value="1"/>
  297 + <!--количество голосов-->
  298 + <input type="hidden" class="votes" value="12"/>
  299 + </div>
  300 + </div>
  301 + <div class="blog-post-date">
  302 + <span></span>
  303 + <p>22.09.2015</p>
272 304 </div>
273 305 </div>
274   - <div class="blog-post-date">
275   - <span></span>
276   - <p>22.09.2015</p>
  306 +
  307 + <div class="new-portf-answer">
  308 + <p>Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p>
  309 + <p>Евровагонка — удобная в монтаже фасонная доска, которая позволяет создать обшивку из плотно пригнанных элементов с качественно обработанной поверхностью. Толщина евровагонки составляет 125 мм, общая ширина (с гребнем) 960 мм, рабочая ширина 880 мм.Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p>
277 310 </div>
  311 +
278 312 </div>
279   -
280   - <div class="new-portf-answer">
281   - <p>Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p>
282   - <p>Евровагонка — удобная в монтаже фасонная доска, которая позволяет создать обшивку из плотно пригнанных элементов с качественно обработанной поверхностью. Толщина евровагонки составляет 125 мм, общая ширина (с гребнем) 960 мм, рабочая ширина 880 мм.Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p>
283   - </div>
284   -
  313 + <div class="style"></div>
285 314 </div>
286   - <div class="style"></div>
287   - </div>
288   - <div class="new-portf-comm-read">
289   - <div class="style">
290   - <div class="header-cabinet-foto">
291   - <img src="/images/ded-ico.png" alt="">
292   - </div>
293   - <div class="new-prof-wrapper-read">
294   - <div class="new-portf-comm-read-title"><a href="#">Петер Цумтор</a></div>
295   - <div class="new-portf-comm-read-rating">
296   - <div class="rating">
297   - <!--оценка-->
298   - <input type="hidden" class="val" value="2"/>
299   - <!--количество голосов-->
300   - <input type="hidden" class="votes" value="12"/>
  315 + <div class="new-portf-comm-read">
  316 + <div class="style">
  317 + <div class="header-cabinet-foto">
  318 + <img src="/images/ded-ico.png" alt="">
  319 + </div>
  320 + <div class="new-prof-wrapper-read">
  321 + <div class="new-portf-comm-read-title"><a href="#">Петер Цумтор</a></div>
  322 + <div class="new-portf-comm-read-rating">
  323 + <div class="rating">
  324 + <!--оценка-->
  325 + <input type="hidden" class="val" value="2"/>
  326 + <!--количество голосов-->
  327 + <input type="hidden" class="votes" value="12"/>
  328 + </div>
  329 + </div>
  330 + <div class="blog-post-date">
  331 + <span></span>
  332 + <p>22.09.2015</p>
301 333 </div>
302 334 </div>
303   - <div class="blog-post-date">
304   - <span></span>
305   - <p>22.09.2015</p>
  335 +
  336 + <div class="new-portf-answer">
  337 + <p>Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p>
  338 + <p>Евровагонка — удобная в монтаже фасонная доска, которая позволяет создать обшивку из плотно пригнанных элементов с качественно обработанной поверхностью. Толщина евровагонки составляет 125 мм, общая ширина (с гребнем) 960 мм, рабочая ширина 880 мм.Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p>
306 339 </div>
  340 +
307 341 </div>
308   -
309   - <div class="new-portf-answer">
310   - <p>Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p>
311   - <p>Евровагонка — удобная в монтаже фасонная доска, которая позволяет создать обшивку из плотно пригнанных элементов с качественно обработанной поверхностью. Толщина евровагонки составляет 125 мм, общая ширина (с гребнем) 960 мм, рабочая ширина 880 мм.Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p>
312   - </div>
313   -
  342 + <div class="style"></div>
314 343 </div>
315   - <div class="style"></div>
  344 +
316 345 </div>
317   -
318 346 </div>
319   - </div>
320   - */
  347 + */
321 348 ?>
322 349 </div>
323 350 <script>
... ... @@ -356,7 +383,7 @@
356 383 {
357 384 $('.new-portf-slider #demo5').scrollbox(
358 385 {
359   - direction : 'h', distance : 230, autoPlay : false, onMouseOverPause : false
  386 + direction : 'h', distance : 210, autoPlay : false, onMouseOverPause : false
360 387 }
361 388 );
362 389 $('#demo5-backward').click(
... ...
frontend/views/site/help.php
... ... @@ -4,7 +4,6 @@
4 4 */
5 5 use yii\base\View;
6 6 ?>
7   -
8 7 <div class="section-box-28-bg">
9 8 <div class="box-wr">
10 9 <div class="box-all">
... ...
frontend/web/css/art_box.css
... ... @@ -8,4 +8,4 @@
8 8 .remover_image {
9 9 position: absolute;
10 10 cursor: pointer;
11   -}
12 11 \ No newline at end of file
  12 +}
... ...
frontend/web/css/owl.carousel.css 0 → 100644
  1 +/*
  2 + * Owl Carousel - Animate Plugin
  3 + */
  4 +.owl-carousel .animated {
  5 + -webkit-animation-duration: 1000ms;
  6 + animation-duration: 1000ms;
  7 + -webkit-animation-fill-mode: both;
  8 + animation-fill-mode: both;
  9 +}
  10 +.owl-carousel .owl-animated-in {
  11 + z-index: 0;
  12 +}
  13 +.owl-carousel .owl-animated-out {
  14 + z-index: 1;
  15 +}
  16 +.owl-carousel .fadeOut {
  17 + -webkit-animation-name: fadeOut;
  18 + animation-name: fadeOut;
  19 +}
  20 +
  21 +@-webkit-keyframes fadeOut {
  22 + 0% {
  23 + opacity: 1;
  24 + }
  25 +
  26 + 100% {
  27 + opacity: 0;
  28 + }
  29 +}
  30 +@keyframes fadeOut {
  31 + 0% {
  32 + opacity: 1;
  33 + }
  34 +
  35 + 100% {
  36 + opacity: 0;
  37 + }
  38 +}
  39 +
  40 +/*
  41 + * Owl Carousel - Auto Height Plugin
  42 + */
  43 +.owl-height {
  44 + -webkit-transition: height 500ms ease-in-out;
  45 + -moz-transition: height 500ms ease-in-out;
  46 + -ms-transition: height 500ms ease-in-out;
  47 + -o-transition: height 500ms ease-in-out;
  48 + transition: height 500ms ease-in-out;
  49 +}
  50 +
  51 +/*
  52 + * Core Owl Carousel CSS File
  53 + */
  54 +.owl-carousel {
  55 + display: none;
  56 + width: 100%;
  57 + -webkit-tap-highlight-color: transparent;
  58 + /* position relative and z-index fix webkit rendering fonts issue */
  59 + position: relative;
  60 + z-index: 1;
  61 +}
  62 +.owl-carousel .owl-stage {
  63 + position: relative;
  64 + -ms-touch-action: pan-Y;
  65 +}
  66 +.owl-carousel .owl-stage:after {
  67 + content: ".";
  68 + display: block;
  69 + clear: both;
  70 + visibility: hidden;
  71 + line-height: 0;
  72 + height: 0;
  73 +}
  74 +.owl-carousel .owl-stage-outer {
  75 + position: relative;
  76 + overflow: hidden;
  77 + /* fix for flashing background */
  78 + -webkit-transform: translate3d(0px, 0px, 0px);
  79 +}
  80 +.owl-carousel .owl-controls .owl-nav .owl-prev,
  81 +.owl-carousel .owl-controls .owl-nav .owl-next,
  82 +.owl-carousel .owl-controls .owl-dot {
  83 + cursor: pointer;
  84 + cursor: hand;
  85 + -webkit-user-select: none;
  86 + -khtml-user-select: none;
  87 + -moz-user-select: none;
  88 + -ms-user-select: none;
  89 + user-select: none;
  90 +}
  91 +.owl-carousel.owl-loaded {
  92 + display: block;
  93 +}
  94 +.owl-carousel.owl-loading {
  95 + opacity: 0;
  96 + display: block;
  97 +}
  98 +.owl-carousel.owl-hidden {
  99 + opacity: 0;
  100 +}
  101 +.owl-carousel .owl-refresh .owl-item {
  102 + display: none;
  103 +}
  104 +.owl-carousel .owl-item {
  105 + position: relative;
  106 + min-height: 1px;
  107 + float: left;
  108 + -webkit-backface-visibility: hidden;
  109 + -webkit-tap-highlight-color: transparent;
  110 + -webkit-touch-callout: none;
  111 + -webkit-user-select: none;
  112 + -moz-user-select: none;
  113 + -ms-user-select: none;
  114 + user-select: none;
  115 +}
  116 +.owl-carousel .owl-item img {
  117 + display: block;
  118 + width: 100%;
  119 + -webkit-transform-style: preserve-3d;
  120 +}
  121 +.owl-carousel.owl-text-select-on .owl-item {
  122 + -webkit-user-select: auto;
  123 + -moz-user-select: auto;
  124 + -ms-user-select: auto;
  125 + user-select: auto;
  126 +}
  127 +.owl-carousel .owl-grab {
  128 + cursor: move;
  129 + cursor: -webkit-grab;
  130 + cursor: -o-grab;
  131 + cursor: -ms-grab;
  132 + cursor: grab;
  133 +}
  134 +.owl-carousel.owl-rtl {
  135 + direction: rtl;
  136 +}
  137 +.owl-carousel.owl-rtl .owl-item {
  138 + float: right;
  139 +}
  140 +
  141 +/* No Js */
  142 +.no-js .owl-carousel {
  143 + display: block;
  144 +}
  145 +
  146 +/*
  147 + * Owl Carousel - Lazy Load Plugin
  148 + */
  149 +.owl-carousel .owl-item .owl-lazy {
  150 + opacity: 0;
  151 + -webkit-transition: opacity 400ms ease;
  152 + -moz-transition: opacity 400ms ease;
  153 + -ms-transition: opacity 400ms ease;
  154 + -o-transition: opacity 400ms ease;
  155 + transition: opacity 400ms ease;
  156 +}
  157 +.owl-carousel .owl-item img {
  158 + transform-style: preserve-3d;
  159 +}
  160 +
  161 +/*
  162 + * Owl Carousel - Video Plugin
  163 + */
  164 +.owl-carousel .owl-video-wrapper {
  165 + position: relative;
  166 + height: 100%;
  167 + background: #000;
  168 +}
  169 +.owl-carousel .owl-video-play-icon {
  170 + position: absolute;
  171 + height: 80px;
  172 + width: 80px;
  173 + left: 50%;
  174 + top: 50%;
  175 + margin-left: -40px;
  176 + margin-top: -40px;
  177 + background: url("owl.video.play.png") no-repeat;
  178 + cursor: pointer;
  179 + z-index: 1;
  180 + -webkit-backface-visibility: hidden;
  181 + -webkit-transition: scale 100ms ease;
  182 + -moz-transition: scale 100ms ease;
  183 + -ms-transition: scale 100ms ease;
  184 + -o-transition: scale 100ms ease;
  185 + transition: scale 100ms ease;
  186 +}
  187 +.owl-carousel .owl-video-play-icon:hover {
  188 + -webkit-transition: scale(1.3, 1.3);
  189 + -moz-transition: scale(1.3, 1.3);
  190 + -ms-transition: scale(1.3, 1.3);
  191 + -o-transition: scale(1.3, 1.3);
  192 + transition: scale(1.3, 1.3);
  193 +}
  194 +.owl-carousel .owl-video-playing .owl-video-tn,
  195 +.owl-carousel .owl-video-playing .owl-video-play-icon {
  196 + display: none;
  197 +}
  198 +.owl-carousel .owl-video-tn {
  199 + opacity: 0;
  200 + height: 100%;
  201 + background-position: center center;
  202 + background-repeat: no-repeat;
  203 + -webkit-background-size: contain;
  204 + -moz-background-size: contain;
  205 + -o-background-size: contain;
  206 + background-size: contain;
  207 + -webkit-transition: opacity 400ms ease;
  208 + -moz-transition: opacity 400ms ease;
  209 + -ms-transition: opacity 400ms ease;
  210 + -o-transition: opacity 400ms ease;
  211 + transition: opacity 400ms ease;
  212 +}
  213 +.owl-carousel .owl-video-frame {
  214 + position: relative;
  215 + z-index: 1;
  216 +}
... ...
frontend/web/css/style.css
... ... @@ -6718,3 +6718,27 @@ input[disabled], select[disabled] {
6718 6718 .section-box.registration input.custom-check + label span {
6719 6719 margin-left: 30px;
6720 6720 }
  6721 +
  6722 +.user_search_modal_grid .user_search_modal_item_image {
  6723 + width: 100px;
  6724 + height: 100px;
  6725 + overflow: hidden;
  6726 +}
  6727 +
  6728 +.user_search_modal_grid .user_search_modal_input_id {
  6729 + width: 50px;
  6730 +}
  6731 +.user_search_modal_grid .user_search_modal_specialization {
  6732 + width: 100px;
  6733 +}
  6734 +.user_search_modal_grid .user_search_modal_tick {
  6735 + width:15px;
  6736 + height:15px;
  6737 + background:url("/images/tick.png");
  6738 + display:block;
  6739 + background-size:cover;
  6740 + cursor:pointer;
  6741 +}
  6742 +.add_project_user_wrapper .add_project_user_link {
  6743 + cursor: pointer;
  6744 +}
... ...
frontend/web/js/jquery.scrollbox.min.js
1   -(function($){$.fn.scrollbox=function(config){var defConfig={linear:false,startDelay:2,delay:3,step:5,speed:32,switchItems:1,direction:"vertical",distance:"auto",autoPlay:true,onMouseOverPause:true,paused:false,queue:null,listElement:"ul",listItemElement:"li",infiniteLoop:true,switchAmount:0,afterForward:null,afterBackward:null,triggerStackable:false};config=$.extend(defConfig,config);config.scrollOffset=config.direction==="vertical"?"scrollTop":"scrollLeft";if(config.queue){config.queue=$("#"+config.queue)}return this.each(function(){var container=$(this),containerUL,scrollingId=null,nextScrollId=null,paused=false,releaseStack,backward,forward,resetClock,scrollForward,scrollBackward,forwardHover,pauseHover,switchCount=0,stackedTriggerIndex=0;if(config.onMouseOverPause){container.bind("mouseover",function(){paused=true});container.bind("mouseout",function(){paused=false})}containerUL=container.children(config.listElement+":first-child");if(config.infiniteLoop===false&&config.switchAmount===0){config.switchAmount=containerUL.children().length}scrollForward=function(){if(paused){return}var curLi,i,newScrollOffset,scrollDistance,theStep;curLi=containerUL.children(config.listItemElement+":first-child");scrollDistance=config.distance!=="auto"?config.distance:config.direction==="vertical"?curLi.outerHeight(true):curLi.outerWidth(true);if(!config.linear){theStep=Math.max(3,parseInt((scrollDistance-container[0][config.scrollOffset])*.3,10));newScrollOffset=Math.min(container[0][config.scrollOffset]+theStep,scrollDistance)}else{newScrollOffset=Math.min(container[0][config.scrollOffset]+config.step,scrollDistance)}container[0][config.scrollOffset]=newScrollOffset;if(newScrollOffset>=scrollDistance){for(i=0;i<config.switchItems;i++){if(config.queue&&config.queue.find(config.listItemElement).length>0){containerUL.append(config.queue.find(config.listItemElement)[0]);containerUL.children(config.listItemElement+":first-child").remove()}else{containerUL.append(containerUL.children(config.listItemElement+":first-child"))}++switchCount}container[0][config.scrollOffset]=0;clearInterval(scrollingId);scrollingId=null;if($.isFunction(config.afterForward)){config.afterForward.call(container,{switchCount:switchCount,currentFirstChild:containerUL.children(config.listItemElement+":first-child")})}if(config.triggerStackable&&stackedTriggerIndex!==0){releaseStack();return}if(config.infiniteLoop===false&&switchCount>=config.switchAmount){return}if(config.autoPlay){nextScrollId=setTimeout(forward,config.delay*1e3)}}};scrollBackward=function(){if(paused){return}var curLi,i,newScrollOffset,scrollDistance,theStep;if(container[0][config.scrollOffset]===0){for(i=0;i<config.switchItems;i++){containerUL.children(config.listItemElement+":last-child").insertBefore(containerUL.children(config.listItemElement+":first-child"))}curLi=containerUL.children(config.listItemElement+":first-child");scrollDistance=config.distance!=="auto"?config.distance:config.direction==="vertical"?curLi.height():curLi.width();container[0][config.scrollOffset]=scrollDistance}if(!config.linear){theStep=Math.max(3,parseInt(container[0][config.scrollOffset]*.3,10));newScrollOffset=Math.max(container[0][config.scrollOffset]-theStep,0)}else{newScrollOffset=Math.max(container[0][config.scrollOffset]-config.step,0)}container[0][config.scrollOffset]=newScrollOffset;if(newScrollOffset===0){--switchCount;clearInterval(scrollingId);scrollingId=null;if($.isFunction(config.afterBackward)){config.afterBackward.call(container,{switchCount:switchCount,currentFirstChild:containerUL.children(config.listItemElement+":first-child")})}if(config.triggerStackable&&stackedTriggerIndex!==0){releaseStack();return}if(config.autoPlay){nextScrollId=setTimeout(forward,config.delay*1e3)}}};releaseStack=function(){if(stackedTriggerIndex===0){return}if(stackedTriggerIndex>0){stackedTriggerIndex--;nextScrollId=setTimeout(forward,0)}else{stackedTriggerIndex++;nextScrollId=setTimeout(backward,0)}};forward=function(){clearInterval(scrollingId);scrollingId=setInterval(scrollForward,config.speed)};backward=function(){clearInterval(scrollingId);scrollingId=setInterval(scrollBackward,config.speed)};forwardHover=function(){config.autoPlay=true;paused=false;clearInterval(scrollingId);scrollingId=setInterval(scrollForward,config.speed)};pauseHover=function(){paused=true};resetClock=function(delay){config.delay=delay||config.delay;clearTimeout(nextScrollId);if(config.autoPlay){nextScrollId=setTimeout(forward,config.delay*1e3)}};if(config.autoPlay){nextScrollId=setTimeout(forward,config.startDelay*1e3)}container.bind("resetClock",function(delay){resetClock(delay)});container.bind("forward",function(){if(config.triggerStackable){if(scrollingId!==null){stackedTriggerIndex++}else{forward()}}else{clearTimeout(nextScrollId);forward()}});container.bind("backward",function(){if(config.triggerStackable){if(scrollingId!==null){stackedTriggerIndex--}else{backward()}}else{clearTimeout(nextScrollId);backward()}});container.bind("pauseHover",function(){pauseHover()});container.bind("forwardHover",function(){forwardHover()});container.bind("speedUp",function(speed){if(speed==="undefined"){speed=Math.max(1,parseInt(config.speed/2,10))}config.speed=speed});container.bind("speedDown",function(speed){if(speed==="undefined"){speed=config.speed*2}config.speed=speed});container.bind("updateConfig",function(options){config=$.extend(config,options)})})}})(jQuery);
2 1 \ No newline at end of file
  2 +(function($){$.fn.scrollbox=function(config){ var defConfig={linear:false,startDelay:2,delay:3,step:5,speed:32,switchItems:1,direction:"vertical",distance:"auto",autoPlay:true,onMouseOverPause:true,paused:false,queue:null,listElement:"ul",listItemElement:"li",infiniteLoop:true,switchAmount:0,afterForward:null,afterBackward:null,triggerStackable:false};config=$.extend(defConfig,config);config.scrollOffset=config.direction==="vertical"?"scrollTop":"scrollLeft";if(config.queue){config.queue=$("#"+config.queue)}return this.each(function(){var container=$(this),containerUL,scrollingId=null,nextScrollId=null,paused=false,releaseStack,backward,forward,resetClock,scrollForward,scrollBackward,forwardHover,pauseHover,switchCount=0,stackedTriggerIndex=0;if(config.onMouseOverPause){container.bind("mouseover",function(){paused=true});container.bind("mouseout",function(){paused=false})}containerUL=container.children(config.listElement+":first-child");if(config.infiniteLoop===false&&config.switchAmount===0){config.switchAmount=containerUL.children().length}scrollForward=function(){if(paused){return}var curLi,i,newScrollOffset,scrollDistance,theStep;curLi=containerUL.children(config.listItemElement+":first-child");scrollDistance=config.distance!=="auto"?config.distance:config.direction==="vertical"?curLi.outerHeight(true):curLi.outerWidth(true);if(!config.linear){theStep=Math.max(3,parseInt((scrollDistance-container[0][config.scrollOffset])*.3,10));newScrollOffset=Math.min(container[0][config.scrollOffset]+theStep,scrollDistance)}else{newScrollOffset=Math.min(container[0][config.scrollOffset]+config.step,scrollDistance)}container[0][config.scrollOffset]=newScrollOffset;if(newScrollOffset>=scrollDistance){for(i=0;i<config.switchItems;i++){if(config.queue&&config.queue.find(config.listItemElement).length>0){containerUL.append(config.queue.find(config.listItemElement)[0]);containerUL.children(config.listItemElement+":first-child").remove()}else{containerUL.append(containerUL.children(config.listItemElement+":first-child"))}++switchCount}container[0][config.scrollOffset]=0;clearInterval(scrollingId);scrollingId=null;if($.isFunction(config.afterForward)){config.afterForward.call(container,{switchCount:switchCount,currentFirstChild:containerUL.children(config.listItemElement+":first-child")})}if(config.triggerStackable&&stackedTriggerIndex!==0){releaseStack();return}if(config.infiniteLoop===false&&switchCount>=config.switchAmount){return}if(config.autoPlay){nextScrollId=setTimeout(forward,config.delay*1e3)}}};scrollBackward=function(){if(paused){return}var curLi,i,newScrollOffset,scrollDistance,theStep;if(container[0][config.scrollOffset]===0){for(i=0;i<config.switchItems;i++){containerUL.children(config.listItemElement+":last-child").insertBefore(containerUL.children(config.listItemElement+":first-child"))}curLi=containerUL.children(config.listItemElement+":first-child");scrollDistance=config.distance!=="auto"?config.distance:config.direction==="vertical"?curLi.height():curLi.width();container[0][config.scrollOffset]=scrollDistance}if(!config.linear){theStep=Math.max(3,parseInt(container[0][config.scrollOffset]*.3,10));newScrollOffset=Math.max(container[0][config.scrollOffset]-theStep,0)}else{newScrollOffset=Math.max(container[0][config.scrollOffset]-config.step,0)}container[0][config.scrollOffset]=newScrollOffset;if(newScrollOffset===0){--switchCount;clearInterval(scrollingId);scrollingId=null;if($.isFunction(config.afterBackward)){config.afterBackward.call(container,{switchCount:switchCount,currentFirstChild:containerUL.children(config.listItemElement+":first-child")})}if(config.triggerStackable&&stackedTriggerIndex!==0){releaseStack();return}if(config.autoPlay){nextScrollId=setTimeout(forward,config.delay*1e3)}}};releaseStack=function(){if(stackedTriggerIndex===0){return}if(stackedTriggerIndex>0){stackedTriggerIndex--;nextScrollId=setTimeout(forward,0)}else{stackedTriggerIndex++;nextScrollId=setTimeout(backward,0)}};forward=function(){clearInterval(scrollingId);scrollingId=setInterval(scrollForward,config.speed)};backward=function(){clearInterval(scrollingId);scrollingId=setInterval(scrollBackward,config.speed)};forwardHover=function(){config.autoPlay=true;paused=false;clearInterval(scrollingId);scrollingId=setInterval(scrollForward,config.speed)};pauseHover=function(){paused=true};resetClock=function(delay){config.delay=delay||config.delay;clearTimeout(nextScrollId);if(config.autoPlay){nextScrollId=setTimeout(forward,config.delay*1e3)}};if(config.autoPlay){nextScrollId=setTimeout(forward,config.startDelay*1e3)}container.bind("resetClock",function(delay){resetClock(delay)});container.bind("forward",function(){if(config.triggerStackable){if(scrollingId!==null){stackedTriggerIndex++}else{forward()}}else{clearTimeout(nextScrollId);forward()}});container.bind("backward",function(){if(config.triggerStackable){if(scrollingId!==null){stackedTriggerIndex--}else{backward()}}else{clearTimeout(nextScrollId);backward()}});container.bind("pauseHover",function(){pauseHover()});container.bind("forwardHover",function(){forwardHover()});container.bind("speedUp",function(speed){if(speed==="undefined"){speed=Math.max(1,parseInt(config.speed/2,10))}config.speed=speed});container.bind("speedDown",function(speed){if(speed==="undefined"){speed=config.speed*2}config.speed=speed});container.bind("updateConfig",function(options){config=$.extend(config,options)})})}})(jQuery);
3 3 \ No newline at end of file
... ...
frontend/web/js/no-comprss/owl.carousel.js 0 → 100644
  1 +/**
  2 + * Owl carousel
  3 + * @version 2.0.0
  4 + * @author Bartosz Wojciechowski
  5 + * @license The MIT License (MIT)
  6 + * @todo Lazy Load Icon
  7 + * @todo prevent animationend bubling
  8 + * @todo itemsScaleUp
  9 + * @todo Test Zepto
  10 + * @todo stagePadding calculate wrong active classes
  11 + */
  12 +;(function($, window, document, undefined) {
  13 +
  14 + var drag, state, e;
  15 +
  16 + /**
  17 + * Template for status information about drag and touch events.
  18 + * @private
  19 + */
  20 + drag = {
  21 + start: 0,
  22 + startX: 0,
  23 + startY: 0,
  24 + current: 0,
  25 + currentX: 0,
  26 + currentY: 0,
  27 + offsetX: 0,
  28 + offsetY: 0,
  29 + distance: null,
  30 + startTime: 0,
  31 + endTime: 0,
  32 + updatedX: 0,
  33 + targetEl: null
  34 + };
  35 +
  36 + /**
  37 + * Template for some status informations.
  38 + * @private
  39 + */
  40 + state = {
  41 + isTouch: false,
  42 + isScrolling: false,
  43 + isSwiping: false,
  44 + direction: false,
  45 + inMotion: false
  46 + };
  47 +
  48 + /**
  49 + * Event functions references.
  50 + * @private
  51 + */
  52 + e = {
  53 + _onDragStart: null,
  54 + _onDragMove: null,
  55 + _onDragEnd: null,
  56 + _transitionEnd: null,
  57 + _resizer: null,
  58 + _responsiveCall: null,
  59 + _goToLoop: null,
  60 + _checkVisibile: null
  61 + };
  62 +
  63 + /**
  64 + * Creates a carousel.
  65 + * @class The Owl Carousel.
  66 + * @public
  67 + * @param {HTMLElement|jQuery} element - The element to create the carousel for.
  68 + * @param {Object} [options] - The options
  69 + */
  70 + function Owl(element, options) {
  71 +
  72 + /**
  73 + * Current settings for the carousel.
  74 + * @public
  75 + */
  76 + this.settings = null;
  77 +
  78 + /**
  79 + * Current options set by the caller including defaults.
  80 + * @public
  81 + */
  82 + this.options = $.extend({}, Owl.Defaults, options);
  83 +
  84 + /**
  85 + * Plugin element.
  86 + * @public
  87 + */
  88 + this.$element = $(element);
  89 +
  90 + /**
  91 + * Caches informations about drag and touch events.
  92 + */
  93 + this.drag = $.extend({}, drag);
  94 +
  95 + /**
  96 + * Caches some status informations.
  97 + * @protected
  98 + */
  99 + this.state = $.extend({}, state);
  100 +
  101 + /**
  102 + * @protected
  103 + * @todo Must be documented
  104 + */
  105 + this.e = $.extend({}, e);
  106 +
  107 + /**
  108 + * References to the running plugins of this carousel.
  109 + * @protected
  110 + */
  111 + this._plugins = {};
  112 +
  113 + /**
  114 + * Currently suppressed events to prevent them from beeing retriggered.
  115 + * @protected
  116 + */
  117 + this._supress = {};
  118 +
  119 + /**
  120 + * Absolute current position.
  121 + * @protected
  122 + */
  123 + this._current = null;
  124 +
  125 + /**
  126 + * Animation speed in milliseconds.
  127 + * @protected
  128 + */
  129 + this._speed = null;
  130 +
  131 + /**
  132 + * Coordinates of all items in pixel.
  133 + * @todo The name of this member is missleading.
  134 + * @protected
  135 + */
  136 + this._coordinates = [];
  137 +
  138 + /**
  139 + * Current breakpoint.
  140 + * @todo Real media queries would be nice.
  141 + * @protected
  142 + */
  143 + this._breakpoint = null;
  144 +
  145 + /**
  146 + * Current width of the plugin element.
  147 + */
  148 + this._width = null;
  149 +
  150 + /**
  151 + * All real items.
  152 + * @protected
  153 + */
  154 + this._items = [];
  155 +
  156 + /**
  157 + * All cloned items.
  158 + * @protected
  159 + */
  160 + this._clones = [];
  161 +
  162 + /**
  163 + * Merge values of all items.
  164 + * @todo Maybe this could be part of a plugin.
  165 + * @protected
  166 + */
  167 + this._mergers = [];
  168 +
  169 + /**
  170 + * Invalidated parts within the update process.
  171 + * @protected
  172 + */
  173 + this._invalidated = {};
  174 +
  175 + /**
  176 + * Ordered list of workers for the update process.
  177 + * @protected
  178 + */
  179 + this._pipe = [];
  180 +
  181 + $.each(Owl.Plugins, $.proxy(function(key, plugin) {
  182 + this._plugins[key[0].toLowerCase() + key.slice(1)]
  183 + = new plugin(this);
  184 + }, this));
  185 +
  186 + $.each(Owl.Pipe, $.proxy(function(priority, worker) {
  187 + this._pipe.push({
  188 + 'filter': worker.filter,
  189 + 'run': $.proxy(worker.run, this)
  190 + });
  191 + }, this));
  192 +
  193 + this.setup();
  194 + this.initialize();
  195 + }
  196 +
  197 + /**
  198 + * Default options for the carousel.
  199 + * @public
  200 + */
  201 + Owl.Defaults = {
  202 + items: 3,
  203 + loop: false,
  204 + center: false,
  205 +
  206 + mouseDrag: true,
  207 + touchDrag: true,
  208 + pullDrag: true,
  209 + freeDrag: false,
  210 +
  211 + margin: 0,
  212 + stagePadding: 0,
  213 +
  214 + merge: false,
  215 + mergeFit: true,
  216 + autoWidth: false,
  217 +
  218 + startPosition: 0,
  219 + rtl: false,
  220 +
  221 + smartSpeed: 250,
  222 + fluidSpeed: false,
  223 + dragEndSpeed: false,
  224 +
  225 + responsive: {},
  226 + responsiveRefreshRate: 200,
  227 + responsiveBaseElement: window,
  228 + responsiveClass: false,
  229 +
  230 + fallbackEasing: 'swing',
  231 +
  232 + info: false,
  233 +
  234 + nestedItemSelector: false,
  235 + itemElement: 'div',
  236 + stageElement: 'div',
  237 +
  238 + // Classes and Names
  239 + themeClass: 'owl-theme',
  240 + baseClass: 'owl-carousel',
  241 + itemClass: 'owl-item',
  242 + centerClass: 'center',
  243 + activeClass: 'active'
  244 + };
  245 +
  246 + /**
  247 + * Enumeration for width.
  248 + * @public
  249 + * @readonly
  250 + * @enum {String}
  251 + */
  252 + Owl.Width = {
  253 + Default: 'default',
  254 + Inner: 'inner',
  255 + Outer: 'outer'
  256 + };
  257 +
  258 + /**
  259 + * Contains all registered plugins.
  260 + * @public
  261 + */
  262 + Owl.Plugins = {};
  263 +
  264 + /**
  265 + * Update pipe.
  266 + */
  267 + Owl.Pipe = [ {
  268 + filter: [ 'width', 'items', 'settings' ],
  269 + run: function(cache) {
  270 + cache.current = this._items && this._items[this.relative(this._current)];
  271 + }
  272 + }, {
  273 + filter: [ 'items', 'settings' ],
  274 + run: function() {
  275 + var cached = this._clones,
  276 + clones = this.$stage.children('.cloned');
  277 +
  278 + if (clones.length !== cached.length || (!this.settings.loop && cached.length > 0)) {
  279 + this.$stage.children('.cloned').remove();
  280 + this._clones = [];
  281 + }
  282 + }
  283 + }, {
  284 + filter: [ 'items', 'settings' ],
  285 + run: function() {
  286 + var i, n,
  287 + clones = this._clones,
  288 + items = this._items,
  289 + delta = this.settings.loop ? clones.length - Math.max(this.settings.items * 2, 4) : 0;
  290 +
  291 + for (i = 0, n = Math.abs(delta / 2); i < n; i++) {
  292 + if (delta > 0) {
  293 + this.$stage.children().eq(items.length + clones.length - 1).remove();
  294 + clones.pop();
  295 + this.$stage.children().eq(0).remove();
  296 + clones.pop();
  297 + } else {
  298 + clones.push(clones.length / 2);
  299 + this.$stage.append(items[clones[clones.length - 1]].clone().addClass('cloned'));
  300 + clones.push(items.length - 1 - (clones.length - 1) / 2);
  301 + this.$stage.prepend(items[clones[clones.length - 1]].clone().addClass('cloned'));
  302 + }
  303 + }
  304 + }
  305 + }, {
  306 + filter: [ 'width', 'items', 'settings' ],
  307 + run: function() {
  308 + var rtl = (this.settings.rtl ? 1 : -1),
  309 + width = (this.width() / this.settings.items).toFixed(3),
  310 + coordinate = 0, merge, i, n;
  311 +
  312 + this._coordinates = [];
  313 + for (i = 0, n = this._clones.length + this._items.length; i < n; i++) {
  314 + merge = this._mergers[this.relative(i)];
  315 + merge = (this.settings.mergeFit && Math.min(merge, this.settings.items)) || merge;
  316 + coordinate += (this.settings.autoWidth ? this._items[this.relative(i)].width() + this.settings.margin : width * merge) * rtl;
  317 +
  318 + this._coordinates.push(coordinate);
  319 + }
  320 + }
  321 + }, {
  322 + filter: [ 'width', 'items', 'settings' ],
  323 + run: function() {
  324 + var i, n, width = (this.width() / this.settings.items).toFixed(3), css = {
  325 + 'width': Math.abs(this._coordinates[this._coordinates.length - 1]) + this.settings.stagePadding * 2,
  326 + 'padding-left': this.settings.stagePadding || '',
  327 + 'padding-right': this.settings.stagePadding || ''
  328 + };
  329 +
  330 + this.$stage.css(css);
  331 +
  332 + css = { 'width': this.settings.autoWidth ? 'auto' : width - this.settings.margin };
  333 + css[this.settings.rtl ? 'margin-left' : 'margin-right'] = this.settings.margin;
  334 +
  335 + if (!this.settings.autoWidth && $.grep(this._mergers, function(v) { return v > 1 }).length > 0) {
  336 + for (i = 0, n = this._coordinates.length; i < n; i++) {
  337 + css.width = Math.abs(this._coordinates[i]) - Math.abs(this._coordinates[i - 1] || 0) - this.settings.margin;
  338 + this.$stage.children().eq(i).css(css);
  339 + }
  340 + } else {
  341 + this.$stage.children().css(css);
  342 + }
  343 + }
  344 + }, {
  345 + filter: [ 'width', 'items', 'settings' ],
  346 + run: function(cache) {
  347 + cache.current && this.reset(this.$stage.children().index(cache.current));
  348 + }
  349 + }, {
  350 + filter: [ 'position' ],
  351 + run: function() {
  352 + this.animate(this.coordinates(this._current));
  353 + }
  354 + }, {
  355 + filter: [ 'width', 'position', 'items', 'settings' ],
  356 + run: function() {
  357 + var rtl = this.settings.rtl ? 1 : -1,
  358 + padding = this.settings.stagePadding * 2,
  359 + begin = this.coordinates(this.current()) + padding,
  360 + end = begin + this.width() * rtl,
  361 + inner, outer, matches = [], i, n;
  362 +
  363 + for (i = 0, n = this._coordinates.length; i < n; i++) {
  364 + inner = this._coordinates[i - 1] || 0;
  365 + outer = Math.abs(this._coordinates[i]) + padding * rtl;
  366 +
  367 + if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end)))
  368 + || (this.op(outer, '<', begin) && this.op(outer, '>', end))) {
  369 + matches.push(i);
  370 + }
  371 + }
  372 +
  373 + this.$stage.children('.' + this.settings.activeClass).removeClass(this.settings.activeClass);
  374 + this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass(this.settings.activeClass);
  375 +
  376 + if (this.settings.center) {
  377 + this.$stage.children('.' + this.settings.centerClass).removeClass(this.settings.centerClass);
  378 + this.$stage.children().eq(this.current()).addClass(this.settings.centerClass);
  379 + }
  380 + }
  381 + } ];
  382 +
  383 + /**
  384 + * Initializes the carousel.
  385 + * @protected
  386 + */
  387 + Owl.prototype.initialize = function() {
  388 + this.trigger('initialize');
  389 +
  390 + this.$element
  391 + .addClass(this.settings.baseClass)
  392 + .addClass(this.settings.themeClass)
  393 + .toggleClass('owl-rtl', this.settings.rtl);
  394 +
  395 + // check support
  396 + this.browserSupport();
  397 +
  398 + if (this.settings.autoWidth && this.state.imagesLoaded !== true) {
  399 + var imgs, nestedSelector, width;
  400 + imgs = this.$element.find('img');
  401 + nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined;
  402 + width = this.$element.children(nestedSelector).width();
  403 +
  404 + if (imgs.length && width <= 0) {
  405 + this.preloadAutoWidthImages(imgs);
  406 + return false;
  407 + }
  408 + }
  409 +
  410 + this.$element.addClass('owl-loading');
  411 +
  412 + // create stage
  413 + this.$stage = $('<' + this.settings.stageElement + ' class="owl-stage"/>')
  414 + .wrap('<div class="owl-stage-outer">');
  415 +
  416 + // append stage
  417 + this.$element.append(this.$stage.parent());
  418 +
  419 + // append content
  420 + this.replace(this.$element.children().not(this.$stage.parent()));
  421 +
  422 + // set view width
  423 + this._width = this.$element.width();
  424 +
  425 + // update view
  426 + this.refresh();
  427 +
  428 + this.$element.removeClass('owl-loading').addClass('owl-loaded');
  429 +
  430 + // attach generic events
  431 + this.eventsCall();
  432 +
  433 + // attach generic events
  434 + this.internalEvents();
  435 +
  436 + // attach custom control events
  437 + this.addTriggerableEvents();
  438 +
  439 + this.trigger('initialized');
  440 + };
  441 +
  442 + /**
  443 + * Setups the current settings.
  444 + * @todo Remove responsive classes. Why should adaptive designs be brought into IE8?
  445 + * @todo Support for media queries by using `matchMedia` would be nice.
  446 + * @public
  447 + */
  448 + Owl.prototype.setup = function() {
  449 + var viewport = this.viewport(),
  450 + overwrites = this.options.responsive,
  451 + match = -1,
  452 + settings = null;
  453 +
  454 + if (!overwrites) {
  455 + settings = $.extend({}, this.options);
  456 + } else {
  457 + $.each(overwrites, function(breakpoint) {
  458 + if (breakpoint <= viewport && breakpoint > match) {
  459 + match = Number(breakpoint);
  460 + }
  461 + });
  462 +
  463 + settings = $.extend({}, this.options, overwrites[match]);
  464 + delete settings.responsive;
  465 +
  466 + // responsive class
  467 + if (settings.responsiveClass) {
  468 + this.$element.attr('class', function(i, c) {
  469 + return c.replace(/\b owl-responsive-\S+/g, '');
  470 + }).addClass('owl-responsive-' + match);
  471 + }
  472 + }
  473 +
  474 + if (this.settings === null || this._breakpoint !== match) {
  475 + this.trigger('change', { property: { name: 'settings', value: settings } });
  476 + this._breakpoint = match;
  477 + this.settings = settings;
  478 + this.invalidate('settings');
  479 + this.trigger('changed', { property: { name: 'settings', value: this.settings } });
  480 + }
  481 + };
  482 +
  483 + /**
  484 + * Updates option logic if necessery.
  485 + * @protected
  486 + */
  487 + Owl.prototype.optionsLogic = function() {
  488 + // Toggle Center class
  489 + this.$element.toggleClass('owl-center', this.settings.center);
  490 +
  491 + // if items number is less than in body
  492 + if (this.settings.loop && this._items.length < this.settings.items) {
  493 + this.settings.loop = false;
  494 + }
  495 +
  496 + if (this.settings.autoWidth) {
  497 + this.settings.stagePadding = false;
  498 + this.settings.merge = false;
  499 + }
  500 + };
  501 +
  502 + /**
  503 + * Prepares an item before add.
  504 + * @todo Rename event parameter `content` to `item`.
  505 + * @protected
  506 + * @returns {jQuery|HTMLElement} - The item container.
  507 + */
  508 + Owl.prototype.prepare = function(item) {
  509 + var event = this.trigger('prepare', { content: item });
  510 +
  511 + if (!event.data) {
  512 + event.data = $('<' + this.settings.itemElement + '/>')
  513 + .addClass(this.settings.itemClass).append(item)
  514 + }
  515 +
  516 + this.trigger('prepared', { content: event.data });
  517 +
  518 + return event.data;
  519 + };
  520 +
  521 + /**
  522 + * Updates the view.
  523 + * @public
  524 + */
  525 + Owl.prototype.update = function() {
  526 + var i = 0,
  527 + n = this._pipe.length,
  528 + filter = $.proxy(function(p) { return this[p] }, this._invalidated),
  529 + cache = {};
  530 +
  531 + while (i < n) {
  532 + if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) {
  533 + this._pipe[i].run(cache);
  534 + }
  535 + i++;
  536 + }
  537 +
  538 + this._invalidated = {};
  539 + };
  540 +
  541 + /**
  542 + * Gets the width of the view.
  543 + * @public
  544 + * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return.
  545 + * @returns {Number} - The width of the view in pixel.
  546 + */
  547 + Owl.prototype.width = function(dimension) {
  548 + dimension = dimension || Owl.Width.Default;
  549 + switch (dimension) {
  550 + case Owl.Width.Inner:
  551 + case Owl.Width.Outer:
  552 + return this._width;
  553 + default:
  554 + return this._width - this.settings.stagePadding * 2 + this.settings.margin;
  555 + }
  556 + };
  557 +
  558 + /**
  559 + * Refreshes the carousel primarily for adaptive purposes.
  560 + * @public
  561 + */
  562 + Owl.prototype.refresh = function() {
  563 + if (this._items.length === 0) {
  564 + return false;
  565 + }
  566 +
  567 + var start = new Date().getTime();
  568 +
  569 + this.trigger('refresh');
  570 +
  571 + this.setup();
  572 +
  573 + this.optionsLogic();
  574 +
  575 + // hide and show methods helps here to set a proper widths,
  576 + // this prevents scrollbar to be calculated in stage width
  577 + this.$stage.addClass('owl-refresh');
  578 +
  579 + this.update();
  580 +
  581 + this.$stage.removeClass('owl-refresh');
  582 +
  583 + this.state.orientation = window.orientation;
  584 +
  585 + this.watchVisibility();
  586 +
  587 + this.trigger('refreshed');
  588 + };
  589 +
  590 + /**
  591 + * Save internal event references and add event based functions.
  592 + * @protected
  593 + */
  594 + Owl.prototype.eventsCall = function() {
  595 + // Save events references
  596 + this.e._onDragStart = $.proxy(function(e) {
  597 + this.onDragStart(e);
  598 + }, this);
  599 + this.e._onDragMove = $.proxy(function(e) {
  600 + this.onDragMove(e);
  601 + }, this);
  602 + this.e._onDragEnd = $.proxy(function(e) {
  603 + this.onDragEnd(e);
  604 + }, this);
  605 + this.e._onResize = $.proxy(function(e) {
  606 + this.onResize(e);
  607 + }, this);
  608 + this.e._transitionEnd = $.proxy(function(e) {
  609 + this.transitionEnd(e);
  610 + }, this);
  611 + this.e._preventClick = $.proxy(function(e) {
  612 + this.preventClick(e);
  613 + }, this);
  614 + };
  615 +
  616 + /**
  617 + * Checks window `resize` event.
  618 + * @protected
  619 + */
  620 + Owl.prototype.onThrottledResize = function() {
  621 + window.clearTimeout(this.resizeTimer);
  622 + this.resizeTimer = window.setTimeout(this.e._onResize, this.settings.responsiveRefreshRate);
  623 + };
  624 +
  625 + /**
  626 + * Checks window `resize` event.
  627 + * @protected
  628 + */
  629 + Owl.prototype.onResize = function() {
  630 + if (!this._items.length) {
  631 + return false;
  632 + }
  633 +
  634 + if (this._width === this.$element.width()) {
  635 + return false;
  636 + }
  637 +
  638 + if (this.trigger('resize').isDefaultPrevented()) {
  639 + return false;
  640 + }
  641 +
  642 + this._width = this.$element.width();
  643 +
  644 + this.invalidate('width');
  645 +
  646 + this.refresh();
  647 +
  648 + this.trigger('resized');
  649 + };
  650 +
  651 + /**
  652 + * Checks for touch/mouse drag event type and add run event handlers.
  653 + * @protected
  654 + */
  655 + Owl.prototype.eventsRouter = function(event) {
  656 + var type = event.type;
  657 +
  658 + if (type === "mousedown" || type === "touchstart") {
  659 + this.onDragStart(event);
  660 + } else if (type === "mousemove" || type === "touchmove") {
  661 + this.onDragMove(event);
  662 + } else if (type === "mouseup" || type === "touchend") {
  663 + this.onDragEnd(event);
  664 + } else if (type === "touchcancel") {
  665 + this.onDragEnd(event);
  666 + }
  667 + };
  668 +
  669 + /**
  670 + * Checks for touch/mouse drag options and add necessery event handlers.
  671 + * @protected
  672 + */
  673 + Owl.prototype.internalEvents = function() {
  674 + var isTouch = isTouchSupport(),
  675 + isTouchIE = isTouchSupportIE();
  676 +
  677 + if (this.settings.mouseDrag){
  678 + this.$stage.on('mousedown', $.proxy(function(event) { this.eventsRouter(event) }, this));
  679 + this.$stage.on('dragstart', function() { return false });
  680 + this.$stage.get(0).onselectstart = function() { return false };
  681 + } else {
  682 + this.$element.addClass('owl-text-select-on');
  683 + }
  684 +
  685 + if (this.settings.touchDrag && !isTouchIE){
  686 + this.$stage.on('touchstart touchcancel', $.proxy(function(event) { this.eventsRouter(event) }, this));
  687 + }
  688 +
  689 + // catch transitionEnd event
  690 + if (this.transitionEndVendor) {
  691 + this.on(this.$stage.get(0), this.transitionEndVendor, this.e._transitionEnd, false);
  692 + }
  693 +
  694 + // responsive
  695 + if (this.settings.responsive !== false) {
  696 + this.on(window, 'resize', $.proxy(this.onThrottledResize, this));
  697 + }
  698 + };
  699 +
  700 + /**
  701 + * Handles touchstart/mousedown event.
  702 + * @protected
  703 + * @param {Event} event - The event arguments.
  704 + */
  705 + Owl.prototype.onDragStart = function(event) {
  706 + var ev, isTouchEvent, pageX, pageY, animatedPos;
  707 +
  708 + ev = event.originalEvent || event || window.event;
  709 +
  710 + // prevent right click
  711 + if (ev.which === 3 || this.state.isTouch) {
  712 + return false;
  713 + }
  714 +
  715 + if (ev.type === 'mousedown') {
  716 + this.$stage.addClass('owl-grab');
  717 + }
  718 +
  719 + this.trigger('drag');
  720 + this.drag.startTime = new Date().getTime();
  721 + this.speed(0);
  722 + this.state.isTouch = true;
  723 + this.state.isScrolling = false;
  724 + this.state.isSwiping = false;
  725 + this.drag.distance = 0;
  726 +
  727 + pageX = getTouches(ev).x;
  728 + pageY = getTouches(ev).y;
  729 +
  730 + // get stage position left
  731 + this.drag.offsetX = this.$stage.position().left;
  732 + this.drag.offsetY = this.$stage.position().top;
  733 +
  734 + if (this.settings.rtl) {
  735 + this.drag.offsetX = this.$stage.position().left + this.$stage.width() - this.width()
  736 + + this.settings.margin;
  737 + }
  738 +
  739 + // catch position // ie to fix
  740 + if (this.state.inMotion && this.support3d) {
  741 + animatedPos = this.getTransformProperty();
  742 + this.drag.offsetX = animatedPos;
  743 + this.animate(animatedPos);
  744 + this.state.inMotion = true;
  745 + } else if (this.state.inMotion && !this.support3d) {
  746 + this.state.inMotion = false;
  747 + return false;
  748 + }
  749 +
  750 + this.drag.startX = pageX - this.drag.offsetX;
  751 + this.drag.startY = pageY - this.drag.offsetY;
  752 +
  753 + this.drag.start = pageX - this.drag.startX;
  754 + this.drag.targetEl = ev.target || ev.srcElement;
  755 + this.drag.updatedX = this.drag.start;
  756 +
  757 + // to do/check
  758 + // prevent links and images dragging;
  759 + if (this.drag.targetEl.tagName === "IMG" || this.drag.targetEl.tagName === "A") {
  760 + this.drag.targetEl.draggable = false;
  761 + }
  762 +
  763 + $(document).on('mousemove.owl.dragEvents mouseup.owl.dragEvents touchmove.owl.dragEvents touchend.owl.dragEvents', $.proxy(function(event) {this.eventsRouter(event)},this));
  764 + };
  765 +
  766 + /**
  767 + * Handles the touchmove/mousemove events.
  768 + * @todo Simplify
  769 + * @protected
  770 + * @param {Event} event - The event arguments.
  771 + */
  772 + Owl.prototype.onDragMove = function(event) {
  773 + var ev, isTouchEvent, pageX, pageY, minValue, maxValue, pull;
  774 +
  775 + if (!this.state.isTouch) {
  776 + return;
  777 + }
  778 +
  779 + if (this.state.isScrolling) {
  780 + return;
  781 + }
  782 +
  783 + ev = event.originalEvent || event || window.event;
  784 +
  785 + pageX = getTouches(ev).x;
  786 + pageY = getTouches(ev).y;
  787 +
  788 + // Drag Direction
  789 + this.drag.currentX = pageX - this.drag.startX;
  790 + this.drag.currentY = pageY - this.drag.startY;
  791 + this.drag.distance = this.drag.currentX - this.drag.offsetX;
  792 +
  793 + // Check move direction
  794 + if (this.drag.distance < 0) {
  795 + this.state.direction = this.settings.rtl ? 'right' : 'left';
  796 + } else if (this.drag.distance > 0) {
  797 + this.state.direction = this.settings.rtl ? 'left' : 'right';
  798 + }
  799 + // Loop
  800 + if (this.settings.loop) {
  801 + if (this.op(this.drag.currentX, '>', this.coordinates(this.minimum())) && this.state.direction === 'right') {
  802 + this.drag.currentX -= (this.settings.center && this.coordinates(0)) - this.coordinates(this._items.length);
  803 + } else if (this.op(this.drag.currentX, '<', this.coordinates(this.maximum())) && this.state.direction === 'left') {
  804 + this.drag.currentX += (this.settings.center && this.coordinates(0)) - this.coordinates(this._items.length);
  805 + }
  806 + } else {
  807 + // pull
  808 + minValue = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum());
  809 + maxValue = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum());
  810 + pull = this.settings.pullDrag ? this.drag.distance / 5 : 0;
  811 + this.drag.currentX = Math.max(Math.min(this.drag.currentX, minValue + pull), maxValue + pull);
  812 + }
  813 +
  814 + // Lock browser if swiping horizontal
  815 +
  816 + if ((this.drag.distance > 8 || this.drag.distance < -8)) {
  817 + if (ev.preventDefault !== undefined) {
  818 + ev.preventDefault();
  819 + } else {
  820 + ev.returnValue = false;
  821 + }
  822 + this.state.isSwiping = true;
  823 + }
  824 +
  825 + this.drag.updatedX = this.drag.currentX;
  826 +
  827 + // Lock Owl if scrolling
  828 + if ((this.drag.currentY > 16 || this.drag.currentY < -16) && this.state.isSwiping === false) {
  829 + this.state.isScrolling = true;
  830 + this.drag.updatedX = this.drag.start;
  831 + }
  832 +
  833 + this.animate(this.drag.updatedX);
  834 + };
  835 +
  836 + /**
  837 + * Handles the touchend/mouseup events.
  838 + * @protected
  839 + */
  840 + Owl.prototype.onDragEnd = function(event) {
  841 + var compareTimes, distanceAbs, closest;
  842 +
  843 + if (!this.state.isTouch) {
  844 + return;
  845 + }
  846 +
  847 + if (event.type === 'mouseup') {
  848 + this.$stage.removeClass('owl-grab');
  849 + }
  850 +
  851 + this.trigger('dragged');
  852 +
  853 + // prevent links and images dragging;
  854 + this.drag.targetEl.removeAttribute("draggable");
  855 +
  856 + // remove drag event listeners
  857 +
  858 + this.state.isTouch = false;
  859 + this.state.isScrolling = false;
  860 + this.state.isSwiping = false;
  861 +
  862 + // to check
  863 + if (this.drag.distance === 0 && this.state.inMotion !== true) {
  864 + this.state.inMotion = false;
  865 + return false;
  866 + }
  867 +
  868 + // prevent clicks while scrolling
  869 +
  870 + this.drag.endTime = new Date().getTime();
  871 + compareTimes = this.drag.endTime - this.drag.startTime;
  872 + distanceAbs = Math.abs(this.drag.distance);
  873 +
  874 + // to test
  875 + if (distanceAbs > 3 || compareTimes > 300) {
  876 + this.removeClick(this.drag.targetEl);
  877 + }
  878 +
  879 + closest = this.closest(this.drag.updatedX);
  880 +
  881 + this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed);
  882 + this.current(closest);
  883 + this.invalidate('position');
  884 + this.update();
  885 +
  886 + // if pullDrag is off then fire transitionEnd event manually when stick
  887 + // to border
  888 + if (!this.settings.pullDrag && this.drag.updatedX === this.coordinates(closest)) {
  889 + this.transitionEnd();
  890 + }
  891 +
  892 + this.drag.distance = 0;
  893 +
  894 + $(document).off('.owl.dragEvents');
  895 + };
  896 +
  897 + /**
  898 + * Attaches `preventClick` to disable link while swipping.
  899 + * @protected
  900 + * @param {HTMLElement} [target] - The target of the `click` event.
  901 + */
  902 + Owl.prototype.removeClick = function(target) {
  903 + this.drag.targetEl = target;
  904 + $(target).on('click.preventClick', this.e._preventClick);
  905 + // to make sure click is removed:
  906 + window.setTimeout(function() {
  907 + $(target).off('click.preventClick');
  908 + }, 300);
  909 + };
  910 +
  911 + /**
  912 + * Suppresses click event.
  913 + * @protected
  914 + * @param {Event} ev - The event arguments.
  915 + */
  916 + Owl.prototype.preventClick = function(ev) {
  917 + if (ev.preventDefault) {
  918 + ev.preventDefault();
  919 + } else {
  920 + ev.returnValue = false;
  921 + }
  922 + if (ev.stopPropagation) {
  923 + ev.stopPropagation();
  924 + }
  925 + $(ev.target).off('click.preventClick');
  926 + };
  927 +
  928 + /**
  929 + * Catches stage position while animate (only CSS3).
  930 + * @protected
  931 + * @returns
  932 + */
  933 + Owl.prototype.getTransformProperty = function() {
  934 + var transform, matrix3d;
  935 +
  936 + transform = window.getComputedStyle(this.$stage.get(0), null).getPropertyValue(this.vendorName + 'transform');
  937 + // var transform = this.$stage.css(this.vendorName + 'transform')
  938 + transform = transform.replace(/matrix(3d)?\(|\)/g, '').split(',');
  939 + matrix3d = transform.length === 16;
  940 +
  941 + return matrix3d !== true ? transform[4] : transform[12];
  942 + };
  943 +
  944 + /**
  945 + * Gets absolute position of the closest item for a coordinate.
  946 + * @todo Setting `freeDrag` makes `closest` not reusable. See #165.
  947 + * @protected
  948 + * @param {Number} coordinate - The coordinate in pixel.
  949 + * @return {Number} - The absolute position of the closest item.
  950 + */
  951 + Owl.prototype.closest = function(coordinate) {
  952 + var position = -1, pull = 30, width = this.width(), coordinates = this.coordinates();
  953 +
  954 + if (!this.settings.freeDrag) {
  955 + // check closest item
  956 + $.each(coordinates, $.proxy(function(index, value) {
  957 + if (coordinate > value - pull && coordinate < value + pull) {
  958 + position = index;
  959 + } else if (this.op(coordinate, '<', value)
  960 + && this.op(coordinate, '>', coordinates[index + 1] || value - width)) {
  961 + position = this.state.direction === 'left' ? index + 1 : index;
  962 + }
  963 + return position === -1;
  964 + }, this));
  965 + }
  966 +
  967 + if (!this.settings.loop) {
  968 + // non loop boundries
  969 + if (this.op(coordinate, '>', coordinates[this.minimum()])) {
  970 + position = coordinate = this.minimum();
  971 + } else if (this.op(coordinate, '<', coordinates[this.maximum()])) {
  972 + position = coordinate = this.maximum();
  973 + }
  974 + }
  975 +
  976 + return position;
  977 + };
  978 +
  979 + /**
  980 + * Animates the stage.
  981 + * @public
  982 + * @param {Number} coordinate - The coordinate in pixels.
  983 + */
  984 + Owl.prototype.animate = function(coordinate) {
  985 + this.trigger('translate');
  986 + this.state.inMotion = this.speed() > 0;
  987 +
  988 + if (this.support3d) {
  989 + this.$stage.css({
  990 + transform: 'translate3d(' + coordinate + 'px' + ',0px, 0px)',
  991 + transition: (this.speed() / 1000) + 's'
  992 + });
  993 + } else if (this.state.isTouch) {
  994 + this.$stage.css({
  995 + left: coordinate + 'px'
  996 + });
  997 + } else {
  998 + this.$stage.animate({
  999 + left: coordinate
  1000 + }, this.speed() / 1000, this.settings.fallbackEasing, $.proxy(function() {
  1001 + if (this.state.inMotion) {
  1002 + this.transitionEnd();
  1003 + }
  1004 + }, this));
  1005 + }
  1006 + };
  1007 +
  1008 + /**
  1009 + * Sets the absolute position of the current item.
  1010 + * @public
  1011 + * @param {Number} [position] - The new absolute position or nothing to leave it unchanged.
  1012 + * @returns {Number} - The absolute position of the current item.
  1013 + */
  1014 + Owl.prototype.current = function(position) {
  1015 + if (position === undefined) {
  1016 + return this._current;
  1017 + }
  1018 +
  1019 + if (this._items.length === 0) {
  1020 + return undefined;
  1021 + }
  1022 +
  1023 + position = this.normalize(position);
  1024 +
  1025 + if (this._current !== position) {
  1026 + var event = this.trigger('change', { property: { name: 'position', value: position } });
  1027 +
  1028 + if (event.data !== undefined) {
  1029 + position = this.normalize(event.data);
  1030 + }
  1031 +
  1032 + this._current = position;
  1033 +
  1034 + this.invalidate('position');
  1035 +
  1036 + this.trigger('changed', { property: { name: 'position', value: this._current } });
  1037 + }
  1038 +
  1039 + return this._current;
  1040 + };
  1041 +
  1042 + /**
  1043 + * Invalidates the given part of the update routine.
  1044 + * @param {String} part - The part to invalidate.
  1045 + */
  1046 + Owl.prototype.invalidate = function(part) {
  1047 + this._invalidated[part] = true;
  1048 + }
  1049 +
  1050 + /**
  1051 + * Resets the absolute position of the current item.
  1052 + * @public
  1053 + * @param {Number} position - The absolute position of the new item.
  1054 + */
  1055 + Owl.prototype.reset = function(position) {
  1056 + position = this.normalize(position);
  1057 +
  1058 + if (position === undefined) {
  1059 + return;
  1060 + }
  1061 +
  1062 + this._speed = 0;
  1063 + this._current = position;
  1064 +
  1065 + this.suppress([ 'translate', 'translated' ]);
  1066 +
  1067 + this.animate(this.coordinates(position));
  1068 +
  1069 + this.release([ 'translate', 'translated' ]);
  1070 + };
  1071 +
  1072 + /**
  1073 + * Normalizes an absolute or a relative position for an item.
  1074 + * @public
  1075 + * @param {Number} position - The absolute or relative position to normalize.
  1076 + * @param {Boolean} [relative=false] - Whether the given position is relative or not.
  1077 + * @returns {Number} - The normalized position.
  1078 + */
  1079 + Owl.prototype.normalize = function(position, relative) {
  1080 + var n = (relative ? this._items.length : this._items.length + this._clones.length);
  1081 +
  1082 + if (!$.isNumeric(position) || n < 1) {
  1083 + return undefined;
  1084 + }
  1085 +
  1086 + if (this._clones.length) {
  1087 + position = ((position % n) + n) % n;
  1088 + } else {
  1089 + position = Math.max(this.minimum(relative), Math.min(this.maximum(relative), position));
  1090 + }
  1091 +
  1092 + return position;
  1093 + };
  1094 +
  1095 + /**
  1096 + * Converts an absolute position for an item into a relative position.
  1097 + * @public
  1098 + * @param {Number} position - The absolute position to convert.
  1099 + * @returns {Number} - The converted position.
  1100 + */
  1101 + Owl.prototype.relative = function(position) {
  1102 + position = this.normalize(position);
  1103 + position = position - this._clones.length / 2;
  1104 + return this.normalize(position, true);
  1105 + };
  1106 +
  1107 + /**
  1108 + * Gets the maximum position for an item.
  1109 + * @public
  1110 + * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
  1111 + * @returns {Number}
  1112 + */
  1113 + Owl.prototype.maximum = function(relative) {
  1114 + var maximum, width, i = 0, coordinate,
  1115 + settings = this.settings;
  1116 +
  1117 + if (relative) {
  1118 + return this._items.length - 1;
  1119 + }
  1120 +
  1121 + if (!settings.loop && settings.center) {
  1122 + maximum = this._items.length - 1;
  1123 + } else if (!settings.loop && !settings.center) {
  1124 + maximum = this._items.length - settings.items;
  1125 + } else if (settings.loop || settings.center) {
  1126 + maximum = this._items.length + settings.items;
  1127 + } else if (settings.autoWidth || settings.merge) {
  1128 + revert = settings.rtl ? 1 : -1;
  1129 + width = this.$stage.width() - this.$element.width();
  1130 + while (coordinate = this.coordinates(i)) {
  1131 + if (coordinate * revert >= width) {
  1132 + break;
  1133 + }
  1134 + maximum = ++i;
  1135 + }
  1136 + } else {
  1137 + throw 'Can not detect maximum absolute position.'
  1138 + }
  1139 +
  1140 + return maximum;
  1141 + };
  1142 +
  1143 + /**
  1144 + * Gets the minimum position for an item.
  1145 + * @public
  1146 + * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
  1147 + * @returns {Number}
  1148 + */
  1149 + Owl.prototype.minimum = function(relative) {
  1150 + if (relative) {
  1151 + return 0;
  1152 + }
  1153 +
  1154 + return this._clones.length / 2;
  1155 + };
  1156 +
  1157 + /**
  1158 + * Gets an item at the specified relative position.
  1159 + * @public
  1160 + * @param {Number} [position] - The relative position of the item.
  1161 + * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
  1162 + */
  1163 + Owl.prototype.items = function(position) {
  1164 + if (position === undefined) {
  1165 + return this._items.slice();
  1166 + }
  1167 +
  1168 + position = this.normalize(position, true);
  1169 + return this._items[position];
  1170 + };
  1171 +
  1172 + /**
  1173 + * Gets an item at the specified relative position.
  1174 + * @public
  1175 + * @param {Number} [position] - The relative position of the item.
  1176 + * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
  1177 + */
  1178 + Owl.prototype.mergers = function(position) {
  1179 + if (position === undefined) {
  1180 + return this._mergers.slice();
  1181 + }
  1182 +
  1183 + position = this.normalize(position, true);
  1184 + return this._mergers[position];
  1185 + };
  1186 +
  1187 + /**
  1188 + * Gets the absolute positions of clones for an item.
  1189 + * @public
  1190 + * @param {Number} [position] - The relative position of the item.
  1191 + * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given.
  1192 + */
  1193 + Owl.prototype.clones = function(position) {
  1194 + var odd = this._clones.length / 2,
  1195 + even = odd + this._items.length,
  1196 + map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 };
  1197 +
  1198 + if (position === undefined) {
  1199 + return $.map(this._clones, function(v, i) { return map(i) });
  1200 + }
  1201 +
  1202 + return $.map(this._clones, function(v, i) { return v === position ? map(i) : null });
  1203 + };
  1204 +
  1205 + /**
  1206 + * Sets the current animation speed.
  1207 + * @public
  1208 + * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged.
  1209 + * @returns {Number} - The current animation speed in milliseconds.
  1210 + */
  1211 + Owl.prototype.speed = function(speed) {
  1212 + if (speed !== undefined) {
  1213 + this._speed = speed;
  1214 + }
  1215 +
  1216 + return this._speed;
  1217 + };
  1218 +
  1219 + /**
  1220 + * Gets the coordinate of an item.
  1221 + * @todo The name of this method is missleanding.
  1222 + * @public
  1223 + * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`.
  1224 + * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates.
  1225 + */
  1226 + Owl.prototype.coordinates = function(position) {
  1227 + var coordinate = null;
  1228 +
  1229 + if (position === undefined) {
  1230 + return $.map(this._coordinates, $.proxy(function(coordinate, index) {
  1231 + return this.coordinates(index);
  1232 + }, this));
  1233 + }
  1234 +
  1235 + if (this.settings.center) {
  1236 + coordinate = this._coordinates[position];
  1237 + coordinate += (this.width() - coordinate + (this._coordinates[position - 1] || 0)) / 2 * (this.settings.rtl ? -1 : 1);
  1238 + } else {
  1239 + coordinate = this._coordinates[position - 1] || 0;
  1240 + }
  1241 +
  1242 + return coordinate;
  1243 + };
  1244 +
  1245 + /**
  1246 + * Calculates the speed for a translation.
  1247 + * @protected
  1248 + * @param {Number} from - The absolute position of the start item.
  1249 + * @param {Number} to - The absolute position of the target item.
  1250 + * @param {Number} [factor=undefined] - The time factor in milliseconds.
  1251 + * @returns {Number} - The time in milliseconds for the translation.
  1252 + */
  1253 + Owl.prototype.duration = function(from, to, factor) {
  1254 + return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed));
  1255 + };
  1256 +
  1257 + /**
  1258 + * Slides to the specified item.
  1259 + * @public
  1260 + * @param {Number} position - The position of the item.
  1261 + * @param {Number} [speed] - The time in milliseconds for the transition.
  1262 + */
  1263 + Owl.prototype.to = function(position, speed) {
  1264 + if (this.settings.loop) {
  1265 + var distance = position - this.relative(this.current()),
  1266 + revert = this.current(),
  1267 + before = this.current(),
  1268 + after = this.current() + distance,
  1269 + direction = before - after < 0 ? true : false,
  1270 + items = this._clones.length + this._items.length;
  1271 +
  1272 + if (after < this.settings.items && direction === false) {
  1273 + revert = before + this._items.length;
  1274 + this.reset(revert);
  1275 + } else if (after >= items - this.settings.items && direction === true) {
  1276 + revert = before - this._items.length;
  1277 + this.reset(revert);
  1278 + }
  1279 + window.clearTimeout(this.e._goToLoop);
  1280 + this.e._goToLoop = window.setTimeout($.proxy(function() {
  1281 + this.speed(this.duration(this.current(), revert + distance, speed));
  1282 + this.current(revert + distance);
  1283 + this.update();
  1284 + }, this), 30);
  1285 + } else {
  1286 + this.speed(this.duration(this.current(), position, speed));
  1287 + this.current(position);
  1288 + this.update();
  1289 + }
  1290 + };
  1291 +
  1292 + /**
  1293 + * Slides to the next item.
  1294 + * @public
  1295 + * @param {Number} [speed] - The time in milliseconds for the transition.
  1296 + */
  1297 + Owl.prototype.next = function(speed) {
  1298 + speed = speed || false;
  1299 + this.to(this.relative(this.current()) + 1, speed);
  1300 + };
  1301 +
  1302 + /**
  1303 + * Slides to the previous item.
  1304 + * @public
  1305 + * @param {Number} [speed] - The time in milliseconds for the transition.
  1306 + */
  1307 + Owl.prototype.prev = function(speed) {
  1308 + speed = speed || false;
  1309 + this.to(this.relative(this.current()) - 1, speed);
  1310 + };
  1311 +
  1312 + /**
  1313 + * Handles the end of an animation.
  1314 + * @protected
  1315 + * @param {Event} event - The event arguments.
  1316 + */
  1317 + Owl.prototype.transitionEnd = function(event) {
  1318 +
  1319 + // if css2 animation then event object is undefined
  1320 + if (event !== undefined) {
  1321 + event.stopPropagation();
  1322 +
  1323 + // Catch only owl-stage transitionEnd event
  1324 + if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) {
  1325 + return false;
  1326 + }
  1327 + }
  1328 +
  1329 + this.state.inMotion = false;
  1330 + this.trigger('translated');
  1331 + };
  1332 +
  1333 + /**
  1334 + * Gets viewport width.
  1335 + * @protected
  1336 + * @return {Number} - The width in pixel.
  1337 + */
  1338 + Owl.prototype.viewport = function() {
  1339 + var width;
  1340 + if (this.options.responsiveBaseElement !== window) {
  1341 + width = $(this.options.responsiveBaseElement).width();
  1342 + } else if (window.innerWidth) {
  1343 + width = window.innerWidth;
  1344 + } else if (document.documentElement && document.documentElement.clientWidth) {
  1345 + width = document.documentElement.clientWidth;
  1346 + } else {
  1347 + throw 'Can not detect viewport width.';
  1348 + }
  1349 + return width;
  1350 + };
  1351 +
  1352 + /**
  1353 + * Replaces the current content.
  1354 + * @public
  1355 + * @param {HTMLElement|jQuery|String} content - The new content.
  1356 + */
  1357 + Owl.prototype.replace = function(content) {
  1358 + this.$stage.empty();
  1359 + this._items = [];
  1360 +
  1361 + if (content) {
  1362 + content = (content instanceof jQuery) ? content : $(content);
  1363 + }
  1364 +
  1365 + if (this.settings.nestedItemSelector) {
  1366 + content = content.find('.' + this.settings.nestedItemSelector);
  1367 + }
  1368 +
  1369 + content.filter(function() {
  1370 + return this.nodeType === 1;
  1371 + }).each($.proxy(function(index, item) {
  1372 + item = this.prepare(item);
  1373 + this.$stage.append(item);
  1374 + this._items.push(item);
  1375 + this._mergers.push(item.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1);
  1376 + }, this));
  1377 +
  1378 + this.reset($.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0);
  1379 +
  1380 + this.invalidate('items');
  1381 + };
  1382 +
  1383 + /**
  1384 + * Adds an item.
  1385 + * @todo Use `item` instead of `content` for the event arguments.
  1386 + * @public
  1387 + * @param {HTMLElement|jQuery|String} content - The item content to add.
  1388 + * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end.
  1389 + */
  1390 + Owl.prototype.add = function(content, position) {
  1391 + position = position === undefined ? this._items.length : this.normalize(position, true);
  1392 +
  1393 + this.trigger('add', { content: content, position: position });
  1394 +
  1395 + if (this._items.length === 0 || position === this._items.length) {
  1396 + this.$stage.append(content);
  1397 + this._items.push(content);
  1398 + this._mergers.push(content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1);
  1399 + } else {
  1400 + this._items[position].before(content);
  1401 + this._items.splice(position, 0, content);
  1402 + this._mergers.splice(position, 0, content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1);
  1403 + }
  1404 +
  1405 + this.invalidate('items');
  1406 +
  1407 + this.trigger('added', { content: content, position: position });
  1408 + };
  1409 +
  1410 + /**
  1411 + * Removes an item by its position.
  1412 + * @todo Use `item` instead of `content` for the event arguments.
  1413 + * @public
  1414 + * @param {Number} position - The relative position of the item to remove.
  1415 + */
  1416 + Owl.prototype.remove = function(position) {
  1417 + position = this.normalize(position, true);
  1418 +
  1419 + if (position === undefined) {
  1420 + return;
  1421 + }
  1422 +
  1423 + this.trigger('remove', { content: this._items[position], position: position });
  1424 +
  1425 + this._items[position].remove();
  1426 + this._items.splice(position, 1);
  1427 + this._mergers.splice(position, 1);
  1428 +
  1429 + this.invalidate('items');
  1430 +
  1431 + this.trigger('removed', { content: null, position: position });
  1432 + };
  1433 +
  1434 + /**
  1435 + * Adds triggerable events.
  1436 + * @protected
  1437 + */
  1438 + Owl.prototype.addTriggerableEvents = function() {
  1439 + var handler = $.proxy(function(callback, event) {
  1440 + return $.proxy(function(e) {
  1441 + if (e.relatedTarget !== this) {
  1442 + this.suppress([ event ]);
  1443 + callback.apply(this, [].slice.call(arguments, 1));
  1444 + this.release([ event ]);
  1445 + }
  1446 + }, this);
  1447 + }, this);
  1448 +
  1449 + $.each({
  1450 + 'next': this.next,
  1451 + 'prev': this.prev,
  1452 + 'to': this.to,
  1453 + 'destroy': this.destroy,
  1454 + 'refresh': this.refresh,
  1455 + 'replace': this.replace,
  1456 + 'add': this.add,
  1457 + 'remove': this.remove
  1458 + }, $.proxy(function(event, callback) {
  1459 + this.$element.on(event + '.owl.carousel', handler(callback, event + '.owl.carousel'));
  1460 + }, this));
  1461 +
  1462 + };
  1463 +
  1464 + /**
  1465 + * Watches the visibility of the carousel element.
  1466 + * @protected
  1467 + */
  1468 + Owl.prototype.watchVisibility = function() {
  1469 +
  1470 + // test on zepto
  1471 + if (!isElVisible(this.$element.get(0))) {
  1472 + this.$element.addClass('owl-hidden');
  1473 + window.clearInterval(this.e._checkVisibile);
  1474 + this.e._checkVisibile = window.setInterval($.proxy(checkVisible, this), 500);
  1475 + }
  1476 +
  1477 + function isElVisible(el) {
  1478 + return el.offsetWidth > 0 && el.offsetHeight > 0;
  1479 + }
  1480 +
  1481 + function checkVisible() {
  1482 + if (isElVisible(this.$element.get(0))) {
  1483 + this.$element.removeClass('owl-hidden');
  1484 + this.refresh();
  1485 + window.clearInterval(this.e._checkVisibile);
  1486 + }
  1487 + }
  1488 + };
  1489 +
  1490 + /**
  1491 + * Preloads images with auto width.
  1492 + * @protected
  1493 + * @todo Still to test
  1494 + */
  1495 + Owl.prototype.preloadAutoWidthImages = function(imgs) {
  1496 + var loaded, that, $el, img;
  1497 +
  1498 + loaded = 0;
  1499 + that = this;
  1500 + imgs.each(function(i, el) {
  1501 + $el = $(el);
  1502 + img = new Image();
  1503 +
  1504 + img.onload = function() {
  1505 + loaded++;
  1506 + $el.attr('src', img.src);
  1507 + $el.css('opacity', 1);
  1508 + if (loaded >= imgs.length) {
  1509 + that.state.imagesLoaded = true;
  1510 + that.initialize();
  1511 + }
  1512 + };
  1513 +
  1514 + img.src = $el.attr('src') || $el.attr('data-src') || $el.attr('data-src-retina');
  1515 + });
  1516 + };
  1517 +
  1518 + /**
  1519 + * Destroys the carousel.
  1520 + * @public
  1521 + */
  1522 + Owl.prototype.destroy = function() {
  1523 +
  1524 + if (this.$element.hasClass(this.settings.themeClass)) {
  1525 + this.$element.removeClass(this.settings.themeClass);
  1526 + }
  1527 +
  1528 + if (this.settings.responsive !== false) {
  1529 + $(window).off('resize.owl.carousel');
  1530 + }
  1531 +
  1532 + if (this.transitionEndVendor) {
  1533 + this.off(this.$stage.get(0), this.transitionEndVendor, this.e._transitionEnd);
  1534 + }
  1535 +
  1536 + for ( var i in this._plugins) {
  1537 + this._plugins[i].destroy();
  1538 + }
  1539 +
  1540 + if (this.settings.mouseDrag || this.settings.touchDrag) {
  1541 + this.$stage.off('mousedown touchstart touchcancel');
  1542 + $(document).off('.owl.dragEvents');
  1543 + this.$stage.get(0).onselectstart = function() {};
  1544 + this.$stage.off('dragstart', function() { return false });
  1545 + }
  1546 +
  1547 + // remove event handlers in the ".owl.carousel" namespace
  1548 + this.$element.off('.owl');
  1549 +
  1550 + this.$stage.children('.cloned').remove();
  1551 + this.e = null;
  1552 + this.$element.removeData('owlCarousel');
  1553 +
  1554 + this.$stage.children().contents().unwrap();
  1555 + this.$stage.children().unwrap();
  1556 + this.$stage.unwrap();
  1557 + };
  1558 +
  1559 + /**
  1560 + * Operators to calculate right-to-left and left-to-right.
  1561 + * @protected
  1562 + * @param {Number} [a] - The left side operand.
  1563 + * @param {String} [o] - The operator.
  1564 + * @param {Number} [b] - The right side operand.
  1565 + */
  1566 + Owl.prototype.op = function(a, o, b) {
  1567 + var rtl = this.settings.rtl;
  1568 + switch (o) {
  1569 + case '<':
  1570 + return rtl ? a > b : a < b;
  1571 + case '>':
  1572 + return rtl ? a < b : a > b;
  1573 + case '>=':
  1574 + return rtl ? a <= b : a >= b;
  1575 + case '<=':
  1576 + return rtl ? a >= b : a <= b;
  1577 + default:
  1578 + break;
  1579 + }
  1580 + };
  1581 +
  1582 + /**
  1583 + * Attaches to an internal event.
  1584 + * @protected
  1585 + * @param {HTMLElement} element - The event source.
  1586 + * @param {String} event - The event name.
  1587 + * @param {Function} listener - The event handler to attach.
  1588 + * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not.
  1589 + */
  1590 + Owl.prototype.on = function(element, event, listener, capture) {
  1591 + if (element.addEventListener) {
  1592 + element.addEventListener(event, listener, capture);
  1593 + } else if (element.attachEvent) {
  1594 + element.attachEvent('on' + event, listener);
  1595 + }
  1596 + };
  1597 +
  1598 + /**
  1599 + * Detaches from an internal event.
  1600 + * @protected
  1601 + * @param {HTMLElement} element - The event source.
  1602 + * @param {String} event - The event name.
  1603 + * @param {Function} listener - The attached event handler to detach.
  1604 + * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not.
  1605 + */
  1606 + Owl.prototype.off = function(element, event, listener, capture) {
  1607 + if (element.removeEventListener) {
  1608 + element.removeEventListener(event, listener, capture);
  1609 + } else if (element.detachEvent) {
  1610 + element.detachEvent('on' + event, listener);
  1611 + }
  1612 + };
  1613 +
  1614 + /**
  1615 + * Triggers an public event.
  1616 + * @protected
  1617 + * @param {String} name - The event name.
  1618 + * @param {*} [data=null] - The event data.
  1619 + * @param {String} [namespace=.owl.carousel] - The event namespace.
  1620 + * @returns {Event} - The event arguments.
  1621 + */
  1622 + Owl.prototype.trigger = function(name, data, namespace) {
  1623 + var status = {
  1624 + item: { count: this._items.length, index: this.current() }
  1625 + }, handler = $.camelCase(
  1626 + $.grep([ 'on', name, namespace ], function(v) { return v })
  1627 + .join('-').toLowerCase()
  1628 + ), event = $.Event(
  1629 + [ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(),
  1630 + $.extend({ relatedTarget: this }, status, data)
  1631 + );
  1632 +
  1633 + if (!this._supress[name]) {
  1634 + $.each(this._plugins, function(name, plugin) {
  1635 + if (plugin.onTrigger) {
  1636 + plugin.onTrigger(event);
  1637 + }
  1638 + });
  1639 +
  1640 + this.$element.trigger(event);
  1641 +
  1642 + if (this.settings && typeof this.settings[handler] === 'function') {
  1643 + this.settings[handler].apply(this, event);
  1644 + }
  1645 + }
  1646 +
  1647 + return event;
  1648 + };
  1649 +
  1650 + /**
  1651 + * Suppresses events.
  1652 + * @protected
  1653 + * @param {Array.<String>} events - The events to suppress.
  1654 + */
  1655 + Owl.prototype.suppress = function(events) {
  1656 + $.each(events, $.proxy(function(index, event) {
  1657 + this._supress[event] = true;
  1658 + }, this));
  1659 + }
  1660 +
  1661 + /**
  1662 + * Releases suppressed events.
  1663 + * @protected
  1664 + * @param {Array.<String>} events - The events to release.
  1665 + */
  1666 + Owl.prototype.release = function(events) {
  1667 + $.each(events, $.proxy(function(index, event) {
  1668 + delete this._supress[event];
  1669 + }, this));
  1670 + }
  1671 +
  1672 + /**
  1673 + * Checks the availability of some browser features.
  1674 + * @protected
  1675 + */
  1676 + Owl.prototype.browserSupport = function() {
  1677 + this.support3d = isPerspective();
  1678 +
  1679 + if (this.support3d) {
  1680 + this.transformVendor = isTransform();
  1681 +
  1682 + // take transitionend event name by detecting transition
  1683 + var endVendors = [ 'transitionend', 'webkitTransitionEnd', 'transitionend', 'oTransitionEnd' ];
  1684 + this.transitionEndVendor = endVendors[isTransition()];
  1685 +
  1686 + // take vendor name from transform name
  1687 + this.vendorName = this.transformVendor.replace(/Transform/i, '');
  1688 + this.vendorName = this.vendorName !== '' ? '-' + this.vendorName.toLowerCase() + '-' : '';
  1689 + }
  1690 +
  1691 + this.state.orientation = window.orientation;
  1692 + };
  1693 +
  1694 + /**
  1695 + * Get touch/drag coordinats.
  1696 + * @private
  1697 + * @param {event} - mousedown/touchstart event
  1698 + * @returns {object} - Contains X and Y of current mouse/touch position
  1699 + */
  1700 +
  1701 + function getTouches(event) {
  1702 + if (event.touches !== undefined) {
  1703 + return {
  1704 + x: event.touches[0].pageX,
  1705 + y: event.touches[0].pageY
  1706 + };
  1707 + }
  1708 +
  1709 + if (event.touches === undefined) {
  1710 + if (event.pageX !== undefined) {
  1711 + return {
  1712 + x: event.pageX,
  1713 + y: event.pageY
  1714 + };
  1715 + }
  1716 +
  1717 + if (event.pageX === undefined) {
  1718 + return {
  1719 + x: event.clientX,
  1720 + y: event.clientY
  1721 + };
  1722 + }
  1723 + }
  1724 + }
  1725 +
  1726 + /**
  1727 + * Checks for CSS support.
  1728 + * @private
  1729 + * @param {Array} array - The CSS properties to check for.
  1730 + * @returns {Array} - Contains the supported CSS property name and its index or `false`.
  1731 + */
  1732 + function isStyleSupported(array) {
  1733 + var p, s, fake = document.createElement('div'), list = array;
  1734 + for (p in list) {
  1735 + s = list[p];
  1736 + if (typeof fake.style[s] !== 'undefined') {
  1737 + fake = null;
  1738 + return [ s, p ];
  1739 + }
  1740 + }
  1741 + return [ false ];
  1742 + }
  1743 +
  1744 + /**
  1745 + * Checks for CSS transition support.
  1746 + * @private
  1747 + * @todo Realy bad design
  1748 + * @returns {Number}
  1749 + */
  1750 + function isTransition() {
  1751 + return isStyleSupported([ 'transition', 'WebkitTransition', 'MozTransition', 'OTransition' ])[1];
  1752 + }
  1753 +
  1754 + /**
  1755 + * Checks for CSS transform support.
  1756 + * @private
  1757 + * @returns {String} The supported property name or false.
  1758 + */
  1759 + function isTransform() {
  1760 + return isStyleSupported([ 'transform', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform' ])[0];
  1761 + }
  1762 +
  1763 + /**
  1764 + * Checks for CSS perspective support.
  1765 + * @private
  1766 + * @returns {String} The supported property name or false.
  1767 + */
  1768 + function isPerspective() {
  1769 + return isStyleSupported([ 'perspective', 'webkitPerspective', 'MozPerspective', 'OPerspective', 'MsPerspective' ])[0];
  1770 + }
  1771 +
  1772 + /**
  1773 + * Checks wether touch is supported or not.
  1774 + * @private
  1775 + * @returns {Boolean}
  1776 + */
  1777 + function isTouchSupport() {
  1778 + return 'ontouchstart' in window || !!(navigator.msMaxTouchPoints);
  1779 + }
  1780 +
  1781 + /**
  1782 + * Checks wether touch is supported or not for IE.
  1783 + * @private
  1784 + * @returns {Boolean}
  1785 + */
  1786 + function isTouchSupportIE() {
  1787 + return window.navigator.msPointerEnabled;
  1788 + }
  1789 +
  1790 + /**
  1791 + * The jQuery Plugin for the Owl Carousel
  1792 + * @public
  1793 + */
  1794 + $.fn.owlCarousel = function(options) {
  1795 + return this.each(function() {
  1796 + if (!$(this).data('owlCarousel')) {
  1797 + $(this).data('owlCarousel', new Owl(this, options));
  1798 + }
  1799 + });
  1800 + };
  1801 +
  1802 + /**
  1803 + * The constructor for the jQuery Plugin
  1804 + * @public
  1805 + */
  1806 + $.fn.owlCarousel.Constructor = Owl;
  1807 +
  1808 +})(window.Zepto || window.jQuery, window, document);
  1809 +
  1810 +/**
  1811 + * Lazy Plugin
  1812 + * @version 2.0.0
  1813 + * @author Bartosz Wojciechowski
  1814 + * @license The MIT License (MIT)
  1815 + */
  1816 +;(function($, window, document, undefined) {
  1817 +
  1818 + /**
  1819 + * Creates the lazy plugin.
  1820 + * @class The Lazy Plugin
  1821 + * @param {Owl} carousel - The Owl Carousel
  1822 + */
  1823 + var Lazy = function(carousel) {
  1824 +
  1825 + /**
  1826 + * Reference to the core.
  1827 + * @protected
  1828 + * @type {Owl}
  1829 + */
  1830 + this._core = carousel;
  1831 +
  1832 + /**
  1833 + * Already loaded items.
  1834 + * @protected
  1835 + * @type {Array.<jQuery>}
  1836 + */
  1837 + this._loaded = [];
  1838 +
  1839 + /**
  1840 + * Event handlers.
  1841 + * @protected
  1842 + * @type {Object}
  1843 + */
  1844 + this._handlers = {
  1845 + 'initialized.owl.carousel change.owl.carousel': $.proxy(function(e) {
  1846 + if (!e.namespace) {
  1847 + return;
  1848 + }
  1849 +
  1850 + if (!this._core.settings || !this._core.settings.lazyLoad) {
  1851 + return;
  1852 + }
  1853 +
  1854 + if ((e.property && e.property.name == 'position') || e.type == 'initialized') {
  1855 + var settings = this._core.settings,
  1856 + n = (settings.center && Math.ceil(settings.items / 2) || settings.items),
  1857 + i = ((settings.center && n * -1) || 0),
  1858 + position = ((e.property && e.property.value) || this._core.current()) + i,
  1859 + clones = this._core.clones().length,
  1860 + load = $.proxy(function(i, v) { this.load(v) }, this);
  1861 +
  1862 + while (i++ < n) {
  1863 + this.load(clones / 2 + this._core.relative(position));
  1864 + clones && $.each(this._core.clones(this._core.relative(position++)), load);
  1865 + }
  1866 + }
  1867 + }, this)
  1868 + };
  1869 +
  1870 + // set the default options
  1871 + this._core.options = $.extend({}, Lazy.Defaults, this._core.options);
  1872 +
  1873 + // register event handler
  1874 + this._core.$element.on(this._handlers);
  1875 + }
  1876 +
  1877 + /**
  1878 + * Default options.
  1879 + * @public
  1880 + */
  1881 + Lazy.Defaults = {
  1882 + lazyLoad: false
  1883 + }
  1884 +
  1885 + /**
  1886 + * Loads all resources of an item at the specified position.
  1887 + * @param {Number} position - The absolute position of the item.
  1888 + * @protected
  1889 + */
  1890 + Lazy.prototype.load = function(position) {
  1891 + var $item = this._core.$stage.children().eq(position),
  1892 + $elements = $item && $item.find('.owl-lazy');
  1893 +
  1894 + if (!$elements || $.inArray($item.get(0), this._loaded) > -1) {
  1895 + return;
  1896 + }
  1897 +
  1898 + $elements.each($.proxy(function(index, element) {
  1899 + var $element = $(element), image,
  1900 + url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src');
  1901 +
  1902 + this._core.trigger('load', { element: $element, url: url }, 'lazy');
  1903 +
  1904 + if ($element.is('img')) {
  1905 + $element.one('load.owl.lazy', $.proxy(function() {
  1906 + $element.css('opacity', 1);
  1907 + this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
  1908 + }, this)).attr('src', url);
  1909 + } else {
  1910 + image = new Image();
  1911 + image.onload = $.proxy(function() {
  1912 + $element.css({
  1913 + 'background-image': 'url(' + url + ')',
  1914 + 'opacity': '1'
  1915 + });
  1916 + this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
  1917 + }, this);
  1918 + image.src = url;
  1919 + }
  1920 + }, this));
  1921 +
  1922 + this._loaded.push($item.get(0));
  1923 + }
  1924 +
  1925 + /**
  1926 + * Destroys the plugin.
  1927 + * @public
  1928 + */
  1929 + Lazy.prototype.destroy = function() {
  1930 + var handler, property;
  1931 +
  1932 + for (handler in this.handlers) {
  1933 + this._core.$element.off(handler, this.handlers[handler]);
  1934 + }
  1935 + for (property in Object.getOwnPropertyNames(this)) {
  1936 + typeof this[property] != 'function' && (this[property] = null);
  1937 + }
  1938 + }
  1939 +
  1940 + $.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy;
  1941 +
  1942 +})(window.Zepto || window.jQuery, window, document);
  1943 +
  1944 +/**
  1945 + * AutoHeight Plugin
  1946 + * @version 2.0.0
  1947 + * @author Bartosz Wojciechowski
  1948 + * @license The MIT License (MIT)
  1949 + */
  1950 +;(function($, window, document, undefined) {
  1951 +
  1952 + /**
  1953 + * Creates the auto height plugin.
  1954 + * @class The Auto Height Plugin
  1955 + * @param {Owl} carousel - The Owl Carousel
  1956 + */
  1957 + var AutoHeight = function(carousel) {
  1958 + /**
  1959 + * Reference to the core.
  1960 + * @protected
  1961 + * @type {Owl}
  1962 + */
  1963 + this._core = carousel;
  1964 +
  1965 + /**
  1966 + * All event handlers.
  1967 + * @protected
  1968 + * @type {Object}
  1969 + */
  1970 + this._handlers = {
  1971 + 'initialized.owl.carousel': $.proxy(function() {
  1972 + if (this._core.settings.autoHeight) {
  1973 + this.update();
  1974 + }
  1975 + }, this),
  1976 + 'changed.owl.carousel': $.proxy(function(e) {
  1977 + if (this._core.settings.autoHeight && e.property.name == 'position'){
  1978 + this.update();
  1979 + }
  1980 + }, this),
  1981 + 'loaded.owl.lazy': $.proxy(function(e) {
  1982 + if (this._core.settings.autoHeight && e.element.closest('.' + this._core.settings.itemClass)
  1983 + === this._core.$stage.children().eq(this._core.current())) {
  1984 + this.update();
  1985 + }
  1986 + }, this)
  1987 + };
  1988 +
  1989 + // set default options
  1990 + this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options);
  1991 +
  1992 + // register event handlers
  1993 + this._core.$element.on(this._handlers);
  1994 + };
  1995 +
  1996 + /**
  1997 + * Default options.
  1998 + * @public
  1999 + */
  2000 + AutoHeight.Defaults = {
  2001 + autoHeight: false,
  2002 + autoHeightClass: 'owl-height'
  2003 + };
  2004 +
  2005 + /**
  2006 + * Updates the view.
  2007 + */
  2008 + AutoHeight.prototype.update = function() {
  2009 + this._core.$stage.parent()
  2010 + .height(this._core.$stage.children().eq(this._core.current()).height())
  2011 + .addClass(this._core.settings.autoHeightClass);
  2012 + };
  2013 +
  2014 + AutoHeight.prototype.destroy = function() {
  2015 + var handler, property;
  2016 +
  2017 + for (handler in this._handlers) {
  2018 + this._core.$element.off(handler, this._handlers[handler]);
  2019 + }
  2020 + for (property in Object.getOwnPropertyNames(this)) {
  2021 + typeof this[property] != 'function' && (this[property] = null);
  2022 + }
  2023 + };
  2024 +
  2025 + $.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight;
  2026 +
  2027 +})(window.Zepto || window.jQuery, window, document);
  2028 +
  2029 +/**
  2030 + * Video Plugin
  2031 + * @version 2.0.0
  2032 + * @author Bartosz Wojciechowski
  2033 + * @license The MIT License (MIT)
  2034 + */
  2035 +;(function($, window, document, undefined) {
  2036 +
  2037 + /**
  2038 + * Creates the video plugin.
  2039 + * @class The Video Plugin
  2040 + * @param {Owl} carousel - The Owl Carousel
  2041 + */
  2042 + var Video = function(carousel) {
  2043 + /**
  2044 + * Reference to the core.
  2045 + * @protected
  2046 + * @type {Owl}
  2047 + */
  2048 + this._core = carousel;
  2049 +
  2050 + /**
  2051 + * Cache all video URLs.
  2052 + * @protected
  2053 + * @type {Object}
  2054 + */
  2055 + this._videos = {};
  2056 +
  2057 + /**
  2058 + * Current playing item.
  2059 + * @protected
  2060 + * @type {jQuery}
  2061 + */
  2062 + this._playing = null;
  2063 +
  2064 + /**
  2065 + * Whether this is in fullscreen or not.
  2066 + * @protected
  2067 + * @type {Boolean}
  2068 + */
  2069 + this._fullscreen = false;
  2070 +
  2071 + /**
  2072 + * All event handlers.
  2073 + * @protected
  2074 + * @type {Object}
  2075 + */
  2076 + this._handlers = {
  2077 + 'resize.owl.carousel': $.proxy(function(e) {
  2078 + if (this._core.settings.video && !this.isInFullScreen()) {
  2079 + e.preventDefault();
  2080 + }
  2081 + }, this),
  2082 + 'refresh.owl.carousel changed.owl.carousel': $.proxy(function(e) {
  2083 + if (this._playing) {
  2084 + this.stop();
  2085 + }
  2086 + }, this),
  2087 + 'prepared.owl.carousel': $.proxy(function(e) {
  2088 + var $element = $(e.content).find('.owl-video');
  2089 + if ($element.length) {
  2090 + $element.css('display', 'none');
  2091 + this.fetch($element, $(e.content));
  2092 + }
  2093 + }, this)
  2094 + };
  2095 +
  2096 + // set default options
  2097 + this._core.options = $.extend({}, Video.Defaults, this._core.options);
  2098 +
  2099 + // register event handlers
  2100 + this._core.$element.on(this._handlers);
  2101 +
  2102 + this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) {
  2103 + this.play(e);
  2104 + }, this));
  2105 + };
  2106 +
  2107 + /**
  2108 + * Default options.
  2109 + * @public
  2110 + */
  2111 + Video.Defaults = {
  2112 + video: false,
  2113 + videoHeight: false,
  2114 + videoWidth: false
  2115 + };
  2116 +
  2117 + /**
  2118 + * Gets the video ID and the type (YouTube/Vimeo only).
  2119 + * @protected
  2120 + * @param {jQuery} target - The target containing the video data.
  2121 + * @param {jQuery} item - The item containing the video.
  2122 + */
  2123 + Video.prototype.fetch = function(target, item) {
  2124 +
  2125 + var type = target.attr('data-vimeo-id') ? 'vimeo' : 'youtube',
  2126 + id = target.attr('data-vimeo-id') || target.attr('data-youtube-id'),
  2127 + width = target.attr('data-width') || this._core.settings.videoWidth,
  2128 + height = target.attr('data-height') || this._core.settings.videoHeight,
  2129 + url = target.attr('href');
  2130 +
  2131 + if (url) {
  2132 + id = url.match(/(http:|https:|)\/\/(player.|www.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/);
  2133 +
  2134 + if (id[3].indexOf('youtu') > -1) {
  2135 + type = 'youtube';
  2136 + } else if (id[3].indexOf('vimeo') > -1) {
  2137 + type = 'vimeo';
  2138 + } else {
  2139 + throw new Error('Video URL not supported.');
  2140 + }
  2141 + id = id[6];
  2142 + } else {
  2143 + throw new Error('Missing video URL.');
  2144 + }
  2145 +
  2146 + this._videos[url] = {
  2147 + type: type,
  2148 + id: id,
  2149 + width: width,
  2150 + height: height
  2151 + };
  2152 +
  2153 + item.attr('data-video', url);
  2154 +
  2155 + this.thumbnail(target, this._videos[url]);
  2156 + };
  2157 +
  2158 + /**
  2159 + * Creates video thumbnail.
  2160 + * @protected
  2161 + * @param {jQuery} target - The target containing the video data.
  2162 + * @param {Object} info - The video info object.
  2163 + * @see `fetch`
  2164 + */
  2165 + Video.prototype.thumbnail = function(target, video) {
  2166 +
  2167 + var tnLink,
  2168 + icon,
  2169 + path,
  2170 + dimensions = video.width && video.height ? 'style="width:' + video.width + 'px;height:' + video.height + 'px;"' : '',
  2171 + customTn = target.find('img'),
  2172 + srcType = 'src',
  2173 + lazyClass = '',
  2174 + settings = this._core.settings,
  2175 + create = function(path) {
  2176 + icon = '<div class="owl-video-play-icon"></div>';
  2177 +
  2178 + if (settings.lazyLoad) {
  2179 + tnLink = '<div class="owl-video-tn ' + lazyClass + '" ' + srcType + '="' + path + '"></div>';
  2180 + } else {
  2181 + tnLink = '<div class="owl-video-tn" style="opacity:1;background-image:url(' + path + ')"></div>';
  2182 + }
  2183 + target.after(tnLink);
  2184 + target.after(icon);
  2185 + };
  2186 +
  2187 + // wrap video content into owl-video-wrapper div
  2188 + target.wrap('<div class="owl-video-wrapper"' + dimensions + '></div>');
  2189 +
  2190 + if (this._core.settings.lazyLoad) {
  2191 + srcType = 'data-src';
  2192 + lazyClass = 'owl-lazy';
  2193 + }
  2194 +
  2195 + // custom thumbnail
  2196 + if (customTn.length) {
  2197 + create(customTn.attr(srcType));
  2198 + customTn.remove();
  2199 + return false;
  2200 + }
  2201 +
  2202 + if (video.type === 'youtube') {
  2203 + path = "http://img.youtube.com/vi/" + video.id + "/hqdefault.jpg";
  2204 + create(path);
  2205 + } else if (video.type === 'vimeo') {
  2206 + $.ajax({
  2207 + type: 'GET',
  2208 + url: 'http://vimeo.com/api/v2/video/' + video.id + '.json',
  2209 + jsonp: 'callback',
  2210 + dataType: 'jsonp',
  2211 + success: function(data) {
  2212 + path = data[0].thumbnail_large;
  2213 + create(path);
  2214 + }
  2215 + });
  2216 + }
  2217 + };
  2218 +
  2219 + /**
  2220 + * Stops the current video.
  2221 + * @public
  2222 + */
  2223 + Video.prototype.stop = function() {
  2224 + this._core.trigger('stop', null, 'video');
  2225 + this._playing.find('.owl-video-frame').remove();
  2226 + this._playing.removeClass('owl-video-playing');
  2227 + this._playing = null;
  2228 + };
  2229 +
  2230 + /**
  2231 + * Starts the current video.
  2232 + * @public
  2233 + * @param {Event} ev - The event arguments.
  2234 + */
  2235 + Video.prototype.play = function(ev) {
  2236 + this._core.trigger('play', null, 'video');
  2237 +
  2238 + if (this._playing) {
  2239 + this.stop();
  2240 + }
  2241 +
  2242 + var target = $(ev.target || ev.srcElement),
  2243 + item = target.closest('.' + this._core.settings.itemClass),
  2244 + video = this._videos[item.attr('data-video')],
  2245 + width = video.width || '100%',
  2246 + height = video.height || this._core.$stage.height(),
  2247 + html, wrap;
  2248 +
  2249 + if (video.type === 'youtube') {
  2250 + html = '<iframe width="' + width + '" height="' + height + '" src="http://www.youtube.com/embed/'
  2251 + + video.id + '?autoplay=1&v=' + video.id + '" frameborder="0" allowfullscreen></iframe>';
  2252 + } else if (video.type === 'vimeo') {
  2253 + html = '<iframe src="http://player.vimeo.com/video/' + video.id + '?autoplay=1" width="' + width
  2254 + + '" height="' + height
  2255 + + '" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>';
  2256 + }
  2257 +
  2258 + item.addClass('owl-video-playing');
  2259 + this._playing = item;
  2260 +
  2261 + wrap = $('<div style="height:' + height + 'px; width:' + width + 'px" class="owl-video-frame">'
  2262 + + html + '</div>');
  2263 + target.after(wrap);
  2264 + };
  2265 +
  2266 + /**
  2267 + * Checks whether an video is currently in full screen mode or not.
  2268 + * @todo Bad style because looks like a readonly method but changes members.
  2269 + * @protected
  2270 + * @returns {Boolean}
  2271 + */
  2272 + Video.prototype.isInFullScreen = function() {
  2273 +
  2274 + // if Vimeo Fullscreen mode
  2275 + var element = document.fullscreenElement || document.mozFullScreenElement
  2276 + || document.webkitFullscreenElement;
  2277 +
  2278 + if (element && $(element).parent().hasClass('owl-video-frame')) {
  2279 + this._core.speed(0);
  2280 + this._fullscreen = true;
  2281 + }
  2282 +
  2283 + if (element && this._fullscreen && this._playing) {
  2284 + return false;
  2285 + }
  2286 +
  2287 + // comming back from fullscreen
  2288 + if (this._fullscreen) {
  2289 + this._fullscreen = false;
  2290 + return false;
  2291 + }
  2292 +
  2293 + // check full screen mode and window orientation
  2294 + if (this._playing) {
  2295 + if (this._core.state.orientation !== window.orientation) {
  2296 + this._core.state.orientation = window.orientation;
  2297 + return false;
  2298 + }
  2299 + }
  2300 +
  2301 + return true;
  2302 + };
  2303 +
  2304 + /**
  2305 + * Destroys the plugin.
  2306 + */
  2307 + Video.prototype.destroy = function() {
  2308 + var handler, property;
  2309 +
  2310 + this._core.$element.off('click.owl.video');
  2311 +
  2312 + for (handler in this._handlers) {
  2313 + this._core.$element.off(handler, this._handlers[handler]);
  2314 + }
  2315 + for (property in Object.getOwnPropertyNames(this)) {
  2316 + typeof this[property] != 'function' && (this[property] = null);
  2317 + }
  2318 + };
  2319 +
  2320 + $.fn.owlCarousel.Constructor.Plugins.Video = Video;
  2321 +
  2322 +})(window.Zepto || window.jQuery, window, document);
  2323 +
  2324 +/**
  2325 + * Animate Plugin
  2326 + * @version 2.0.0
  2327 + * @author Bartosz Wojciechowski
  2328 + * @license The MIT License (MIT)
  2329 + */
  2330 +;(function($, window, document, undefined) {
  2331 +
  2332 + /**
  2333 + * Creates the animate plugin.
  2334 + * @class The Navigation Plugin
  2335 + * @param {Owl} scope - The Owl Carousel
  2336 + */
  2337 + var Animate = function(scope) {
  2338 + this.core = scope;
  2339 + this.core.options = $.extend({}, Animate.Defaults, this.core.options);
  2340 + this.swapping = true;
  2341 + this.previous = undefined;
  2342 + this.next = undefined;
  2343 +
  2344 + this.handlers = {
  2345 + 'change.owl.carousel': $.proxy(function(e) {
  2346 + if (e.property.name == 'position') {
  2347 + this.previous = this.core.current();
  2348 + this.next = e.property.value;
  2349 + }
  2350 + }, this),
  2351 + 'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) {
  2352 + this.swapping = e.type == 'translated';
  2353 + }, this),
  2354 + 'translate.owl.carousel': $.proxy(function(e) {
  2355 + if (this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) {
  2356 + this.swap();
  2357 + }
  2358 + }, this)
  2359 + };
  2360 +
  2361 + this.core.$element.on(this.handlers);
  2362 + };
  2363 +
  2364 + /**
  2365 + * Default options.
  2366 + * @public
  2367 + */
  2368 + Animate.Defaults = {
  2369 + animateOut: false,
  2370 + animateIn: false
  2371 + };
  2372 +
  2373 + /**
  2374 + * Toggles the animation classes whenever an translations starts.
  2375 + * @protected
  2376 + * @returns {Boolean|undefined}
  2377 + */
  2378 + Animate.prototype.swap = function() {
  2379 +
  2380 + if (this.core.settings.items !== 1 || !this.core.support3d) {
  2381 + return;
  2382 + }
  2383 +
  2384 + this.core.speed(0);
  2385 +
  2386 + var left,
  2387 + clear = $.proxy(this.clear, this),
  2388 + previous = this.core.$stage.children().eq(this.previous),
  2389 + next = this.core.$stage.children().eq(this.next),
  2390 + incoming = this.core.settings.animateIn,
  2391 + outgoing = this.core.settings.animateOut;
  2392 +
  2393 + if (this.core.current() === this.previous) {
  2394 + return;
  2395 + }
  2396 +
  2397 + if (outgoing) {
  2398 + left = this.core.coordinates(this.previous) - this.core.coordinates(this.next);
  2399 + previous.css( { 'left': left + 'px' } )
  2400 + .addClass('animated owl-animated-out')
  2401 + .addClass(outgoing)
  2402 + .one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', clear);
  2403 + }
  2404 +
  2405 + if (incoming) {
  2406 + next.addClass('animated owl-animated-in')
  2407 + .addClass(incoming)
  2408 + .one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', clear);
  2409 + }
  2410 + };
  2411 +
  2412 + Animate.prototype.clear = function(e) {
  2413 + $(e.target).css( { 'left': '' } )
  2414 + .removeClass('animated owl-animated-out owl-animated-in')
  2415 + .removeClass(this.core.settings.animateIn)
  2416 + .removeClass(this.core.settings.animateOut);
  2417 + this.core.transitionEnd();
  2418 + }
  2419 +
  2420 + /**
  2421 + * Destroys the plugin.
  2422 + * @public
  2423 + */
  2424 + Animate.prototype.destroy = function() {
  2425 + var handler, property;
  2426 +
  2427 + for (handler in this.handlers) {
  2428 + this.core.$element.off(handler, this.handlers[handler]);
  2429 + }
  2430 + for (property in Object.getOwnPropertyNames(this)) {
  2431 + typeof this[property] != 'function' && (this[property] = null);
  2432 + }
  2433 + };
  2434 +
  2435 + $.fn.owlCarousel.Constructor.Plugins.Animate = Animate;
  2436 +
  2437 +})(window.Zepto || window.jQuery, window, document);
  2438 +
  2439 +/**
  2440 + * Autoplay Plugin
  2441 + * @version 2.0.0
  2442 + * @author Bartosz Wojciechowski
  2443 + * @license The MIT License (MIT)
  2444 + */
  2445 +;(function($, window, document, undefined) {
  2446 +
  2447 + /**
  2448 + * Creates the autoplay plugin.
  2449 + * @class The Autoplay Plugin
  2450 + * @param {Owl} scope - The Owl Carousel
  2451 + */
  2452 + var Autoplay = function(scope) {
  2453 + this.core = scope;
  2454 + this.core.options = $.extend({}, Autoplay.Defaults, this.core.options);
  2455 +
  2456 + this.handlers = {
  2457 + 'translated.owl.carousel refreshed.owl.carousel': $.proxy(function() {
  2458 + this.autoplay();
  2459 + }, this),
  2460 + 'play.owl.autoplay': $.proxy(function(e, t, s) {
  2461 + this.play(t, s);
  2462 + }, this),
  2463 + 'stop.owl.autoplay': $.proxy(function() {
  2464 + this.stop();
  2465 + }, this),
  2466 + 'mouseover.owl.autoplay': $.proxy(function() {
  2467 + if (this.core.settings.autoplayHoverPause) {
  2468 + this.pause();
  2469 + }
  2470 + }, this),
  2471 + 'mouseleave.owl.autoplay': $.proxy(function() {
  2472 + if (this.core.settings.autoplayHoverPause) {
  2473 + this.autoplay();
  2474 + }
  2475 + }, this)
  2476 + };
  2477 +
  2478 + this.core.$element.on(this.handlers);
  2479 + };
  2480 +
  2481 + /**
  2482 + * Default options.
  2483 + * @public
  2484 + */
  2485 + Autoplay.Defaults = {
  2486 + autoplay: false,
  2487 + autoplayTimeout: 5000,
  2488 + autoplayHoverPause: false,
  2489 + autoplaySpeed: false
  2490 + };
  2491 +
  2492 + /**
  2493 + * @protected
  2494 + * @todo Must be documented.
  2495 + */
  2496 + Autoplay.prototype.autoplay = function() {
  2497 + if (this.core.settings.autoplay && !this.core.state.videoPlay) {
  2498 + window.clearInterval(this.interval);
  2499 +
  2500 + this.interval = window.setInterval($.proxy(function() {
  2501 + this.play();
  2502 + }, this), this.core.settings.autoplayTimeout);
  2503 + } else {
  2504 + window.clearInterval(this.interval);
  2505 + }
  2506 + };
  2507 +
  2508 + /**
  2509 + * Starts the autoplay.
  2510 + * @public
  2511 + * @param {Number} [timeout] - ...
  2512 + * @param {Number} [speed] - ...
  2513 + * @returns {Boolean|undefined} - ...
  2514 + * @todo Must be documented.
  2515 + */
  2516 + Autoplay.prototype.play = function(timeout, speed) {
  2517 + // if tab is inactive - doesnt work in <IE10
  2518 + if (document.hidden === true) {
  2519 + return;
  2520 + }
  2521 +
  2522 + if (this.core.state.isTouch || this.core.state.isScrolling
  2523 + || this.core.state.isSwiping || this.core.state.inMotion) {
  2524 + return;
  2525 + }
  2526 +
  2527 + if (this.core.settings.autoplay === false) {
  2528 + window.clearInterval(this.interval);
  2529 + return;
  2530 + }
  2531 +
  2532 + this.core.next(this.core.settings.autoplaySpeed);
  2533 + };
  2534 +
  2535 + /**
  2536 + * Stops the autoplay.
  2537 + * @public
  2538 + */
  2539 + Autoplay.prototype.stop = function() {
  2540 + window.clearInterval(this.interval);
  2541 + };
  2542 +
  2543 + /**
  2544 + * Pauses the autoplay.
  2545 + * @public
  2546 + */
  2547 + Autoplay.prototype.pause = function() {
  2548 + window.clearInterval(this.interval);
  2549 + };
  2550 +
  2551 + /**
  2552 + * Destroys the plugin.
  2553 + */
  2554 + Autoplay.prototype.destroy = function() {
  2555 + var handler, property;
  2556 +
  2557 + window.clearInterval(this.interval);
  2558 +
  2559 + for (handler in this.handlers) {
  2560 + this.core.$element.off(handler, this.handlers[handler]);
  2561 + }
  2562 + for (property in Object.getOwnPropertyNames(this)) {
  2563 + typeof this[property] != 'function' && (this[property] = null);
  2564 + }
  2565 + };
  2566 +
  2567 + $.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay;
  2568 +
  2569 +})(window.Zepto || window.jQuery, window, document);
  2570 +
  2571 +/**
  2572 + * Navigation Plugin
  2573 + * @version 2.0.0
  2574 + * @author Artus Kolanowski
  2575 + * @license The MIT License (MIT)
  2576 + */
  2577 +;(function($, window, document, undefined) {
  2578 + 'use strict';
  2579 +
  2580 + /**
  2581 + * Creates the navigation plugin.
  2582 + * @class The Navigation Plugin
  2583 + * @param {Owl} carousel - The Owl Carousel.
  2584 + */
  2585 + var Navigation = function(carousel) {
  2586 + /**
  2587 + * Reference to the core.
  2588 + * @protected
  2589 + * @type {Owl}
  2590 + */
  2591 + this._core = carousel;
  2592 +
  2593 + /**
  2594 + * Indicates whether the plugin is initialized or not.
  2595 + * @protected
  2596 + * @type {Boolean}
  2597 + */
  2598 + this._initialized = false;
  2599 +
  2600 + /**
  2601 + * The current paging indexes.
  2602 + * @protected
  2603 + * @type {Array}
  2604 + */
  2605 + this._pages = [];
  2606 +
  2607 + /**
  2608 + * All DOM elements of the user interface.
  2609 + * @protected
  2610 + * @type {Object}
  2611 + */
  2612 + this._controls = {};
  2613 +
  2614 + /**
  2615 + * Markup for an indicator.
  2616 + * @protected
  2617 + * @type {Array.<String>}
  2618 + */
  2619 + this._templates = [];
  2620 +
  2621 + /**
  2622 + * The carousel element.
  2623 + * @type {jQuery}
  2624 + */
  2625 + this.$element = this._core.$element;
  2626 +
  2627 + /**
  2628 + * Overridden methods of the carousel.
  2629 + * @protected
  2630 + * @type {Object}
  2631 + */
  2632 + this._overrides = {
  2633 + next: this._core.next,
  2634 + prev: this._core.prev,
  2635 + to: this._core.to
  2636 + };
  2637 +
  2638 + /**
  2639 + * All event handlers.
  2640 + * @protected
  2641 + * @type {Object}
  2642 + */
  2643 + this._handlers = {
  2644 + 'prepared.owl.carousel': $.proxy(function(e) {
  2645 + if (this._core.settings.dotsData) {
  2646 + this._templates.push($(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot'));
  2647 + }
  2648 + }, this),
  2649 + 'add.owl.carousel': $.proxy(function(e) {
  2650 + if (this._core.settings.dotsData) {
  2651 + this._templates.splice(e.position, 0, $(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot'));
  2652 + }
  2653 + }, this),
  2654 + 'remove.owl.carousel prepared.owl.carousel': $.proxy(function(e) {
  2655 + if (this._core.settings.dotsData) {
  2656 + this._templates.splice(e.position, 1);
  2657 + }
  2658 + }, this),
  2659 + 'change.owl.carousel': $.proxy(function(e) {
  2660 + if (e.property.name == 'position') {
  2661 + if (!this._core.state.revert && !this._core.settings.loop && this._core.settings.navRewind) {
  2662 + var current = this._core.current(),
  2663 + maximum = this._core.maximum(),
  2664 + minimum = this._core.minimum();
  2665 + e.data = e.property.value > maximum
  2666 + ? current >= maximum ? minimum : maximum
  2667 + : e.property.value < minimum ? maximum : e.property.value;
  2668 + }
  2669 + }
  2670 + }, this),
  2671 + 'changed.owl.carousel': $.proxy(function(e) {
  2672 + if (e.property.name == 'position') {
  2673 + this.draw();
  2674 + }
  2675 + }, this),
  2676 + 'refreshed.owl.carousel': $.proxy(function() {
  2677 + if (!this._initialized) {
  2678 + this.initialize();
  2679 + this._initialized = true;
  2680 + }
  2681 + this._core.trigger('refresh', null, 'navigation');
  2682 + this.update();
  2683 + this.draw();
  2684 + this._core.trigger('refreshed', null, 'navigation');
  2685 + }, this)
  2686 + };
  2687 +
  2688 + // set default options
  2689 + this._core.options = $.extend({}, Navigation.Defaults, this._core.options);
  2690 +
  2691 + // register event handlers
  2692 + this.$element.on(this._handlers);
  2693 + }
  2694 +
  2695 + /**
  2696 + * Default options.
  2697 + * @public
  2698 + * @todo Rename `slideBy` to `navBy`
  2699 + */
  2700 + Navigation.Defaults = {
  2701 + nav: false,
  2702 + navRewind: true,
  2703 + navText: [ 'prev', 'next' ],
  2704 + navSpeed: false,
  2705 + navElement: 'div',
  2706 + navContainer: false,
  2707 + navContainerClass: 'owl-nav',
  2708 + navClass: [ 'owl-prev', 'owl-next' ],
  2709 + slideBy: 1,
  2710 + dotClass: 'owl-dot',
  2711 + dotsClass: 'owl-dots',
  2712 + dots: true,
  2713 + dotsEach: false,
  2714 + dotData: false,
  2715 + dotsSpeed: false,
  2716 + dotsContainer: false,
  2717 + controlsClass: 'owl-controls'
  2718 + }
  2719 +
  2720 + /**
  2721 + * Initializes the layout of the plugin and extends the carousel.
  2722 + * @protected
  2723 + */
  2724 + Navigation.prototype.initialize = function() {
  2725 + var $container, override,
  2726 + options = this._core.settings;
  2727 +
  2728 + // create the indicator template
  2729 + if (!options.dotsData) {
  2730 + this._templates = [ $('<div>')
  2731 + .addClass(options.dotClass)
  2732 + .append($('<span>'))
  2733 + .prop('outerHTML') ];
  2734 + }
  2735 +
  2736 + // create controls container if needed
  2737 + if (!options.navContainer || !options.dotsContainer) {
  2738 + this._controls.$container = $('<div>')
  2739 + .addClass(options.controlsClass)
  2740 + .appendTo(this.$element);
  2741 + }
  2742 +
  2743 + // create DOM structure for absolute navigation
  2744 + this._controls.$indicators = options.dotsContainer ? $(options.dotsContainer)
  2745 + : $('<div>').hide().addClass(options.dotsClass).appendTo(this._controls.$container);
  2746 +
  2747 + this._controls.$indicators.on('click', 'div', $.proxy(function(e) {
  2748 + var index = $(e.target).parent().is(this._controls.$indicators)
  2749 + ? $(e.target).index() : $(e.target).parent().index();
  2750 +
  2751 + e.preventDefault();
  2752 +
  2753 + this.to(index, options.dotsSpeed);
  2754 + }, this));
  2755 +
  2756 + // create DOM structure for relative navigation
  2757 + $container = options.navContainer ? $(options.navContainer)
  2758 + : $('<div>').addClass(options.navContainerClass).prependTo(this._controls.$container);
  2759 +
  2760 + this._controls.$next = $('<' + options.navElement + '>');
  2761 + this._controls.$previous = this._controls.$next.clone();
  2762 +
  2763 + this._controls.$previous
  2764 + .addClass(options.navClass[0])
  2765 + .html(options.navText[0])
  2766 + .hide()
  2767 + .prependTo($container)
  2768 + .on('click', $.proxy(function(e) {
  2769 + this.prev(options.navSpeed);
  2770 + }, this));
  2771 + this._controls.$next
  2772 + .addClass(options.navClass[1])
  2773 + .html(options.navText[1])
  2774 + .hide()
  2775 + .appendTo($container)
  2776 + .on('click', $.proxy(function(e) {
  2777 + this.next(options.navSpeed);
  2778 + }, this));
  2779 +
  2780 + // override public methods of the carousel
  2781 + for (override in this._overrides) {
  2782 + this._core[override] = $.proxy(this[override], this);
  2783 + }
  2784 + }
  2785 +
  2786 + /**
  2787 + * Destroys the plugin.
  2788 + * @protected
  2789 + */
  2790 + Navigation.prototype.destroy = function() {
  2791 + var handler, control, property, override;
  2792 +
  2793 + for (handler in this._handlers) {
  2794 + this.$element.off(handler, this._handlers[handler]);
  2795 + }
  2796 + for (control in this._controls) {
  2797 + this._controls[control].remove();
  2798 + }
  2799 + for (override in this.overides) {
  2800 + this._core[override] = this._overrides[override];
  2801 + }
  2802 + for (property in Object.getOwnPropertyNames(this)) {
  2803 + typeof this[property] != 'function' && (this[property] = null);
  2804 + }
  2805 + }
  2806 +
  2807 + /**
  2808 + * Updates the internal state.
  2809 + * @protected
  2810 + */
  2811 + Navigation.prototype.update = function() {
  2812 + var i, j, k,
  2813 + options = this._core.settings,
  2814 + lower = this._core.clones().length / 2,
  2815 + upper = lower + this._core.items().length,
  2816 + size = options.center || options.autoWidth || options.dotData
  2817 + ? 1 : options.dotsEach || options.items;
  2818 +
  2819 + if (options.slideBy !== 'page') {
  2820 + options.slideBy = Math.min(options.slideBy, options.items);
  2821 + }
  2822 +
  2823 + if (options.dots || options.slideBy == 'page') {
  2824 + this._pages = [];
  2825 +
  2826 + for (i = lower, j = 0, k = 0; i < upper; i++) {
  2827 + if (j >= size || j === 0) {
  2828 + this._pages.push({
  2829 + start: i - lower,
  2830 + end: i - lower + size - 1
  2831 + });
  2832 + j = 0, ++k;
  2833 + }
  2834 + j += this._core.mergers(this._core.relative(i));
  2835 + }
  2836 + }
  2837 + }
  2838 +
  2839 + /**
  2840 + * Draws the user interface.
  2841 + * @todo The option `dotData` wont work.
  2842 + * @protected
  2843 + */
  2844 + Navigation.prototype.draw = function() {
  2845 + var difference, i, html = '',
  2846 + options = this._core.settings,
  2847 + $items = this._core.$stage.children(),
  2848 + index = this._core.relative(this._core.current());
  2849 +
  2850 + if (options.nav && !options.loop && !options.navRewind) {
  2851 + this._controls.$previous.toggleClass('disabled', index <= 0);
  2852 + this._controls.$next.toggleClass('disabled', index >= this._core.maximum());
  2853 + }
  2854 +
  2855 + this._controls.$previous.toggle(options.nav);
  2856 + this._controls.$next.toggle(options.nav);
  2857 +
  2858 + if (options.dots) {
  2859 + difference = this._pages.length - this._controls.$indicators.children().length;
  2860 +
  2861 + if (options.dotData && difference !== 0) {
  2862 + for (i = 0; i < this._controls.$indicators.children().length; i++) {
  2863 + html += this._templates[this._core.relative(i)];
  2864 + }
  2865 + this._controls.$indicators.html(html);
  2866 + } else if (difference > 0) {
  2867 + html = new Array(difference + 1).join(this._templates[0]);
  2868 + this._controls.$indicators.append(html);
  2869 + } else if (difference < 0) {
  2870 + this._controls.$indicators.children().slice(difference).remove();
  2871 + }
  2872 +
  2873 + this._controls.$indicators.find('.active').removeClass('active');
  2874 + this._controls.$indicators.children().eq($.inArray(this.current(), this._pages)).addClass('active');
  2875 + }
  2876 +
  2877 + this._controls.$indicators.toggle(options.dots);
  2878 + }
  2879 +
  2880 + /**
  2881 + * Extends event data.
  2882 + * @protected
  2883 + * @param {Event} event - The event object which gets thrown.
  2884 + */
  2885 + Navigation.prototype.onTrigger = function(event) {
  2886 + var settings = this._core.settings;
  2887 +
  2888 + event.page = {
  2889 + index: $.inArray(this.current(), this._pages),
  2890 + count: this._pages.length,
  2891 + size: settings && (settings.center || settings.autoWidth || settings.dotData
  2892 + ? 1 : settings.dotsEach || settings.items)
  2893 + };
  2894 + }
  2895 +
  2896 + /**
  2897 + * Gets the current page position of the carousel.
  2898 + * @protected
  2899 + * @returns {Number}
  2900 + */
  2901 + Navigation.prototype.current = function() {
  2902 + var index = this._core.relative(this._core.current());
  2903 + return $.grep(this._pages, function(o) {
  2904 + return o.start <= index && o.end >= index;
  2905 + }).pop();
  2906 + }
  2907 +
  2908 + /**
  2909 + * Gets the current succesor/predecessor position.
  2910 + * @protected
  2911 + * @returns {Number}
  2912 + */
  2913 + Navigation.prototype.getPosition = function(successor) {
  2914 + var position, length,
  2915 + options = this._core.settings;
  2916 +
  2917 + if (options.slideBy == 'page') {
  2918 + position = $.inArray(this.current(), this._pages);
  2919 + length = this._pages.length;
  2920 + successor ? ++position : --position;
  2921 + position = this._pages[((position % length) + length) % length].start;
  2922 + } else {
  2923 + position = this._core.relative(this._core.current());
  2924 + length = this._core.items().length;
  2925 + successor ? position += options.slideBy : position -= options.slideBy;
  2926 + }
  2927 + return position;
  2928 + }
  2929 +
  2930 + /**
  2931 + * Slides to the next item or page.
  2932 + * @public
  2933 + * @param {Number} [speed=false] - The time in milliseconds for the transition.
  2934 + */
  2935 + Navigation.prototype.next = function(speed) {
  2936 + $.proxy(this._overrides.to, this._core)(this.getPosition(true), speed);
  2937 + }
  2938 +
  2939 + /**
  2940 + * Slides to the previous item or page.
  2941 + * @public
  2942 + * @param {Number} [speed=false] - The time in milliseconds for the transition.
  2943 + */
  2944 + Navigation.prototype.prev = function(speed) {
  2945 + $.proxy(this._overrides.to, this._core)(this.getPosition(false), speed);
  2946 + }
  2947 +
  2948 + /**
  2949 + * Slides to the specified item or page.
  2950 + * @public
  2951 + * @param {Number} position - The position of the item or page.
  2952 + * @param {Number} [speed] - The time in milliseconds for the transition.
  2953 + * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not.
  2954 + */
  2955 + Navigation.prototype.to = function(position, speed, standard) {
  2956 + var length;
  2957 +
  2958 + if (!standard) {
  2959 + length = this._pages.length;
  2960 + $.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed);
  2961 + } else {
  2962 + $.proxy(this._overrides.to, this._core)(position, speed);
  2963 + }
  2964 + }
  2965 +
  2966 + $.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation;
  2967 +
  2968 +})(window.Zepto || window.jQuery, window, document);
  2969 +
  2970 +/**
  2971 + * Hash Plugin
  2972 + * @version 2.0.0
  2973 + * @author Artus Kolanowski
  2974 + * @license The MIT License (MIT)
  2975 + */
  2976 +;(function($, window, document, undefined) {
  2977 + 'use strict';
  2978 +
  2979 + /**
  2980 + * Creates the hash plugin.
  2981 + * @class The Hash Plugin
  2982 + * @param {Owl} carousel - The Owl Carousel
  2983 + */
  2984 + var Hash = function(carousel) {
  2985 + /**
  2986 + * Reference to the core.
  2987 + * @protected
  2988 + * @type {Owl}
  2989 + */
  2990 + this._core = carousel;
  2991 +
  2992 + /**
  2993 + * Hash table for the hashes.
  2994 + * @protected
  2995 + * @type {Object}
  2996 + */
  2997 + this._hashes = {};
  2998 +
  2999 + /**
  3000 + * The carousel element.
  3001 + * @type {jQuery}
  3002 + */
  3003 + this.$element = this._core.$element;
  3004 +
  3005 + /**
  3006 + * All event handlers.
  3007 + * @protected
  3008 + * @type {Object}
  3009 + */
  3010 + this._handlers = {
  3011 + 'initialized.owl.carousel': $.proxy(function() {
  3012 + if (this._core.settings.startPosition == 'URLHash') {
  3013 + $(window).trigger('hashchange.owl.navigation');
  3014 + }
  3015 + }, this),
  3016 + 'prepared.owl.carousel': $.proxy(function(e) {
  3017 + var hash = $(e.content).find('[data-hash]').andSelf('[data-hash]').attr('data-hash');
  3018 + this._hashes[hash] = e.content;
  3019 + }, this)
  3020 + };
  3021 +
  3022 + // set default options
  3023 + this._core.options = $.extend({}, Hash.Defaults, this._core.options);
  3024 +
  3025 + // register the event handlers
  3026 + this.$element.on(this._handlers);
  3027 +
  3028 + // register event listener for hash navigation
  3029 + $(window).on('hashchange.owl.navigation', $.proxy(function() {
  3030 + var hash = window.location.hash.substring(1),
  3031 + items = this._core.$stage.children(),
  3032 + position = this._hashes[hash] && items.index(this._hashes[hash]) || 0;
  3033 +
  3034 + if (!hash) {
  3035 + return false;
  3036 + }
  3037 +
  3038 + this._core.to(position, false, true);
  3039 + }, this));
  3040 + }
  3041 +
  3042 + /**
  3043 + * Default options.
  3044 + * @public
  3045 + */
  3046 + Hash.Defaults = {
  3047 + URLhashListener: false
  3048 + }
  3049 +
  3050 + /**
  3051 + * Destroys the plugin.
  3052 + * @public
  3053 + */
  3054 + Hash.prototype.destroy = function() {
  3055 + var handler, property;
  3056 +
  3057 + $(window).off('hashchange.owl.navigation');
  3058 +
  3059 + for (handler in this._handlers) {
  3060 + this._core.$element.off(handler, this._handlers[handler]);
  3061 + }
  3062 + for (property in Object.getOwnPropertyNames(this)) {
  3063 + typeof this[property] != 'function' && (this[property] = null);
  3064 + }
  3065 + }
  3066 +
  3067 + $.fn.owlCarousel.Constructor.Plugins.Hash = Hash;
  3068 +
  3069 +})(window.Zepto || window.jQuery, window, document);
... ...
frontend/web/js/owl.carousel.min.js 0 → 100644
  1 +!function(a,b,c,d){function e(b,c){this.settings=null,this.options=a.extend({},e.Defaults,c),this.$element=a(b),this.drag=a.extend({},m),this.state=a.extend({},n),this.e=a.extend({},o),this._plugins={},this._supress={},this._current=null,this._speed=null,this._coordinates=[],this._breakpoint=null,this._width=null,this._items=[],this._clones=[],this._mergers=[],this._invalidated={},this._pipe=[],a.each(e.Plugins,a.proxy(function(a,b){this._plugins[a[0].toLowerCase()+a.slice(1)]=new b(this)},this)),a.each(e.Pipe,a.proxy(function(b,c){this._pipe.push({filter:c.filter,run:a.proxy(c.run,this)})},this)),this.setup(),this.initialize()}function f(a){if(a.touches!==d)return{x:a.touches[0].pageX,y:a.touches[0].pageY};if(a.touches===d){if(a.pageX!==d)return{x:a.pageX,y:a.pageY};if(a.pageX===d)return{x:a.clientX,y:a.clientY}}}function g(a){var b,d,e=c.createElement("div"),f=a;for(b in f)if(d=f[b],"undefined"!=typeof e.style[d])return e=null,[d,b];return[!1]}function h(){return g(["transition","WebkitTransition","MozTransition","OTransition"])[1]}function i(){return g(["transform","WebkitTransform","MozTransform","OTransform","msTransform"])[0]}function j(){return g(["perspective","webkitPerspective","MozPerspective","OPerspective","MsPerspective"])[0]}function k(){return"ontouchstart"in b||!!navigator.msMaxTouchPoints}function l(){return b.navigator.msPointerEnabled}var m,n,o;m={start:0,startX:0,startY:0,current:0,currentX:0,currentY:0,offsetX:0,offsetY:0,distance:null,startTime:0,endTime:0,updatedX:0,targetEl:null},n={isTouch:!1,isScrolling:!1,isSwiping:!1,direction:!1,inMotion:!1},o={_onDragStart:null,_onDragMove:null,_onDragEnd:null,_transitionEnd:null,_resizer:null,_responsiveCall:null,_goToLoop:null,_checkVisibile:null},e.Defaults={items:3,loop:!1,center:!1,mouseDrag:!0,touchDrag:!0,pullDrag:!0,freeDrag:!1,margin:0,stagePadding:0,merge:!1,mergeFit:!0,autoWidth:!1,startPosition:0,rtl:!1,smartSpeed:250,fluidSpeed:!1,dragEndSpeed:!1,responsive:{},responsiveRefreshRate:200,responsiveBaseElement:b,responsiveClass:!1,fallbackEasing:"swing",info:!1,nestedItemSelector:!1,itemElement:"div",stageElement:"div",themeClass:"owl-theme",baseClass:"owl-carousel",itemClass:"owl-item",centerClass:"center",activeClass:"active"},e.Width={Default:"default",Inner:"inner",Outer:"outer"},e.Plugins={},e.Pipe=[{filter:["width","items","settings"],run:function(a){a.current=this._items&&this._items[this.relative(this._current)]}},{filter:["items","settings"],run:function(){var a=this._clones,b=this.$stage.children(".cloned");(b.length!==a.length||!this.settings.loop&&a.length>0)&&(this.$stage.children(".cloned").remove(),this._clones=[])}},{filter:["items","settings"],run:function(){var a,b,c=this._clones,d=this._items,e=this.settings.loop?c.length-Math.max(2*this.settings.items,4):0;for(a=0,b=Math.abs(e/2);b>a;a++)e>0?(this.$stage.children().eq(d.length+c.length-1).remove(),c.pop(),this.$stage.children().eq(0).remove(),c.pop()):(c.push(c.length/2),this.$stage.append(d[c[c.length-1]].clone().addClass("cloned")),c.push(d.length-1-(c.length-1)/2),this.$stage.prepend(d[c[c.length-1]].clone().addClass("cloned")))}},{filter:["width","items","settings"],run:function(){var a,b,c,d=this.settings.rtl?1:-1,e=(this.width()/this.settings.items).toFixed(3),f=0;for(this._coordinates=[],b=0,c=this._clones.length+this._items.length;c>b;b++)a=this._mergers[this.relative(b)],a=this.settings.mergeFit&&Math.min(a,this.settings.items)||a,f+=(this.settings.autoWidth?this._items[this.relative(b)].width()+this.settings.margin:e*a)*d,this._coordinates.push(f)}},{filter:["width","items","settings"],run:function(){var b,c,d=(this.width()/this.settings.items).toFixed(3),e={width:Math.abs(this._coordinates[this._coordinates.length-1])+2*this.settings.stagePadding,"padding-left":this.settings.stagePadding||"","padding-right":this.settings.stagePadding||""};if(this.$stage.css(e),e={width:this.settings.autoWidth?"auto":d-this.settings.margin},e[this.settings.rtl?"margin-left":"margin-right"]=this.settings.margin,!this.settings.autoWidth&&a.grep(this._mergers,function(a){return a>1}).length>0)for(b=0,c=this._coordinates.length;c>b;b++)e.width=Math.abs(this._coordinates[b])-Math.abs(this._coordinates[b-1]||0)-this.settings.margin,this.$stage.children().eq(b).css(e);else this.$stage.children().css(e)}},{filter:["width","items","settings"],run:function(a){a.current&&this.reset(this.$stage.children().index(a.current))}},{filter:["position"],run:function(){this.animate(this.coordinates(this._current))}},{filter:["width","position","items","settings"],run:function(){var a,b,c,d,e=this.settings.rtl?1:-1,f=2*this.settings.stagePadding,g=this.coordinates(this.current())+f,h=g+this.width()*e,i=[];for(c=0,d=this._coordinates.length;d>c;c++)a=this._coordinates[c-1]||0,b=Math.abs(this._coordinates[c])+f*e,(this.op(a,"<=",g)&&this.op(a,">",h)||this.op(b,"<",g)&&this.op(b,">",h))&&i.push(c);this.$stage.children("."+this.settings.activeClass).removeClass(this.settings.activeClass),this.$stage.children(":eq("+i.join("), :eq(")+")").addClass(this.settings.activeClass),this.settings.center&&(this.$stage.children("."+this.settings.centerClass).removeClass(this.settings.centerClass),this.$stage.children().eq(this.current()).addClass(this.settings.centerClass))}}],e.prototype.initialize=function(){if(this.trigger("initialize"),this.$element.addClass(this.settings.baseClass).addClass(this.settings.themeClass).toggleClass("owl-rtl",this.settings.rtl),this.browserSupport(),this.settings.autoWidth&&this.state.imagesLoaded!==!0){var b,c,e;if(b=this.$element.find("img"),c=this.settings.nestedItemSelector?"."+this.settings.nestedItemSelector:d,e=this.$element.children(c).width(),b.length&&0>=e)return this.preloadAutoWidthImages(b),!1}this.$element.addClass("owl-loading"),this.$stage=a("<"+this.settings.stageElement+' class="owl-stage"/>').wrap('<div class="owl-stage-outer">'),this.$element.append(this.$stage.parent()),this.replace(this.$element.children().not(this.$stage.parent())),this._width=this.$element.width(),this.refresh(),this.$element.removeClass("owl-loading").addClass("owl-loaded"),this.eventsCall(),this.internalEvents(),this.addTriggerableEvents(),this.trigger("initialized")},e.prototype.setup=function(){var b=this.viewport(),c=this.options.responsive,d=-1,e=null;c?(a.each(c,function(a){b>=a&&a>d&&(d=Number(a))}),e=a.extend({},this.options,c[d]),delete e.responsive,e.responsiveClass&&this.$element.attr("class",function(a,b){return b.replace(/\b owl-responsive-\S+/g,"")}).addClass("owl-responsive-"+d)):e=a.extend({},this.options),(null===this.settings||this._breakpoint!==d)&&(this.trigger("change",{property:{name:"settings",value:e}}),this._breakpoint=d,this.settings=e,this.invalidate("settings"),this.trigger("changed",{property:{name:"settings",value:this.settings}}))},e.prototype.optionsLogic=function(){this.$element.toggleClass("owl-center",this.settings.center),this.settings.loop&&this._items.length<this.settings.items&&(this.settings.loop=!1),this.settings.autoWidth&&(this.settings.stagePadding=!1,this.settings.merge=!1)},e.prototype.prepare=function(b){var c=this.trigger("prepare",{content:b});return c.data||(c.data=a("<"+this.settings.itemElement+"/>").addClass(this.settings.itemClass).append(b)),this.trigger("prepared",{content:c.data}),c.data},e.prototype.update=function(){for(var b=0,c=this._pipe.length,d=a.proxy(function(a){return this[a]},this._invalidated),e={};c>b;)(this._invalidated.all||a.grep(this._pipe[b].filter,d).length>0)&&this._pipe[b].run(e),b++;this._invalidated={}},e.prototype.width=function(a){switch(a=a||e.Width.Default){case e.Width.Inner:case e.Width.Outer:return this._width;default:return this._width-2*this.settings.stagePadding+this.settings.margin}},e.prototype.refresh=function(){if(0===this._items.length)return!1;(new Date).getTime();this.trigger("refresh"),this.setup(),this.optionsLogic(),this.$stage.addClass("owl-refresh"),this.update(),this.$stage.removeClass("owl-refresh"),this.state.orientation=b.orientation,this.watchVisibility(),this.trigger("refreshed")},e.prototype.eventsCall=function(){this.e._onDragStart=a.proxy(function(a){this.onDragStart(a)},this),this.e._onDragMove=a.proxy(function(a){this.onDragMove(a)},this),this.e._onDragEnd=a.proxy(function(a){this.onDragEnd(a)},this),this.e._onResize=a.proxy(function(a){this.onResize(a)},this),this.e._transitionEnd=a.proxy(function(a){this.transitionEnd(a)},this),this.e._preventClick=a.proxy(function(a){this.preventClick(a)},this)},e.prototype.onThrottledResize=function(){b.clearTimeout(this.resizeTimer),this.resizeTimer=b.setTimeout(this.e._onResize,this.settings.responsiveRefreshRate)},e.prototype.onResize=function(){return this._items.length?this._width===this.$element.width()?!1:this.trigger("resize").isDefaultPrevented()?!1:(this._width=this.$element.width(),this.invalidate("width"),this.refresh(),void this.trigger("resized")):!1},e.prototype.eventsRouter=function(a){var b=a.type;"mousedown"===b||"touchstart"===b?this.onDragStart(a):"mousemove"===b||"touchmove"===b?this.onDragMove(a):"mouseup"===b||"touchend"===b?this.onDragEnd(a):"touchcancel"===b&&this.onDragEnd(a)},e.prototype.internalEvents=function(){var c=(k(),l());this.settings.mouseDrag?(this.$stage.on("mousedown",a.proxy(function(a){this.eventsRouter(a)},this)),this.$stage.on("dragstart",function(){return!1}),this.$stage.get(0).onselectstart=function(){return!1}):this.$element.addClass("owl-text-select-on"),this.settings.touchDrag&&!c&&this.$stage.on("touchstart touchcancel",a.proxy(function(a){this.eventsRouter(a)},this)),this.transitionEndVendor&&this.on(this.$stage.get(0),this.transitionEndVendor,this.e._transitionEnd,!1),this.settings.responsive!==!1&&this.on(b,"resize",a.proxy(this.onThrottledResize,this))},e.prototype.onDragStart=function(d){var e,g,h,i;if(e=d.originalEvent||d||b.event,3===e.which||this.state.isTouch)return!1;if("mousedown"===e.type&&this.$stage.addClass("owl-grab"),this.trigger("drag"),this.drag.startTime=(new Date).getTime(),this.speed(0),this.state.isTouch=!0,this.state.isScrolling=!1,this.state.isSwiping=!1,this.drag.distance=0,g=f(e).x,h=f(e).y,this.drag.offsetX=this.$stage.position().left,this.drag.offsetY=this.$stage.position().top,this.settings.rtl&&(this.drag.offsetX=this.$stage.position().left+this.$stage.width()-this.width()+this.settings.margin),this.state.inMotion&&this.support3d)i=this.getTransformProperty(),this.drag.offsetX=i,this.animate(i),this.state.inMotion=!0;else if(this.state.inMotion&&!this.support3d)return this.state.inMotion=!1,!1;this.drag.startX=g-this.drag.offsetX,this.drag.startY=h-this.drag.offsetY,this.drag.start=g-this.drag.startX,this.drag.targetEl=e.target||e.srcElement,this.drag.updatedX=this.drag.start,("IMG"===this.drag.targetEl.tagName||"A"===this.drag.targetEl.tagName)&&(this.drag.targetEl.draggable=!1),a(c).on("mousemove.owl.dragEvents mouseup.owl.dragEvents touchmove.owl.dragEvents touchend.owl.dragEvents",a.proxy(function(a){this.eventsRouter(a)},this))},e.prototype.onDragMove=function(a){var c,e,g,h,i,j;this.state.isTouch&&(this.state.isScrolling||(c=a.originalEvent||a||b.event,e=f(c).x,g=f(c).y,this.drag.currentX=e-this.drag.startX,this.drag.currentY=g-this.drag.startY,this.drag.distance=this.drag.currentX-this.drag.offsetX,this.drag.distance<0?this.state.direction=this.settings.rtl?"right":"left":this.drag.distance>0&&(this.state.direction=this.settings.rtl?"left":"right"),this.settings.loop?this.op(this.drag.currentX,">",this.coordinates(this.minimum()))&&"right"===this.state.direction?this.drag.currentX-=(this.settings.center&&this.coordinates(0))-this.coordinates(this._items.length):this.op(this.drag.currentX,"<",this.coordinates(this.maximum()))&&"left"===this.state.direction&&(this.drag.currentX+=(this.settings.center&&this.coordinates(0))-this.coordinates(this._items.length)):(h=this.coordinates(this.settings.rtl?this.maximum():this.minimum()),i=this.coordinates(this.settings.rtl?this.minimum():this.maximum()),j=this.settings.pullDrag?this.drag.distance/5:0,this.drag.currentX=Math.max(Math.min(this.drag.currentX,h+j),i+j)),(this.drag.distance>8||this.drag.distance<-8)&&(c.preventDefault!==d?c.preventDefault():c.returnValue=!1,this.state.isSwiping=!0),this.drag.updatedX=this.drag.currentX,(this.drag.currentY>16||this.drag.currentY<-16)&&this.state.isSwiping===!1&&(this.state.isScrolling=!0,this.drag.updatedX=this.drag.start),this.animate(this.drag.updatedX)))},e.prototype.onDragEnd=function(b){var d,e,f;if(this.state.isTouch){if("mouseup"===b.type&&this.$stage.removeClass("owl-grab"),this.trigger("dragged"),this.drag.targetEl.removeAttribute("draggable"),this.state.isTouch=!1,this.state.isScrolling=!1,this.state.isSwiping=!1,0===this.drag.distance&&this.state.inMotion!==!0)return this.state.inMotion=!1,!1;this.drag.endTime=(new Date).getTime(),d=this.drag.endTime-this.drag.startTime,e=Math.abs(this.drag.distance),(e>3||d>300)&&this.removeClick(this.drag.targetEl),f=this.closest(this.drag.updatedX),this.speed(this.settings.dragEndSpeed||this.settings.smartSpeed),this.current(f),this.invalidate("position"),this.update(),this.settings.pullDrag||this.drag.updatedX!==this.coordinates(f)||this.transitionEnd(),this.drag.distance=0,a(c).off(".owl.dragEvents")}},e.prototype.removeClick=function(c){this.drag.targetEl=c,a(c).on("click.preventClick",this.e._preventClick),b.setTimeout(function(){a(c).off("click.preventClick")},300)},e.prototype.preventClick=function(b){b.preventDefault?b.preventDefault():b.returnValue=!1,b.stopPropagation&&b.stopPropagation(),a(b.target).off("click.preventClick")},e.prototype.getTransformProperty=function(){var a,c;return a=b.getComputedStyle(this.$stage.get(0),null).getPropertyValue(this.vendorName+"transform"),a=a.replace(/matrix(3d)?\(|\)/g,"").split(","),c=16===a.length,c!==!0?a[4]:a[12]},e.prototype.closest=function(b){var c=-1,d=30,e=this.width(),f=this.coordinates();return this.settings.freeDrag||a.each(f,a.proxy(function(a,g){return b>g-d&&g+d>b?c=a:this.op(b,"<",g)&&this.op(b,">",f[a+1]||g-e)&&(c="left"===this.state.direction?a+1:a),-1===c},this)),this.settings.loop||(this.op(b,">",f[this.minimum()])?c=b=this.minimum():this.op(b,"<",f[this.maximum()])&&(c=b=this.maximum())),c},e.prototype.animate=function(b){this.trigger("translate"),this.state.inMotion=this.speed()>0,this.support3d?this.$stage.css({transform:"translate3d("+b+"px,0px, 0px)",transition:this.speed()/1e3+"s"}):this.state.isTouch?this.$stage.css({left:b+"px"}):this.$stage.animate({left:b},this.speed()/1e3,this.settings.fallbackEasing,a.proxy(function(){this.state.inMotion&&this.transitionEnd()},this))},e.prototype.current=function(a){if(a===d)return this._current;if(0===this._items.length)return d;if(a=this.normalize(a),this._current!==a){var b=this.trigger("change",{property:{name:"position",value:a}});b.data!==d&&(a=this.normalize(b.data)),this._current=a,this.invalidate("position"),this.trigger("changed",{property:{name:"position",value:this._current}})}return this._current},e.prototype.invalidate=function(a){this._invalidated[a]=!0},e.prototype.reset=function(a){a=this.normalize(a),a!==d&&(this._speed=0,this._current=a,this.suppress(["translate","translated"]),this.animate(this.coordinates(a)),this.release(["translate","translated"]))},e.prototype.normalize=function(b,c){var e=c?this._items.length:this._items.length+this._clones.length;return!a.isNumeric(b)||1>e?d:b=this._clones.length?(b%e+e)%e:Math.max(this.minimum(c),Math.min(this.maximum(c),b))},e.prototype.relative=function(a){return a=this.normalize(a),a-=this._clones.length/2,this.normalize(a,!0)},e.prototype.maximum=function(a){var b,c,d,e=0,f=this.settings;if(a)return this._items.length-1;if(!f.loop&&f.center)b=this._items.length-1;else if(f.loop||f.center)if(f.loop||f.center)b=this._items.length+f.items;else{if(!f.autoWidth&&!f.merge)throw"Can not detect maximum absolute position.";for(revert=f.rtl?1:-1,c=this.$stage.width()-this.$element.width();(d=this.coordinates(e))&&!(d*revert>=c);)b=++e}else b=this._items.length-f.items;return b},e.prototype.minimum=function(a){return a?0:this._clones.length/2},e.prototype.items=function(a){return a===d?this._items.slice():(a=this.normalize(a,!0),this._items[a])},e.prototype.mergers=function(a){return a===d?this._mergers.slice():(a=this.normalize(a,!0),this._mergers[a])},e.prototype.clones=function(b){var c=this._clones.length/2,e=c+this._items.length,f=function(a){return a%2===0?e+a/2:c-(a+1)/2};return b===d?a.map(this._clones,function(a,b){return f(b)}):a.map(this._clones,function(a,c){return a===b?f(c):null})},e.prototype.speed=function(a){return a!==d&&(this._speed=a),this._speed},e.prototype.coordinates=function(b){var c=null;return b===d?a.map(this._coordinates,a.proxy(function(a,b){return this.coordinates(b)},this)):(this.settings.center?(c=this._coordinates[b],c+=(this.width()-c+(this._coordinates[b-1]||0))/2*(this.settings.rtl?-1:1)):c=this._coordinates[b-1]||0,c)},e.prototype.duration=function(a,b,c){return Math.min(Math.max(Math.abs(b-a),1),6)*Math.abs(c||this.settings.smartSpeed)},e.prototype.to=function(c,d){if(this.settings.loop){var e=c-this.relative(this.current()),f=this.current(),g=this.current(),h=this.current()+e,i=0>g-h?!0:!1,j=this._clones.length+this._items.length;h<this.settings.items&&i===!1?(f=g+this._items.length,this.reset(f)):h>=j-this.settings.items&&i===!0&&(f=g-this._items.length,this.reset(f)),b.clearTimeout(this.e._goToLoop),this.e._goToLoop=b.setTimeout(a.proxy(function(){this.speed(this.duration(this.current(),f+e,d)),this.current(f+e),this.update()},this),30)}else this.speed(this.duration(this.current(),c,d)),this.current(c),this.update()},e.prototype.next=function(a){a=a||!1,this.to(this.relative(this.current())+1,a)},e.prototype.prev=function(a){a=a||!1,this.to(this.relative(this.current())-1,a)},e.prototype.transitionEnd=function(a){return a!==d&&(a.stopPropagation(),(a.target||a.srcElement||a.originalTarget)!==this.$stage.get(0))?!1:(this.state.inMotion=!1,void this.trigger("translated"))},e.prototype.viewport=function(){var d;if(this.options.responsiveBaseElement!==b)d=a(this.options.responsiveBaseElement).width();else if(b.innerWidth)d=b.innerWidth;else{if(!c.documentElement||!c.documentElement.clientWidth)throw"Can not detect viewport width.";d=c.documentElement.clientWidth}return d},e.prototype.replace=function(b){this.$stage.empty(),this._items=[],b&&(b=b instanceof jQuery?b:a(b)),this.settings.nestedItemSelector&&(b=b.find("."+this.settings.nestedItemSelector)),b.filter(function(){return 1===this.nodeType}).each(a.proxy(function(a,b){b=this.prepare(b),this.$stage.append(b),this._items.push(b),this._mergers.push(1*b.find("[data-merge]").andSelf("[data-merge]").attr("data-merge")||1)},this)),this.reset(a.isNumeric(this.settings.startPosition)?this.settings.startPosition:0),this.invalidate("items")},e.prototype.add=function(a,b){b=b===d?this._items.length:this.normalize(b,!0),this.trigger("add",{content:a,position:b}),0===this._items.length||b===this._items.length?(this.$stage.append(a),this._items.push(a),this._mergers.push(1*a.find("[data-merge]").andSelf("[data-merge]").attr("data-merge")||1)):(this._items[b].before(a),this._items.splice(b,0,a),this._mergers.splice(b,0,1*a.find("[data-merge]").andSelf("[data-merge]").attr("data-merge")||1)),this.invalidate("items"),this.trigger("added",{content:a,position:b})},e.prototype.remove=function(a){a=this.normalize(a,!0),a!==d&&(this.trigger("remove",{content:this._items[a],position:a}),this._items[a].remove(),this._items.splice(a,1),this._mergers.splice(a,1),this.invalidate("items"),this.trigger("removed",{content:null,position:a}))},e.prototype.addTriggerableEvents=function(){var b=a.proxy(function(b,c){return a.proxy(function(a){a.relatedTarget!==this&&(this.suppress([c]),b.apply(this,[].slice.call(arguments,1)),this.release([c]))},this)},this);a.each({next:this.next,prev:this.prev,to:this.to,destroy:this.destroy,refresh:this.refresh,replace:this.replace,add:this.add,remove:this.remove},a.proxy(function(a,c){this.$element.on(a+".owl.carousel",b(c,a+".owl.carousel"))},this))},e.prototype.watchVisibility=function(){function c(a){return a.offsetWidth>0&&a.offsetHeight>0}function d(){c(this.$element.get(0))&&(this.$element.removeClass("owl-hidden"),this.refresh(),b.clearInterval(this.e._checkVisibile))}c(this.$element.get(0))||(this.$element.addClass("owl-hidden"),b.clearInterval(this.e._checkVisibile),this.e._checkVisibile=b.setInterval(a.proxy(d,this),500))},e.prototype.preloadAutoWidthImages=function(b){var c,d,e,f;c=0,d=this,b.each(function(g,h){e=a(h),f=new Image,f.onload=function(){c++,e.attr("src",f.src),e.css("opacity",1),c>=b.length&&(d.state.imagesLoaded=!0,d.initialize())},f.src=e.attr("src")||e.attr("data-src")||e.attr("data-src-retina")})},e.prototype.destroy=function(){this.$element.hasClass(this.settings.themeClass)&&this.$element.removeClass(this.settings.themeClass),this.settings.responsive!==!1&&a(b).off("resize.owl.carousel"),this.transitionEndVendor&&this.off(this.$stage.get(0),this.transitionEndVendor,this.e._transitionEnd);for(var d in this._plugins)this._plugins[d].destroy();(this.settings.mouseDrag||this.settings.touchDrag)&&(this.$stage.off("mousedown touchstart touchcancel"),a(c).off(".owl.dragEvents"),this.$stage.get(0).onselectstart=function(){},this.$stage.off("dragstart",function(){return!1})),this.$element.off(".owl"),this.$stage.children(".cloned").remove(),this.e=null,this.$element.removeData("owlCarousel"),this.$stage.children().contents().unwrap(),this.$stage.children().unwrap(),this.$stage.unwrap()},e.prototype.op=function(a,b,c){var d=this.settings.rtl;switch(b){case"<":return d?a>c:c>a;case">":return d?c>a:a>c;case">=":return d?c>=a:a>=c;case"<=":return d?a>=c:c>=a}},e.prototype.on=function(a,b,c,d){a.addEventListener?a.addEventListener(b,c,d):a.attachEvent&&a.attachEvent("on"+b,c)},e.prototype.off=function(a,b,c,d){a.removeEventListener?a.removeEventListener(b,c,d):a.detachEvent&&a.detachEvent("on"+b,c)},e.prototype.trigger=function(b,c,d){var e={item:{count:this._items.length,index:this.current()}},f=a.camelCase(a.grep(["on",b,d],function(a){return a}).join("-").toLowerCase()),g=a.Event([b,"owl",d||"carousel"].join(".").toLowerCase(),a.extend({relatedTarget:this},e,c));return this._supress[b]||(a.each(this._plugins,function(a,b){b.onTrigger&&b.onTrigger(g)}),this.$element.trigger(g),this.settings&&"function"==typeof this.settings[f]&&this.settings[f].apply(this,g)),g},e.prototype.suppress=function(b){a.each(b,a.proxy(function(a,b){this._supress[b]=!0},this))},e.prototype.release=function(b){a.each(b,a.proxy(function(a,b){delete this._supress[b]},this))},e.prototype.browserSupport=function(){if(this.support3d=j(),this.support3d){this.transformVendor=i();var a=["transitionend","webkitTransitionEnd","transitionend","oTransitionEnd"];this.transitionEndVendor=a[h()],this.vendorName=this.transformVendor.replace(/Transform/i,""),this.vendorName=""!==this.vendorName?"-"+this.vendorName.toLowerCase()+"-":""}this.state.orientation=b.orientation},a.fn.owlCarousel=function(b){return this.each(function(){a(this).data("owlCarousel")||a(this).data("owlCarousel",new e(this,b))})},a.fn.owlCarousel.Constructor=e}(window.Zepto||window.jQuery,window,document),function(a,b){var c=function(b){this._core=b,this._loaded=[],this._handlers={"initialized.owl.carousel change.owl.carousel":a.proxy(function(b){if(b.namespace&&this._core.settings&&this._core.settings.lazyLoad&&(b.property&&"position"==b.property.name||"initialized"==b.type))for(var c=this._core.settings,d=c.center&&Math.ceil(c.items/2)||c.items,e=c.center&&-1*d||0,f=(b.property&&b.property.value||this._core.current())+e,g=this._core.clones().length,h=a.proxy(function(a,b){this.load(b)},this);e++<d;)this.load(g/2+this._core.relative(f)),g&&a.each(this._core.clones(this._core.relative(f++)),h)},this)},this._core.options=a.extend({},c.Defaults,this._core.options),this._core.$element.on(this._handlers)};c.Defaults={lazyLoad:!1},c.prototype.load=function(c){var d=this._core.$stage.children().eq(c),e=d&&d.find(".owl-lazy");!e||a.inArray(d.get(0),this._loaded)>-1||(e.each(a.proxy(function(c,d){var e,f=a(d),g=b.devicePixelRatio>1&&f.attr("data-src-retina")||f.attr("data-src");this._core.trigger("load",{element:f,url:g},"lazy"),f.is("img")?f.one("load.owl.lazy",a.proxy(function(){f.css("opacity",1),this._core.trigger("loaded",{element:f,url:g},"lazy")},this)).attr("src",g):(e=new Image,e.onload=a.proxy(function(){f.css({"background-image":"url("+g+")",opacity:"1"}),this._core.trigger("loaded",{element:f,url:g},"lazy")},this),e.src=g)},this)),this._loaded.push(d.get(0)))},c.prototype.destroy=function(){var a,b;for(a in this.handlers)this._core.$element.off(a,this.handlers[a]);for(b in Object.getOwnPropertyNames(this))"function"!=typeof this[b]&&(this[b]=null)},a.fn.owlCarousel.Constructor.Plugins.Lazy=c}(window.Zepto||window.jQuery,window,document),function(a){var b=function(c){this._core=c,this._handlers={"initialized.owl.carousel":a.proxy(function(){this._core.settings.autoHeight&&this.update()},this),"changed.owl.carousel":a.proxy(function(a){this._core.settings.autoHeight&&"position"==a.property.name&&this.update()},this),"loaded.owl.lazy":a.proxy(function(a){this._core.settings.autoHeight&&a.element.closest("."+this._core.settings.itemClass)===this._core.$stage.children().eq(this._core.current())&&this.update()},this)},this._core.options=a.extend({},b.Defaults,this._core.options),this._core.$element.on(this._handlers)};b.Defaults={autoHeight:!1,autoHeightClass:"owl-height"},b.prototype.update=function(){this._core.$stage.parent().height(this._core.$stage.children().eq(this._core.current()).height()).addClass(this._core.settings.autoHeightClass)},b.prototype.destroy=function(){var a,b;for(a in this._handlers)this._core.$element.off(a,this._handlers[a]);for(b in Object.getOwnPropertyNames(this))"function"!=typeof this[b]&&(this[b]=null)},a.fn.owlCarousel.Constructor.Plugins.AutoHeight=b}(window.Zepto||window.jQuery,window,document),function(a,b,c){var d=function(b){this._core=b,this._videos={},this._playing=null,this._fullscreen=!1,this._handlers={"resize.owl.carousel":a.proxy(function(a){this._core.settings.video&&!this.isInFullScreen()&&a.preventDefault()},this),"refresh.owl.carousel changed.owl.carousel":a.proxy(function(){this._playing&&this.stop()},this),"prepared.owl.carousel":a.proxy(function(b){var c=a(b.content).find(".owl-video");c.length&&(c.css("display","none"),this.fetch(c,a(b.content)))},this)},this._core.options=a.extend({},d.Defaults,this._core.options),this._core.$element.on(this._handlers),this._core.$element.on("click.owl.video",".owl-video-play-icon",a.proxy(function(a){this.play(a)},this))};d.Defaults={video:!1,videoHeight:!1,videoWidth:!1},d.prototype.fetch=function(a,b){var c=a.attr("data-vimeo-id")?"vimeo":"youtube",d=a.attr("data-vimeo-id")||a.attr("data-youtube-id"),e=a.attr("data-width")||this._core.settings.videoWidth,f=a.attr("data-height")||this._core.settings.videoHeight,g=a.attr("href");if(!g)throw new Error("Missing video URL.");if(d=g.match(/(http:|https:|)\/\/(player.|www.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/),d[3].indexOf("youtu")>-1)c="youtube";else{if(!(d[3].indexOf("vimeo")>-1))throw new Error("Video URL not supported.");c="vimeo"}d=d[6],this._videos[g]={type:c,id:d,width:e,height:f},b.attr("data-video",g),this.thumbnail(a,this._videos[g])},d.prototype.thumbnail=function(b,c){var d,e,f,g=c.width&&c.height?'style="width:'+c.width+"px;height:"+c.height+'px;"':"",h=b.find("img"),i="src",j="",k=this._core.settings,l=function(a){e='<div class="owl-video-play-icon"></div>',d=k.lazyLoad?'<div class="owl-video-tn '+j+'" '+i+'="'+a+'"></div>':'<div class="owl-video-tn" style="opacity:1;background-image:url('+a+')"></div>',b.after(d),b.after(e)};return b.wrap('<div class="owl-video-wrapper"'+g+"></div>"),this._core.settings.lazyLoad&&(i="data-src",j="owl-lazy"),h.length?(l(h.attr(i)),h.remove(),!1):void("youtube"===c.type?(f="http://img.youtube.com/vi/"+c.id+"/hqdefault.jpg",l(f)):"vimeo"===c.type&&a.ajax({type:"GET",url:"http://vimeo.com/api/v2/video/"+c.id+".json",jsonp:"callback",dataType:"jsonp",success:function(a){f=a[0].thumbnail_large,l(f)}}))},d.prototype.stop=function(){this._core.trigger("stop",null,"video"),this._playing.find(".owl-video-frame").remove(),this._playing.removeClass("owl-video-playing"),this._playing=null},d.prototype.play=function(b){this._core.trigger("play",null,"video"),this._playing&&this.stop();var c,d,e=a(b.target||b.srcElement),f=e.closest("."+this._core.settings.itemClass),g=this._videos[f.attr("data-video")],h=g.width||"100%",i=g.height||this._core.$stage.height();"youtube"===g.type?c='<iframe width="'+h+'" height="'+i+'" src="http://www.youtube.com/embed/'+g.id+"?autoplay=1&v="+g.id+'" frameborder="0" allowfullscreen></iframe>':"vimeo"===g.type&&(c='<iframe src="http://player.vimeo.com/video/'+g.id+'?autoplay=1" width="'+h+'" height="'+i+'" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>'),f.addClass("owl-video-playing"),this._playing=f,d=a('<div style="height:'+i+"px; width:"+h+'px" class="owl-video-frame">'+c+"</div>"),e.after(d)},d.prototype.isInFullScreen=function(){var d=c.fullscreenElement||c.mozFullScreenElement||c.webkitFullscreenElement;return d&&a(d).parent().hasClass("owl-video-frame")&&(this._core.speed(0),this._fullscreen=!0),d&&this._fullscreen&&this._playing?!1:this._fullscreen?(this._fullscreen=!1,!1):this._playing&&this._core.state.orientation!==b.orientation?(this._core.state.orientation=b.orientation,!1):!0},d.prototype.destroy=function(){var a,b;this._core.$element.off("click.owl.video");for(a in this._handlers)this._core.$element.off(a,this._handlers[a]);for(b in Object.getOwnPropertyNames(this))"function"!=typeof this[b]&&(this[b]=null)},a.fn.owlCarousel.Constructor.Plugins.Video=d}(window.Zepto||window.jQuery,window,document),function(a,b,c,d){var e=function(b){this.core=b,this.core.options=a.extend({},e.Defaults,this.core.options),this.swapping=!0,this.previous=d,this.next=d,this.handlers={"change.owl.carousel":a.proxy(function(a){"position"==a.property.name&&(this.previous=this.core.current(),this.next=a.property.value)},this),"drag.owl.carousel dragged.owl.carousel translated.owl.carousel":a.proxy(function(a){this.swapping="translated"==a.type},this),"translate.owl.carousel":a.proxy(function(){this.swapping&&(this.core.options.animateOut||this.core.options.animateIn)&&this.swap()},this)},this.core.$element.on(this.handlers)};e.Defaults={animateOut:!1,animateIn:!1},e.prototype.swap=function(){if(1===this.core.settings.items&&this.core.support3d){this.core.speed(0);var b,c=a.proxy(this.clear,this),d=this.core.$stage.children().eq(this.previous),e=this.core.$stage.children().eq(this.next),f=this.core.settings.animateIn,g=this.core.settings.animateOut;this.core.current()!==this.previous&&(g&&(b=this.core.coordinates(this.previous)-this.core.coordinates(this.next),d.css({left:b+"px"}).addClass("animated owl-animated-out").addClass(g).one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend",c)),f&&e.addClass("animated owl-animated-in").addClass(f).one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend",c))}},e.prototype.clear=function(b){a(b.target).css({left:""}).removeClass("animated owl-animated-out owl-animated-in").removeClass(this.core.settings.animateIn).removeClass(this.core.settings.animateOut),this.core.transitionEnd()},e.prototype.destroy=function(){var a,b;for(a in this.handlers)this.core.$element.off(a,this.handlers[a]);for(b in Object.getOwnPropertyNames(this))"function"!=typeof this[b]&&(this[b]=null)},a.fn.owlCarousel.Constructor.Plugins.Animate=e}(window.Zepto||window.jQuery,window,document),function(a,b,c){var d=function(b){this.core=b,this.core.options=a.extend({},d.Defaults,this.core.options),this.handlers={"translated.owl.carousel refreshed.owl.carousel":a.proxy(function(){this.autoplay()
  2 +},this),"play.owl.autoplay":a.proxy(function(a,b,c){this.play(b,c)},this),"stop.owl.autoplay":a.proxy(function(){this.stop()},this),"mouseover.owl.autoplay":a.proxy(function(){this.core.settings.autoplayHoverPause&&this.pause()},this),"mouseleave.owl.autoplay":a.proxy(function(){this.core.settings.autoplayHoverPause&&this.autoplay()},this)},this.core.$element.on(this.handlers)};d.Defaults={autoplay:!1,autoplayTimeout:5e3,autoplayHoverPause:!1,autoplaySpeed:!1},d.prototype.autoplay=function(){this.core.settings.autoplay&&!this.core.state.videoPlay?(b.clearInterval(this.interval),this.interval=b.setInterval(a.proxy(function(){this.play()},this),this.core.settings.autoplayTimeout)):b.clearInterval(this.interval)},d.prototype.play=function(){return c.hidden===!0||this.core.state.isTouch||this.core.state.isScrolling||this.core.state.isSwiping||this.core.state.inMotion?void 0:this.core.settings.autoplay===!1?void b.clearInterval(this.interval):void this.core.next(this.core.settings.autoplaySpeed)},d.prototype.stop=function(){b.clearInterval(this.interval)},d.prototype.pause=function(){b.clearInterval(this.interval)},d.prototype.destroy=function(){var a,c;b.clearInterval(this.interval);for(a in this.handlers)this.core.$element.off(a,this.handlers[a]);for(c in Object.getOwnPropertyNames(this))"function"!=typeof this[c]&&(this[c]=null)},a.fn.owlCarousel.Constructor.Plugins.autoplay=d}(window.Zepto||window.jQuery,window,document),function(a){"use strict";var b=function(c){this._core=c,this._initialized=!1,this._pages=[],this._controls={},this._templates=[],this.$element=this._core.$element,this._overrides={next:this._core.next,prev:this._core.prev,to:this._core.to},this._handlers={"prepared.owl.carousel":a.proxy(function(b){this._core.settings.dotsData&&this._templates.push(a(b.content).find("[data-dot]").andSelf("[data-dot]").attr("data-dot"))},this),"add.owl.carousel":a.proxy(function(b){this._core.settings.dotsData&&this._templates.splice(b.position,0,a(b.content).find("[data-dot]").andSelf("[data-dot]").attr("data-dot"))},this),"remove.owl.carousel prepared.owl.carousel":a.proxy(function(a){this._core.settings.dotsData&&this._templates.splice(a.position,1)},this),"change.owl.carousel":a.proxy(function(a){if("position"==a.property.name&&!this._core.state.revert&&!this._core.settings.loop&&this._core.settings.navRewind){var b=this._core.current(),c=this._core.maximum(),d=this._core.minimum();a.data=a.property.value>c?b>=c?d:c:a.property.value<d?c:a.property.value}},this),"changed.owl.carousel":a.proxy(function(a){"position"==a.property.name&&this.draw()},this),"refreshed.owl.carousel":a.proxy(function(){this._initialized||(this.initialize(),this._initialized=!0),this._core.trigger("refresh",null,"navigation"),this.update(),this.draw(),this._core.trigger("refreshed",null,"navigation")},this)},this._core.options=a.extend({},b.Defaults,this._core.options),this.$element.on(this._handlers)};b.Defaults={nav:!1,navRewind:!0,navText:["prev","next"],navSpeed:!1,navElement:"div",navContainer:!1,navContainerClass:"owl-nav",navClass:["owl-prev","owl-next"],slideBy:1,dotClass:"owl-dot",dotsClass:"owl-dots",dots:!0,dotsEach:!1,dotData:!1,dotsSpeed:!1,dotsContainer:!1,controlsClass:"owl-controls"},b.prototype.initialize=function(){var b,c,d=this._core.settings;d.dotsData||(this._templates=[a("<div>").addClass(d.dotClass).append(a("<span>")).prop("outerHTML")]),d.navContainer&&d.dotsContainer||(this._controls.$container=a("<div>").addClass(d.controlsClass).appendTo(this.$element)),this._controls.$indicators=d.dotsContainer?a(d.dotsContainer):a("<div>").hide().addClass(d.dotsClass).appendTo(this._controls.$container),this._controls.$indicators.on("click","div",a.proxy(function(b){var c=a(b.target).parent().is(this._controls.$indicators)?a(b.target).index():a(b.target).parent().index();b.preventDefault(),this.to(c,d.dotsSpeed)},this)),b=d.navContainer?a(d.navContainer):a("<div>").addClass(d.navContainerClass).prependTo(this._controls.$container),this._controls.$next=a("<"+d.navElement+">"),this._controls.$previous=this._controls.$next.clone(),this._controls.$previous.addClass(d.navClass[0]).html(d.navText[0]).hide().prependTo(b).on("click",a.proxy(function(){this.prev(d.navSpeed)},this)),this._controls.$next.addClass(d.navClass[1]).html(d.navText[1]).hide().appendTo(b).on("click",a.proxy(function(){this.next(d.navSpeed)},this));for(c in this._overrides)this._core[c]=a.proxy(this[c],this)},b.prototype.destroy=function(){var a,b,c,d;for(a in this._handlers)this.$element.off(a,this._handlers[a]);for(b in this._controls)this._controls[b].remove();for(d in this.overides)this._core[d]=this._overrides[d];for(c in Object.getOwnPropertyNames(this))"function"!=typeof this[c]&&(this[c]=null)},b.prototype.update=function(){var a,b,c,d=this._core.settings,e=this._core.clones().length/2,f=e+this._core.items().length,g=d.center||d.autoWidth||d.dotData?1:d.dotsEach||d.items;if("page"!==d.slideBy&&(d.slideBy=Math.min(d.slideBy,d.items)),d.dots||"page"==d.slideBy)for(this._pages=[],a=e,b=0,c=0;f>a;a++)(b>=g||0===b)&&(this._pages.push({start:a-e,end:a-e+g-1}),b=0,++c),b+=this._core.mergers(this._core.relative(a))},b.prototype.draw=function(){var b,c,d="",e=this._core.settings,f=(this._core.$stage.children(),this._core.relative(this._core.current()));if(!e.nav||e.loop||e.navRewind||(this._controls.$previous.toggleClass("disabled",0>=f),this._controls.$next.toggleClass("disabled",f>=this._core.maximum())),this._controls.$previous.toggle(e.nav),this._controls.$next.toggle(e.nav),e.dots){if(b=this._pages.length-this._controls.$indicators.children().length,e.dotData&&0!==b){for(c=0;c<this._controls.$indicators.children().length;c++)d+=this._templates[this._core.relative(c)];this._controls.$indicators.html(d)}else b>0?(d=new Array(b+1).join(this._templates[0]),this._controls.$indicators.append(d)):0>b&&this._controls.$indicators.children().slice(b).remove();this._controls.$indicators.find(".active").removeClass("active"),this._controls.$indicators.children().eq(a.inArray(this.current(),this._pages)).addClass("active")}this._controls.$indicators.toggle(e.dots)},b.prototype.onTrigger=function(b){var c=this._core.settings;b.page={index:a.inArray(this.current(),this._pages),count:this._pages.length,size:c&&(c.center||c.autoWidth||c.dotData?1:c.dotsEach||c.items)}},b.prototype.current=function(){var b=this._core.relative(this._core.current());return a.grep(this._pages,function(a){return a.start<=b&&a.end>=b}).pop()},b.prototype.getPosition=function(b){var c,d,e=this._core.settings;return"page"==e.slideBy?(c=a.inArray(this.current(),this._pages),d=this._pages.length,b?++c:--c,c=this._pages[(c%d+d)%d].start):(c=this._core.relative(this._core.current()),d=this._core.items().length,b?c+=e.slideBy:c-=e.slideBy),c},b.prototype.next=function(b){a.proxy(this._overrides.to,this._core)(this.getPosition(!0),b)},b.prototype.prev=function(b){a.proxy(this._overrides.to,this._core)(this.getPosition(!1),b)},b.prototype.to=function(b,c,d){var e;d?a.proxy(this._overrides.to,this._core)(b,c):(e=this._pages.length,a.proxy(this._overrides.to,this._core)(this._pages[(b%e+e)%e].start,c))},a.fn.owlCarousel.Constructor.Plugins.Navigation=b}(window.Zepto||window.jQuery,window,document),function(a,b){"use strict";var c=function(d){this._core=d,this._hashes={},this.$element=this._core.$element,this._handlers={"initialized.owl.carousel":a.proxy(function(){"URLHash"==this._core.settings.startPosition&&a(b).trigger("hashchange.owl.navigation")},this),"prepared.owl.carousel":a.proxy(function(b){var c=a(b.content).find("[data-hash]").andSelf("[data-hash]").attr("data-hash");this._hashes[c]=b.content},this)},this._core.options=a.extend({},c.Defaults,this._core.options),this.$element.on(this._handlers),a(b).on("hashchange.owl.navigation",a.proxy(function(){var a=b.location.hash.substring(1),c=this._core.$stage.children(),d=this._hashes[a]&&c.index(this._hashes[a])||0;return a?void this._core.to(d,!1,!0):!1},this))};c.Defaults={URLhashListener:!1},c.prototype.destroy=function(){var c,d;a(b).off("hashchange.owl.navigation");for(c in this._handlers)this._core.$element.off(c,this._handlers[c]);for(d in Object.getOwnPropertyNames(this))"function"!=typeof this[d]&&(this[d]=null)},a.fn.owlCarousel.Constructor.Plugins.Hash=c}(window.Zepto||window.jQuery,window,document);
0 3 \ No newline at end of file
... ...
tests/_bootstrap.php
1 1 <?php
2   -// This is global bootstrap for autoloading
  2 +
  3 +defined('YII_DEBUG') or define('YII_DEBUG', true);
  4 +defined('YII_ENV') or define('YII_ENV', 'test');
  5 +
  6 +require(__DIR__ . '/../vendor/autoload.php');
  7 +require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
  8 +require(__DIR__ . '/../common/config/bootstrap.php');
  9 +
  10 +$config = yii\helpers\ArrayHelper::merge(
  11 + require(__DIR__ . '/../common/config/main.php'),
  12 + require(__DIR__ . '/../common/config/main-local.php'),
  13 + require(__DIR__ . '/config/main.php')
  14 +
  15 +);
  16 +
  17 +Yii::setAlias('@tests', dirname(__DIR__));
  18 +
  19 +$application = new yii\web\Application($config);
3 20 \ No newline at end of file
... ...
tests/_support/AcceptanceTester.php
... ... @@ -12,7 +12,7 @@
12 12 * @method void am($role)
13 13 * @method void lookForwardTo($achieveValue)
14 14 * @method void comment($description)
15   - * @method \Codeception\Lib\Friend haveFriend($name, $actorClass = NULL)
  15 + * @method \Codeception\Lib\Friend haveFriend($name, $actorClass = null)
16 16 *
17 17 * @SuppressWarnings(PHPMD)
18 18 */
... ...
tests/_support/FunctionalTester.php
... ... @@ -12,7 +12,7 @@
12 12 * @method void am($role)
13 13 * @method void lookForwardTo($achieveValue)
14 14 * @method void comment($description)
15   - * @method \Codeception\Lib\Friend haveFriend($name, $actorClass = NULL)
  15 + * @method \Codeception\Lib\Friend haveFriend($name, $actorClass = null)
16 16 *
17 17 * @SuppressWarnings(PHPMD)
18 18 */
... ...
tests/_support/Helper/Acceptance.php
1 1 <?php
2 2 namespace Helper;
3   -
4 3 // here you can define custom actions
5 4 // all public methods declared in helper class will be available in $I
6 5  
... ...
tests/_support/Helper/Functional.php
1 1 <?php
2 2 namespace Helper;
3   -
4 3 // here you can define custom actions
5 4 // all public methods declared in helper class will be available in $I
6 5  
... ...
tests/_support/Helper/Unit.php
1 1 <?php
2 2 namespace Helper;
3   -
4 3 // here you can define custom actions
5 4 // all public methods declared in helper class will be available in $I
6 5  
... ...
tests/_support/UnitTester.php
... ... @@ -12,7 +12,7 @@
12 12 * @method void am($role)
13 13 * @method void lookForwardTo($achieveValue)
14 14 * @method void comment($description)
15   - * @method \Codeception\Lib\Friend haveFriend($name, $actorClass = NULL)
  15 + * @method \Codeception\Lib\Friend haveFriend($name, $actorClass = null)
16 16 *
17 17 * @SuppressWarnings(PHPMD)
18 18 */
... ...
tests/_support/_generated/AcceptanceTesterActions.php
1   -<?php //[STAMP] 749e5af797e3fdd425f46313312ddd2a
  1 +<?php //[STAMP] 11cfc123f33c5f6417461c48aa19af00
2 2 namespace _generated;
3 3  
4 4 // This class was automatically generated by build task
... ...
tests/acceptance.suite.yml
... ... @@ -8,6 +8,6 @@ class_name: AcceptanceTester
8 8 modules:
9 9 enabled:
10 10 - WebDriver:
11   - url: http://home-1.local/
  11 + url: http://mfp.dev/
12 12 browser: firefox
13 13 - \Helper\Acceptance
14 14 \ No newline at end of file
... ...