From a6d81a57ca9c0ad84eb4595652bca3042a08ee1e Mon Sep 17 00:00:00 2001 From: Shih-Wen Su Date: Thu, 16 May 2013 12:39:19 +0800 Subject: [PATCH 1/9] fix ambiguity condition --- app/app/controllers.ls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/app/controllers.ls b/app/app/controllers.ls index 2a507b3..f733a28 100644 --- a/app/app/controllers.ls +++ b/app/app/controllers.ls @@ -17,7 +17,7 @@ mod.AppCtrl = <[$scope $location $resource $rootScope]> ++ (s, $location, $resou # getClass('/orders') # returns '' # s.getClass = (id) -> - if s.activeNavId.substring 0 id.length is id + if s.activeNavId.substring(0 id.length) is id 'active' else '' From 13eb088766b1b9a71ed6d433e75a58f95ab2b097 Mon Sep 17 00:00:00 2001 From: Shih-Wen Su Date: Thu, 16 May 2013 14:33:56 +0800 Subject: [PATCH 2/9] change from bootstrap less/sass to metro stylus --- app/assets/font/iconFont.eot | Bin 0 -> 60392 bytes app/assets/font/iconFont.svg | 2011 ++++++ app/assets/font/iconFont.ttf | Bin 0 -> 60224 bytes app/assets/font/iconFont.woff | Bin 0 -> 83060 bytes app/assets/font/license.txt | 10 + app/assets/img/preloader-w8-cycle-black.gif | Bin 0 -> 11630 bytes app/assets/img/preloader-w8-cycle-white.gif | Bin 0 -> 11630 bytes app/assets/img/preloader-w8-line-black.gif | Bin 0 -> 5190 bytes app/assets/img/preloader-w8-line-white.gif | Bin 0 -> 5190 bytes vendor/styles/bootstrap/_accordion.scss | 34 - vendor/styles/bootstrap/_alerts.scss | 79 - vendor/styles/bootstrap/_breadcrumbs.scss | 24 - vendor/styles/bootstrap/_button-groups.scss | 229 - vendor/styles/bootstrap/_buttons.scss | 228 - vendor/styles/bootstrap/_carousel.scss | 158 - vendor/styles/bootstrap/_close.scss | 32 - vendor/styles/bootstrap/_code.scss | 61 - .../bootstrap/_component-animations.scss | 22 - vendor/styles/bootstrap/_dropdowns.scss | 237 - vendor/styles/bootstrap/_forms.scss | 689 -- vendor/styles/bootstrap/_grid.scss | 21 - vendor/styles/bootstrap/_hero-unit.scss | 25 - vendor/styles/bootstrap/_labels-badges.scss | 83 - vendor/styles/bootstrap/_layouts.scss | 16 - vendor/styles/bootstrap/_media.scss | 55 - vendor/styles/bootstrap/_mixins.scss | 690 -- vendor/styles/bootstrap/_modals.scss | 95 - vendor/styles/bootstrap/_navbar.scss | 497 -- vendor/styles/bootstrap/_navs.scss | 409 -- vendor/styles/bootstrap/_pager.scss | 43 - vendor/styles/bootstrap/_pagination.scss | 123 - vendor/styles/bootstrap/_popovers.scss | 133 - vendor/styles/bootstrap/_progress-bars.scss | 122 - vendor/styles/bootstrap/_reset.scss | 216 - .../bootstrap/_responsive-1200px-min.scss | 28 - .../bootstrap/_responsive-767px-max.scss | 193 - .../bootstrap/_responsive-768px-979px.scss | 19 - .../styles/bootstrap/_responsive-navbar.scss | 189 - .../bootstrap/_responsive-utilities.scss | 74 - vendor/styles/bootstrap/_scaffolding.scss | 53 - vendor/styles/bootstrap/_sprites.scss | 197 - vendor/styles/bootstrap/_tables.scss | 235 - vendor/styles/bootstrap/_thumbnails.scss | 53 - vendor/styles/bootstrap/_tooltip.scss | 70 - vendor/styles/bootstrap/_type.scss | 247 - vendor/styles/bootstrap/_utilities.scss | 45 - vendor/styles/bootstrap/_variables.scss | 301 - vendor/styles/bootstrap/_wells.scss | 29 - vendor/styles/metro/_theme-dark.styl | 65 + vendor/styles/metro/modern-responsive.styl | 753 ++ vendor/styles/metro/modern.styl | 6316 +++++++++++++++++ vendor/styles/sapling/_account.less | 7 - vendor/styles/sapling/_angular.less | 18 - vendor/styles/sapling/_auth.less | 47 - vendor/styles/sapling/_breadcrumbs.less | 22 - vendor/styles/sapling/_font-awesome.less | 329 - vendor/styles/sapling/_sticky-footer.less | 23 - vendor/styles/themes/default/_overrides.less | 9 - vendor/styles/themes/default/_variables.less | 205 - vendor/styles/themes/sapling/_overrides.less | 59 - vendor/styles/themes/sapling/_variables.less | 206 - vendor/styles/themes/smokey/_overrides.less | 59 - vendor/styles/themes/smokey/_variables.less | 212 - 63 files changed, 9155 insertions(+), 7250 deletions(-) create mode 100644 app/assets/font/iconFont.eot create mode 100644 app/assets/font/iconFont.svg create mode 100644 app/assets/font/iconFont.ttf create mode 100644 app/assets/font/iconFont.woff create mode 100644 app/assets/font/license.txt create mode 100644 app/assets/img/preloader-w8-cycle-black.gif create mode 100644 app/assets/img/preloader-w8-cycle-white.gif create mode 100644 app/assets/img/preloader-w8-line-black.gif create mode 100644 app/assets/img/preloader-w8-line-white.gif delete mode 100644 vendor/styles/bootstrap/_accordion.scss delete mode 100644 vendor/styles/bootstrap/_alerts.scss delete mode 100644 vendor/styles/bootstrap/_breadcrumbs.scss delete mode 100644 vendor/styles/bootstrap/_button-groups.scss delete mode 100644 vendor/styles/bootstrap/_buttons.scss delete mode 100644 vendor/styles/bootstrap/_carousel.scss delete mode 100644 vendor/styles/bootstrap/_close.scss delete mode 100644 vendor/styles/bootstrap/_code.scss delete mode 100644 vendor/styles/bootstrap/_component-animations.scss delete mode 100644 vendor/styles/bootstrap/_dropdowns.scss delete mode 100644 vendor/styles/bootstrap/_forms.scss delete mode 100644 vendor/styles/bootstrap/_grid.scss delete mode 100644 vendor/styles/bootstrap/_hero-unit.scss delete mode 100644 vendor/styles/bootstrap/_labels-badges.scss delete mode 100644 vendor/styles/bootstrap/_layouts.scss delete mode 100644 vendor/styles/bootstrap/_media.scss delete mode 100644 vendor/styles/bootstrap/_mixins.scss delete mode 100644 vendor/styles/bootstrap/_modals.scss delete mode 100644 vendor/styles/bootstrap/_navbar.scss delete mode 100644 vendor/styles/bootstrap/_navs.scss delete mode 100644 vendor/styles/bootstrap/_pager.scss delete mode 100644 vendor/styles/bootstrap/_pagination.scss delete mode 100644 vendor/styles/bootstrap/_popovers.scss delete mode 100644 vendor/styles/bootstrap/_progress-bars.scss delete mode 100644 vendor/styles/bootstrap/_reset.scss delete mode 100644 vendor/styles/bootstrap/_responsive-1200px-min.scss delete mode 100644 vendor/styles/bootstrap/_responsive-767px-max.scss delete mode 100644 vendor/styles/bootstrap/_responsive-768px-979px.scss delete mode 100644 vendor/styles/bootstrap/_responsive-navbar.scss delete mode 100644 vendor/styles/bootstrap/_responsive-utilities.scss delete mode 100644 vendor/styles/bootstrap/_scaffolding.scss delete mode 100644 vendor/styles/bootstrap/_sprites.scss delete mode 100644 vendor/styles/bootstrap/_tables.scss delete mode 100644 vendor/styles/bootstrap/_thumbnails.scss delete mode 100644 vendor/styles/bootstrap/_tooltip.scss delete mode 100644 vendor/styles/bootstrap/_type.scss delete mode 100644 vendor/styles/bootstrap/_utilities.scss delete mode 100644 vendor/styles/bootstrap/_variables.scss delete mode 100644 vendor/styles/bootstrap/_wells.scss create mode 100644 vendor/styles/metro/_theme-dark.styl create mode 100644 vendor/styles/metro/modern-responsive.styl create mode 100644 vendor/styles/metro/modern.styl delete mode 100644 vendor/styles/sapling/_account.less delete mode 100644 vendor/styles/sapling/_angular.less delete mode 100644 vendor/styles/sapling/_auth.less delete mode 100644 vendor/styles/sapling/_breadcrumbs.less delete mode 100644 vendor/styles/sapling/_font-awesome.less delete mode 100644 vendor/styles/sapling/_sticky-footer.less delete mode 100644 vendor/styles/themes/default/_overrides.less delete mode 100644 vendor/styles/themes/default/_variables.less delete mode 100644 vendor/styles/themes/sapling/_overrides.less delete mode 100644 vendor/styles/themes/sapling/_variables.less delete mode 100644 vendor/styles/themes/smokey/_overrides.less delete mode 100644 vendor/styles/themes/smokey/_variables.less diff --git a/app/assets/font/iconFont.eot b/app/assets/font/iconFont.eot new file mode 100644 index 0000000000000000000000000000000000000000..c4e464e18aa4eca9b99fde48ee484f194ffc1f4e GIT binary patch literal 60392 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 E&#fRD{r~^~ literal 0 HcmV?d00001 diff --git a/app/assets/font/iconFont.svg b/app/assets/font/iconFont.svg new file mode 100644 index 0000000..4682f4c --- /dev/null +++ b/app/assets/font/iconFont.svg @@ -0,0 +1,2011 @@ + + + + +This is a custom SVG font generated by IcoMoon. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/assets/font/iconFont.ttf b/app/assets/font/iconFont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..e7dccbdeef9110ded0dea58974690179828096e0 GIT binary patch literal 60224 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

w>#5Jt_El;PC7^hP63?1N6;N0qX zTy0MR{8KPxV*Db1KW$xfwFEP3_!I$K8pPm6t=PVCNmxTp+;&-ebZ}T&-?$sHQh(0u zTa|Ky1$cU4<}%G$Mn;bI@yBtQd2BSmk4thjp6_0MN92-?YZwr%&KNRkj=?^cdHL;> zKCpg05f7i?fF!+p`EXmq%IG=9%p2Gc-~UM*XP(KatS-@^VI*?lg)^=1!K5`!&>w6t zM#s+EYn_~D;NyJvseH5}m!0fy+V9G}=26v9txYo$dqBB3Uykw>Rv=WSY^X(V}fQf|A5_XkOw z&HRfx!R*^IZUSF=9wqwPWcz)UK0RpLn1$mH$)E>=3V%^! z&Q!4?UO59N!(P$pnLkIY+pQL9*WYy>0Ojj3k*&8mzmK9SHE6$ZWW=Pm^RrQz0jOG} zE!O>gog0B%_++b!s@D9-InN4x%6xU#s7wpUnt4OS%)aZq82gm~D{PRx;EdY7ny*|q zClcv>+O^XNMmQO0cAM+such+koIh8pU6xsEg<+h&L!+JarzxjebK@mzJ;2QgGQOLy-o;G*5BbN(Jl z%+ci%LOm1sUOo^H4FQ%n8{f>=jj%l>)!aN}&ayd_UQ#gog7 zxd8ykCogYBNlW$lZ+Ax<54M2t+qXPJ>cyA zW8e^HI^}koF8pMRuEj9C2JJ?RluyslW=jHrAgKgSBd+dnxdtm9u(hMV^Ypgv7?0Lq zBVUIVd<`jT=5$q`zvmQf=~*8dCw<`c#_4*;n?#g$Yx%M!kYw;(ZhJ*EIJ{9r@DDU5 zYkbUoQ?)R#_{4mNyLBmxJNBrSOt9!XHKx@%PEpFinh9VH@>;Z*$(*B>Y157Yk}p)+ zUsZnpoJzYZ3=z#LEg1kO`R&k0#%!r0{*m$6KSb=Dr1t#2zj4kW0YRs6Vt)PVd>~G8 zO{dFE_{R$*@R-W$c4~z+7Z=W{5b?zYMdSz5w20~xU0=FQd?@N-?SLgXU3l`YepVf5 zq3vTO3F92j+}GucGw*G59mDnYdNpIK#@uN`81^0x?0OL4IcPAj_1$tcTpaG5-sl~M z%lExRP@75D_dzdX!UXjAp1N0ce2pLO>su}n&9s6$ge@c?u4bp%^K7h(orZ~gDltuW z!XmV%i}-MBjvsbm_4mX+rV`m2J^s%%pF8f+$Y%}}oYM%`|K?RY!s z_F94e6ArG%eA?ip(Gi-2rZ7rvnt0&fX>!UbX)^bJq{-}4(quPi^1fP{d>xu>4o%jr zrO7uKb{?i@Tz7k<7j5y1*oJ?`y8ce{(6Ja>h}^2VpB_5qKk2@GiPxJ4kHwr+PwjoR zap>U@A(HDfOTDOQ-{ShX2GHE?@=<^&_5N&v9KzJui3A`V?5ry4WIsy2qH+EanL{GE_D+~ePm!7Y zSzid|~2~!d2V=s~% z<{@G`Kz21RW4{LG8%qYH9h?<)zR7N!JFYRf=_;tqYBUK=W zc4qrWF&difxH#>5N^`xBqsZ;}dTqzuVjunh=~oo$?P&{i!N(&V-}!VHb(^=-BryI= zs+8s9fV^2a_-uXREgZD&M%=chK5*EcFJju71E`u3s%-zZ2W| zdU#K#3$)??p1sgG4T)D@(quNefzxcB@gz4)hPiiIFJ_Mcs&T*e;_bh0)eG-Wy&tLM z;OSo*bK!)mjPnyo3Y#`L0t%>2yV;YamBEVJ$U@B0LJSRyq0l38Ya;(w8k1=w8 z6)*MR^;OM-dcLNf9&TmaPbYQ^e0}^lWaW!0 zT=2(yFDcsc5z8vjA9%0kawJl!K+n+2nfAp

x=tvOVt0`aq+TKUKW5Jq=mvzO2S| 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

LH#o3w-5aSNQrxQ$O9gM&NJu_OO1&L-6 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 Pc${NkX21&o0DS-iZfb41 literal 0 HcmV?d00001 diff --git a/app/assets/font/license.txt b/app/assets/font/license.txt new file mode 100644 index 0000000..b59a5cd --- /dev/null +++ b/app/assets/font/license.txt @@ -0,0 +1,10 @@ +Icon Set: Broccolidry -- http://dribbble.com/shots/587469-Free-16px-Broccolidryiconsaniconsetitisfullof-icons +License: Aribitrary -- http://licence.visualidiot.com/ + + +Icon Set: Meteocons -- http://www.alessioatzeni.com/meteocons/ +License: Arbitrary -- http://www.alessioatzeni.com/meteocons/#about + + +Icon Set: IcoMoon - Free -- http://keyamoon.com/icomoon/ +License: CC BY-SA 3.0 -- http://creativecommons.org/licenses/by-sa/3.0/ \ No newline at end of file diff --git a/app/assets/img/preloader-w8-cycle-black.gif b/app/assets/img/preloader-w8-cycle-black.gif new file mode 100644 index 0000000000000000000000000000000000000000..764b04f78d3f29370cd52f316324418f1abbe979 GIT binary patch literal 11630 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 z z6Dio7^5VjP$4j!|GV(F^lE=U;hVJ#sPSF|Wu$WBy4CpeiH^O(O)TFCvL*TAcHwr8Z z?_4-)JjPeEfFT;+!cw)U%4{&(4kV617uAAe>N=U7!08U4QlN){>@{7 z>?FSB)BVJAJvyI0ch&avM`4I#_KKnb)HVp6ji9u<+Pk}d%Rx-w$;0EGnWj8*R|V7jPS<8HIg zZ0;(*NNVL(V-0De6OF{uaoZsbzsiD8P2I_8E2rC&QRugn=sGko zMqXo!&S?pAibv?}>v*1)Ae04GXIj?eUFv;s*PLTeA$Js>3HGjwcs^c#>smEE6Mf!_ z(5ytNo<^tAxN`6X`4+H3v8>-gqO)je*~Q*1lcik)rX#E8l%emYqp}bfBZ~Hb!KIK) zOdKiOs`Od=Y`mk(fviW1b+qBVMayPlX(Ie3BXuG}S!kaLn*NzQ=aqK#< ziou>W9m-({)#pW-cAHPbN6w3AX)Bq6 zB$Yrx_Cz|H!gxf&!;NF$!6dpX1Sxkq23;s8gaHbj;YJe>skvHqk$1`)2#neZu ziJI_UR_db=yFJzy-6?`$lzXaI-^zyP;9sD!tOzQK?%JP17YhG3U>VLKqzhEqxNF&~ zO(GyTCUx~0zBIaM4-!*v^&qi2AdHlUh&Yc>@jg!^uujSAn184VqK~6r>>+?RlLkNK zRnkNW%f)Uy3wAvpM%+bl+*s0`(o1Lg8Vs}A)_z}&X;-5~8L1)e8yK7pl5!DDifMg^ zr@sM{&QFc-r$+cwBmAim{?rKPo+&1OYJ@*ELLmFZPmS=WM)*@B{HYOgpMebsKQ+Sn zo6-MIjWC#h1OC6&2zj=IMcQ>buz(QAyIJyI0sf=P;G8|{hUQh+0r&IvT-`-P6RwmR zix+~dAyHV!dkK!kJ@4DL^vZGqWH5S-QzJ>Hv5&{F;>Mrq%>TgMWkC$Y9 z7I4NG^`=)Vdje(%wOd zf)5GzKQ=yOue|N^%VeqTzS9!NG-PilE3Ez1XJ26RvDEJ^l{}j$K(#0Vi!Wjen(p{R8}2v9pO~qr6=5DBG zD$N%~`_65wFF0{no3-+-#EmgIf5Qh?km?(6?&-V5upGrzZC&WnTVTzdiFTI%f-m@u px%r=Xj->?zd`upc4CJGu-{+ajvI;+0XO%jR&E@k?uIE_qzW|BeqOkw~ literal 0 HcmV?d00001 diff --git a/app/assets/img/preloader-w8-cycle-white.gif b/app/assets/img/preloader-w8-cycle-white.gif new file mode 100644 index 0000000000000000000000000000000000000000..cb2f48500e4b16270954f73d85dbf8ec041e5cb6 GIT binary patch literal 11630 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 literal 0 HcmV?d00001 diff --git a/app/assets/img/preloader-w8-line-black.gif b/app/assets/img/preloader-w8-line-black.gif new file mode 100644 index 0000000000000000000000000000000000000000..abc50a78f4a12cfa40fcb679f9c6b86304f04dca GIT binary patch literal 5190 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 Dsp0cE literal 0 HcmV?d00001 diff --git a/app/assets/img/preloader-w8-line-white.gif b/app/assets/img/preloader-w8-line-white.gif new file mode 100644 index 0000000000000000000000000000000000000000..41aa1edbbc895af07863ee4b0578cd9fdaa925ce GIT binary patch literal 5190 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 p, -.alert-block > ul { - margin-bottom: 0; -} -.alert-block p + p { - margin-top: 5px; -} diff --git a/vendor/styles/bootstrap/_breadcrumbs.scss b/vendor/styles/bootstrap/_breadcrumbs.scss deleted file mode 100644 index cc3f327..0000000 --- a/vendor/styles/bootstrap/_breadcrumbs.scss +++ /dev/null @@ -1,24 +0,0 @@ -// -// Breadcrumbs -// -------------------------------------------------- - - -.breadcrumb { - padding: 8px 15px; - margin: 0 0 $baseLineHeight; - list-style: none; - background-color: #f5f5f5; - @include border-radius($baseBorderRadius); - > li { - display: inline-block; - @include ie7-inline-block(); - text-shadow: 0 1px 0 $white; - > .divider { - padding: 0 5px; - color: #ccc; - } - } - .active { - color: $grayLight; - } -} diff --git a/vendor/styles/bootstrap/_button-groups.scss b/vendor/styles/bootstrap/_button-groups.scss deleted file mode 100644 index 1b08d50..0000000 --- a/vendor/styles/bootstrap/_button-groups.scss +++ /dev/null @@ -1,229 +0,0 @@ -// -// Button groups -// -------------------------------------------------- - - -// Make the div behave like a button -.btn-group { - position: relative; - display: inline-block; - @include ie7-inline-block(); - font-size: 0; // remove as part 1 of font-size inline-block hack - vertical-align: middle; // match .btn alignment given font-size hack above - white-space: nowrap; // prevent buttons from wrapping when in tight spaces (e.g., the table on the tests page) - @include ie7-restore-left-whitespace(); -} - -// Space out series of button groups -.btn-group + .btn-group { - margin-left: 5px; -} - -// Optional: Group multiple button groups together for a toolbar -.btn-toolbar { - font-size: 0; // Hack to remove whitespace that results from using inline-block - margin-top: $baseLineHeight / 2; - margin-bottom: $baseLineHeight / 2; - > .btn + .btn, - > .btn-group + .btn, - > .btn + .btn-group { - margin-left: 5px; - } -} - -// Float them, remove border radius, then re-add to first and last elements -.btn-group > .btn { - position: relative; - @include border-radius(0); -} -.btn-group > .btn + .btn { - margin-left: -1px; -} -.btn-group > .btn, -.btn-group > .dropdown-menu, -.btn-group > .popover { - font-size: $baseFontSize; // redeclare as part 2 of font-size inline-block hack -} - -// Reset fonts for other sizes -.btn-group > .btn-mini { - font-size: $fontSizeMini; -} -.btn-group > .btn-small { - font-size: $fontSizeSmall; -} -.btn-group > .btn-large { - font-size: $fontSizeLarge; -} - -// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match -.btn-group > .btn:first-child { - margin-left: 0; - @include border-top-left-radius($baseBorderRadius); - @include border-bottom-left-radius($baseBorderRadius); -} -// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it -.btn-group > .btn:last-child, -.btn-group > .dropdown-toggle { - @include border-top-right-radius($baseBorderRadius); - @include border-bottom-right-radius($baseBorderRadius); -} -// Reset corners for large buttons -.btn-group > .btn.large:first-child { - margin-left: 0; - @include border-top-left-radius($borderRadiusLarge); - @include border-bottom-left-radius($borderRadiusLarge); -} -.btn-group > .btn.large:last-child, -.btn-group > .large.dropdown-toggle { - @include border-top-right-radius($borderRadiusLarge); - @include border-bottom-right-radius($borderRadiusLarge); -} - -// On hover/focus/active, bring the proper btn to front -.btn-group > .btn:hover, -.btn-group > .btn:focus, -.btn-group > .btn:active, -.btn-group > .btn.active { - z-index: 2; -} - -// On active and open, don't show outline -.btn-group .dropdown-toggle:active, -.btn-group.open .dropdown-toggle { - outline: 0; -} - - - -// Split button dropdowns -// ---------------------- - -// Give the line between buttons some depth -.btn-group > .btn + .dropdown-toggle { - padding-left: 8px; - padding-right: 8px; - @include box-shadow(inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05)); - *padding-top: 5px; - *padding-bottom: 5px; -} -.btn-group > .btn-mini + .dropdown-toggle { - padding-left: 5px; - padding-right: 5px; - *padding-top: 2px; - *padding-bottom: 2px; -} -.btn-group > .btn-small + .dropdown-toggle { - *padding-top: 5px; - *padding-bottom: 4px; -} -.btn-group > .btn-large + .dropdown-toggle { - padding-left: 12px; - padding-right: 12px; - *padding-top: 7px; - *padding-bottom: 7px; -} - -.btn-group.open { - - // The clickable button for toggling the menu - // Remove the gradient and set the same inset shadow as the :active state - .dropdown-toggle { - background-image: none; - @include box-shadow(inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05)); - } - - // Keep the hover's background when dropdown is open - .btn.dropdown-toggle { - background-color: $btnBackgroundHighlight; - } - .btn-primary.dropdown-toggle { - background-color: $btnPrimaryBackgroundHighlight; - } - .btn-warning.dropdown-toggle { - background-color: $btnWarningBackgroundHighlight; - } - .btn-danger.dropdown-toggle { - background-color: $btnDangerBackgroundHighlight; - } - .btn-success.dropdown-toggle { - background-color: $btnSuccessBackgroundHighlight; - } - .btn-info.dropdown-toggle { - background-color: $btnInfoBackgroundHighlight; - } - .btn-inverse.dropdown-toggle { - background-color: $btnInverseBackgroundHighlight; - } -} - - -// Reposition the caret -.btn .caret { - margin-top: 8px; - margin-left: 0; -} -// Carets in other button sizes -.btn-large .caret { - margin-top: 6px; -} -.btn-large .caret { - border-left-width: 5px; - border-right-width: 5px; - border-top-width: 5px; -} -.btn-mini .caret, -.btn-small .caret { - margin-top: 8px; -} -// Upside down carets for .dropup -.dropup .btn-large .caret { - border-bottom-width: 5px; -} - - - -// Account for other colors -.btn-primary, -.btn-warning, -.btn-danger, -.btn-info, -.btn-success, -.btn-inverse { - .caret { - border-top-color: $white; - border-bottom-color: $white; - } -} - - - -// Vertical button groups -// ---------------------- - -.btn-group-vertical { - display: inline-block; // makes buttons only take up the width they need - @include ie7-inline-block(); -} -.btn-group-vertical > .btn { - display: block; - float: none; - max-width: 100%; - @include border-radius(0); -} -.btn-group-vertical > .btn + .btn { - margin-left: 0; - margin-top: -1px; -} -.btn-group-vertical > .btn:first-child { - @include border-radius($baseBorderRadius $baseBorderRadius 0 0); -} -.btn-group-vertical > .btn:last-child { - @include border-radius(0 0 $baseBorderRadius $baseBorderRadius); -} -.btn-group-vertical > .btn-large:first-child { - @include border-radius($borderRadiusLarge $borderRadiusLarge 0 0); -} -.btn-group-vertical > .btn-large:last-child { - @include border-radius(0 0 $borderRadiusLarge $borderRadiusLarge); -} diff --git a/vendor/styles/bootstrap/_buttons.scss b/vendor/styles/bootstrap/_buttons.scss deleted file mode 100644 index a92268b..0000000 --- a/vendor/styles/bootstrap/_buttons.scss +++ /dev/null @@ -1,228 +0,0 @@ -// -// Buttons -// -------------------------------------------------- - - -// Base styles -// -------------------------------------------------- - -// Core -.btn { - display: inline-block; - @include ie7-inline-block(); - padding: 4px 12px; - margin-bottom: 0; // For input.btn - font-size: $baseFontSize; - line-height: $baseLineHeight; - text-align: center; - vertical-align: middle; - cursor: pointer; - @include buttonBackground($btnBackground, $btnBackgroundHighlight, $grayDark, 0 1px 1px rgba(255,255,255,.75)); - border: 1px solid $btnBorder; - *border: 0; // Remove the border to prevent IE7's black border on input:focus - border-bottom-color: darken($btnBorder, 10%); - @include border-radius($baseBorderRadius); - @include ie7-restore-left-whitespace(); // Give IE7 some love - @include box-shadow(inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05)); - - // Hover/focus state - &:hover, - &:focus { - color: $grayDark; - text-decoration: none; - background-position: 0 -15px; - - // transition is only when going to hover/focus, otherwise the background - // behind the gradient (there for IE<=9 fallback) gets mismatched - @include transition(background-position .1s linear); - } - - // Focus state for keyboard and accessibility - &:focus { - @include tab-focus(); - } - - // Active state - &.active, - &:active { - background-image: none; - outline: 0; - @include box-shadow(inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05)); - } - - // Disabled state - &.disabled, - &[disabled] { - cursor: default; - background-image: none; - @include opacity(65); - @include box-shadow(none); - } - -} - - - -// Button Sizes -// -------------------------------------------------- - -// Large -.btn-large { - padding: $paddingLarge; - font-size: $fontSizeLarge; - @include border-radius($borderRadiusLarge); -} -.btn-large [class^="icon-"], -.btn-large [class*=" icon-"] { - margin-top: 4px; -} - -// Small -.btn-small { - padding: $paddingSmall; - font-size: $fontSizeSmall; - @include border-radius($borderRadiusSmall); -} -.btn-small [class^="icon-"], -.btn-small [class*=" icon-"] { - margin-top: 0; -} -.btn-mini [class^="icon-"], -.btn-mini [class*=" icon-"] { - margin-top: -1px; -} - -// Mini -.btn-mini { - padding: $paddingMini; - font-size: $fontSizeMini; - @include border-radius($borderRadiusSmall); -} - - -// Block button -// ------------------------- - -.btn-block { - display: block; - width: 100%; - padding-left: 0; - padding-right: 0; - @include box-sizing(border-box); -} - -// Vertically space out multiple block buttons -.btn-block + .btn-block { - margin-top: 5px; -} - -// Specificity overrides -input[type="submit"], -input[type="reset"], -input[type="button"] { - &.btn-block { - width: 100%; - } -} - - - -// Alternate buttons -// -------------------------------------------------- - -// Provide *some* extra contrast for those who can get it -.btn-primary.active, -.btn-warning.active, -.btn-danger.active, -.btn-success.active, -.btn-info.active, -.btn-inverse.active { - color: rgba(255,255,255,.75); -} - -// Set the backgrounds -// ------------------------- -.btn-primary { - @include buttonBackground($btnPrimaryBackground, $btnPrimaryBackgroundHighlight); -} -// Warning appears are orange -.btn-warning { - @include buttonBackground($btnWarningBackground, $btnWarningBackgroundHighlight); -} -// Danger and error appear as red -.btn-danger { - @include buttonBackground($btnDangerBackground, $btnDangerBackgroundHighlight); -} -// Success appears as green -.btn-success { - @include buttonBackground($btnSuccessBackground, $btnSuccessBackgroundHighlight); -} -// Info appears as a neutral blue -.btn-info { - @include buttonBackground($btnInfoBackground, $btnInfoBackgroundHighlight); -} -// Inverse appears as dark gray -.btn-inverse { - @include buttonBackground($btnInverseBackground, $btnInverseBackgroundHighlight); -} - - -// Cross-browser Jank -// -------------------------------------------------- - -button.btn, -input[type="submit"].btn { - - // Firefox 3.6 only I believe - &::-moz-focus-inner { - padding: 0; - border: 0; - } - - // IE7 has some default padding on button controls - *padding-top: 3px; - *padding-bottom: 3px; - - &.btn-large { - *padding-top: 7px; - *padding-bottom: 7px; - } - &.btn-small { - *padding-top: 3px; - *padding-bottom: 3px; - } - &.btn-mini { - *padding-top: 1px; - *padding-bottom: 1px; - } -} - - -// Link buttons -// -------------------------------------------------- - -// Make a button look and behave like a link -.btn-link, -.btn-link:active, -.btn-link[disabled] { - background-color: transparent; - background-image: none; - @include box-shadow(none); -} -.btn-link { - border-color: transparent; - cursor: pointer; - color: $linkColor; - @include border-radius(0); -} -.btn-link:hover, -.btn-link:focus { - color: $linkColorHover; - text-decoration: underline; - background-color: transparent; -} -.btn-link[disabled]:hover, -.btn-link[disabled]:focus { - color: $grayDark; - text-decoration: none; -} diff --git a/vendor/styles/bootstrap/_carousel.scss b/vendor/styles/bootstrap/_carousel.scss deleted file mode 100644 index 22eaddb..0000000 --- a/vendor/styles/bootstrap/_carousel.scss +++ /dev/null @@ -1,158 +0,0 @@ -// -// Carousel -// -------------------------------------------------- - - -.carousel { - position: relative; - margin-bottom: $baseLineHeight; - line-height: 1; -} - -.carousel-inner { - overflow: hidden; - width: 100%; - position: relative; -} - -.carousel-inner { - - > .item { - display: none; - position: relative; - @include transition(.6s ease-in-out left); - - // Account for jankitude on images - > img, - > a > img { - display: block; - line-height: 1; - } - } - - > .active, - > .next, - > .prev { display: block; } - - > .active { - left: 0; - } - - > .next, - > .prev { - position: absolute; - top: 0; - width: 100%; - } - - > .next { - left: 100%; - } - > .prev { - left: -100%; - } - > .next.left, - > .prev.right { - left: 0; - } - - > .active.left { - left: -100%; - } - > .active.right { - left: 100%; - } - -} - -// Left/right controls for nav -// --------------------------- - -.carousel-control { - position: absolute; - top: 40%; - left: 15px; - width: 40px; - height: 40px; - margin-top: -20px; - font-size: 60px; - font-weight: 100; - line-height: 30px; - color: $white; - text-align: center; - background: $grayDarker; - border: 3px solid $white; - @include border-radius(23px); - @include opacity(50); - - // we can't have this transition here - // because webkit cancels the carousel - // animation if you trip this while - // in the middle of another animation - // ;_; - // .transition(opacity .2s linear); - - // Reposition the right one - &.right { - left: auto; - right: 15px; - } - - // Hover/focus state - &:hover, - &:focus { - color: $white; - text-decoration: none; - @include opacity(90); - } -} - -// Carousel indicator pips -// ----------------------------- -.carousel-indicators { - position: absolute; - top: 15px; - right: 15px; - z-index: 5; - margin: 0; - list-style: none; - - li { - display: block; - float: left; - width: 10px; - height: 10px; - margin-left: 5px; - text-indent: -999px; - background-color: #ccc; - background-color: rgba(255,255,255,.25); - border-radius: 5px; - } - .active { - background-color: #fff; - } -} - -// Caption for text below images -// ----------------------------- - -.carousel-caption { - position: absolute; - left: 0; - right: 0; - bottom: 0; - padding: 15px; - background: $grayDark; - background: rgba(0,0,0,.75); -} -.carousel-caption h4, -.carousel-caption p { - color: $white; - line-height: $baseLineHeight; -} -.carousel-caption h4 { - margin: 0 0 5px; -} -.carousel-caption p { - margin-bottom: 0; -} diff --git a/vendor/styles/bootstrap/_close.scss b/vendor/styles/bootstrap/_close.scss deleted file mode 100644 index ee14a6b..0000000 --- a/vendor/styles/bootstrap/_close.scss +++ /dev/null @@ -1,32 +0,0 @@ -// -// Close icons -// -------------------------------------------------- - - -.close { - float: right; - font-size: 20px; - font-weight: bold; - line-height: $baseLineHeight; - color: $black; - text-shadow: 0 1px 0 rgba(255,255,255,1); - @include opacity(20); - &:hover, - &:focus { - color: $black; - text-decoration: none; - cursor: pointer; - @include opacity(40); - } -} - -// Additional properties for button version -// iOS requires the button element instead of an anchor tag. -// If you want the anchor version, it requires `href="#"`. -button.close { - padding: 0; - cursor: pointer; - background: transparent; - border: 0; - -webkit-appearance: none; -} diff --git a/vendor/styles/bootstrap/_code.scss b/vendor/styles/bootstrap/_code.scss deleted file mode 100644 index b9e2f6f..0000000 --- a/vendor/styles/bootstrap/_code.scss +++ /dev/null @@ -1,61 +0,0 @@ -// -// Code (inline and blocK) -// -------------------------------------------------- - - -// Inline and block code styles -code, -pre { - padding: 0 3px 2px; - @include font-family-monospace; - font-size: $baseFontSize - 2; - color: $grayDark; - @include border-radius(3px); -} - -// Inline code -code { - padding: 2px 4px; - color: #d14; - background-color: #f7f7f9; - border: 1px solid #e1e1e8; - white-space: nowrap; -} - -// Blocks of code -pre { - display: block; - padding: ($baseLineHeight - 1) / 2; - margin: 0 0 $baseLineHeight / 2; - font-size: $baseFontSize - 1; // 14px to 13px - line-height: $baseLineHeight; - word-break: break-all; - word-wrap: break-word; - white-space: pre; - white-space: pre-wrap; - background-color: #f5f5f5; - border: 1px solid #ccc; // fallback for IE7-8 - border: 1px solid rgba(0,0,0,.15); - @include border-radius($baseBorderRadius); - - // Make prettyprint styles more spaced out for readability - &.prettyprint { - margin-bottom: $baseLineHeight; - } - - // Account for some code outputs that place code tags in pre tags - code { - padding: 0; - color: inherit; - white-space: pre; - white-space: pre-wrap; - background-color: transparent; - border: 0; - } -} - -// Enable scrollable blocks of code -.pre-scrollable { - max-height: 340px; - overflow-y: scroll; -} diff --git a/vendor/styles/bootstrap/_component-animations.scss b/vendor/styles/bootstrap/_component-animations.scss deleted file mode 100644 index 5ef86b0..0000000 --- a/vendor/styles/bootstrap/_component-animations.scss +++ /dev/null @@ -1,22 +0,0 @@ -// -// Component animations -// -------------------------------------------------- - - -.fade { - opacity: 0; - @include transition(opacity .15s linear); - &.in { - opacity: 1; - } -} - -.collapse { - position: relative; - height: 0; - overflow: hidden; - @include transition(height .35s ease); - &.in { - height: auto; - } -} diff --git a/vendor/styles/bootstrap/_dropdowns.scss b/vendor/styles/bootstrap/_dropdowns.scss deleted file mode 100644 index dbe1cb7..0000000 --- a/vendor/styles/bootstrap/_dropdowns.scss +++ /dev/null @@ -1,237 +0,0 @@ -// -// Dropdown menus -// -------------------------------------------------- - - -// Use the .menu class on any

  • element within the topbar or ul.tabs and you'll get some superfancy dropdowns -.dropup, -.dropdown { - position: relative; -} -.dropdown-toggle { - // The caret makes the toggle a bit too tall in IE7 - *margin-bottom: -3px; -} -.dropdown-toggle:active, -.open .dropdown-toggle { - outline: 0; -} - -// Dropdown arrow/caret -// -------------------- -.caret { - display: inline-block; - width: 0; - height: 0; - vertical-align: top; - border-top: 4px solid $black; - border-right: 4px solid transparent; - border-left: 4px solid transparent; - content: ""; -} - -// Place the caret -.dropdown .caret { - margin-top: 8px; - margin-left: 2px; -} - -// The dropdown menu (ul) -// ---------------------- -.dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: $zindexDropdown; - display: none; // none by default, but block on "open" of the menu - float: left; - min-width: 160px; - padding: 5px 0; - margin: 2px 0 0; // override default ul - list-style: none; - background-color: $dropdownBackground; - border: 1px solid #ccc; // Fallback for IE7-8 - border: 1px solid $dropdownBorder; - *border-right-width: 2px; - *border-bottom-width: 2px; - @include border-radius(6px); - @include box-shadow(0 5px 10px rgba(0,0,0,.2)); - -webkit-background-clip: padding-box; - -moz-background-clip: padding; - background-clip: padding-box; - - // Aligns the dropdown menu to right - &.pull-right { - right: 0; - left: auto; - } - - // Dividers (basically an hr) within the dropdown - .divider { - @include nav-divider($dropdownDividerTop, $dropdownDividerBottom); - } - - // Links within the dropdown menu - > li > a { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: $baseLineHeight; - color: $dropdownLinkColor; - white-space: nowrap; - } -} - -// Hover/Focus state -// ----------- -.dropdown-menu > li > a:hover, -.dropdown-menu > li > a:focus, -.dropdown-submenu:hover > a, -.dropdown-submenu:focus > a { - text-decoration: none; - color: $dropdownLinkColorHover; - @include gradient-vertical($dropdownLinkBackgroundHover, darken($dropdownLinkBackgroundHover, 5%)); -} - -// Active state -// ------------ -.dropdown-menu > .active > a, -.dropdown-menu > .active > a:hover, -.dropdown-menu > .active > a:focus { - color: $dropdownLinkColorActive; - text-decoration: none; - outline: 0; - @include gradient-vertical($dropdownLinkBackgroundActive, darken($dropdownLinkBackgroundActive, 5%)); -} - -// Disabled state -// -------------- -// Gray out text and ensure the hover/focus state remains gray -.dropdown-menu > .disabled > a, -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - color: $grayLight; -} -// Nuke hover/focus effects -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - text-decoration: none; - background-color: transparent; - background-image: none; // Remove CSS gradient - @include reset-filter(); - cursor: default; -} - -// Open state for the dropdown -// --------------------------- -.open { - // IE7's z-index only goes to the nearest positioned ancestor, which would - // make the menu appear below buttons that appeared later on the page - *z-index: $zindexDropdown; - - & > .dropdown-menu { - display: block; - } -} - -// Right aligned dropdowns -// --------------------------- -.pull-right > .dropdown-menu { - right: 0; - left: auto; -} - -// Allow for dropdowns to go bottom up (aka, dropup-menu) -// ------------------------------------------------------ -// Just add .dropup after the standard .dropdown class and you're set, bro. -// TODO: abstract this so that the navbar fixed styles are not placed here? -.dropup, -.navbar-fixed-bottom .dropdown { - // Reverse the caret - .caret { - border-top: 0; - border-bottom: 4px solid $black; - content: ""; - } - // Different positioning for bottom up menu - .dropdown-menu { - top: auto; - bottom: 100%; - margin-bottom: 1px; - } -} - -// Sub menus -// --------------------------- -.dropdown-submenu { - position: relative; -} -// Default dropdowns -.dropdown-submenu > .dropdown-menu { - top: 0; - left: 100%; - margin-top: -6px; - margin-left: -1px; - @include border-radius(0 6px 6px 6px); -} -.dropdown-submenu:hover > .dropdown-menu { - display: block; -} - -// Dropups -.dropup .dropdown-submenu > .dropdown-menu { - top: auto; - bottom: 0; - margin-top: 0; - margin-bottom: -2px; - @include border-radius(5px 5px 5px 0); -} - -// Caret to indicate there is a submenu -.dropdown-submenu > a:after { - display: block; - content: " "; - float: right; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; - border-width: 5px 0 5px 5px; - border-left-color: darken($dropdownBackground, 20%); - margin-top: 5px; - margin-right: -10px; -} -.dropdown-submenu:hover > a:after { - border-left-color: $dropdownLinkColorHover; -} - -// Left aligned submenus -.dropdown-submenu.pull-left { - // Undo the float - // Yes, this is awkward since .pull-left adds a float, but it sticks to our conventions elsewhere. - float: none; - - // Positioning the submenu - > .dropdown-menu { - left: -100%; - margin-left: 10px; - @include border-radius(6px 0 6px 6px); - } -} - -// Tweak nav headers -// ----------------- -// Increase padding from 15px to 20px on sides -.dropdown .dropdown-menu .nav-header { - padding-left: 20px; - padding-right: 20px; -} - -// Typeahead -// --------- -.typeahead { - z-index: 1051; - margin-top: 2px; // give it some space to breathe - @include border-radius($baseBorderRadius); -} diff --git a/vendor/styles/bootstrap/_forms.scss b/vendor/styles/bootstrap/_forms.scss deleted file mode 100644 index 6b05636..0000000 --- a/vendor/styles/bootstrap/_forms.scss +++ /dev/null @@ -1,689 +0,0 @@ -// -// Forms -// -------------------------------------------------- - - -// GENERAL STYLES -// -------------- - -// Make all forms have space below them -form { - margin: 0 0 $baseLineHeight; -} - -fieldset { - padding: 0; - margin: 0; - border: 0; -} - -// Groups of fields with labels on top (legends) -legend { - display: block; - width: 100%; - padding: 0; - margin-bottom: $baseLineHeight; - font-size: $baseFontSize * 1.5; - line-height: $baseLineHeight * 2; - color: $grayDark; - border: 0; - border-bottom: 1px solid #e5e5e5; - - // Small - small { - font-size: $baseLineHeight * .75; - color: $grayLight; - } -} - -// Set font for forms -label, -input, -button, -select, -textarea { - @include font-shorthand($baseFontSize, normal, $baseLineHeight); // Set size, weight, line-height here -} -input, -button, -select, -textarea { - font-family: $baseFontFamily; // And only set font-family here for those that need it (note the missing label element) -} - -// Identify controls by their labels -label { - display: block; - margin-bottom: 5px; -} - -// Form controls -// ------------------------- - -// Shared size and type resets -select, -textarea, -input[type="text"], -input[type="password"], -input[type="datetime"], -input[type="datetime-local"], -input[type="date"], -input[type="month"], -input[type="time"], -input[type="week"], -input[type="number"], -input[type="email"], -input[type="url"], -input[type="search"], -input[type="tel"], -input[type="color"], -.uneditable-input { - display: inline-block; - height: $baseLineHeight; - padding: 4px 6px; - margin-bottom: $baseLineHeight / 2;; - font-size: $baseFontSize; - line-height: $baseLineHeight; - color: $gray; - @include border-radius($inputBorderRadius); - vertical-align: middle; -} - -// Reset appearance properties for textual inputs and textarea -// Declare width for legacy (can't be on input[type=*] selectors or it's too specific) -input, -textarea, -.uneditable-input { - width: 206px; // plus 12px padding and 2px border -} -// Reset height since textareas have rows -textarea { - height: auto; -} -// Everything else -textarea, -input[type="text"], -input[type="password"], -input[type="datetime"], -input[type="datetime-local"], -input[type="date"], -input[type="month"], -input[type="time"], -input[type="week"], -input[type="number"], -input[type="email"], -input[type="url"], -input[type="search"], -input[type="tel"], -input[type="color"], -.uneditable-input { - background-color: $inputBackground; - border: 1px solid $inputBorder; - @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); - @include transition(border linear .2s, box-shadow linear .2s); - - // Focus state - &:focus { - border-color: rgba(82,168,236,.8); - outline: 0; - outline: thin dotted \9; /* IE6-9 */ - @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6)); - } -} - -// Position radios and checkboxes better -input[type="radio"], -input[type="checkbox"] { - margin: 4px 0 0; - *margin-top: 0; /* IE7 */ - margin-top: 1px \9; /* IE8-9 */ - line-height: normal; -} - -// Reset width of input images, buttons, radios, checkboxes -input[type="file"], -input[type="image"], -input[type="submit"], -input[type="reset"], -input[type="button"], -input[type="radio"], -input[type="checkbox"] { - width: auto; // Override of generic input selector -} - -// Set the height of select and file controls to match text inputs -select, -input[type="file"] { - height: $inputHeight; /* In IE7, the height of the select element cannot be changed by height, only font-size */ - *margin-top: 4px; /* For IE7, add top margin to align select with labels */ - line-height: $inputHeight; -} - -// Make select elements obey height by applying a border -select { - width: 220px; // default input width + 10px of padding that doesn't get applied - border: 1px solid $inputBorder; - background-color: $inputBackground; // Chrome on Linux and Mobile Safari need background-color -} - -// Make multiple select elements height not fixed -select[multiple], -select[size] { - height: auto; -} - -// Focus for select, file, radio, and checkbox -select:focus, -input[type="file"]:focus, -input[type="radio"]:focus, -input[type="checkbox"]:focus { - @include tab-focus(); -} - - -// Uneditable inputs -// ------------------------- - -// Make uneditable inputs look inactive -.uneditable-input, -.uneditable-textarea { - color: $grayLight; - background-color: darken($inputBackground, 1%); - border-color: $inputBorder; - @include box-shadow(inset 0 1px 2px rgba(0,0,0,.025)); - cursor: not-allowed; -} - -// For text that needs to appear as an input but should not be an input -.uneditable-input { - overflow: hidden; // prevent text from wrapping, but still cut it off like an input does - white-space: nowrap; -} - -// Make uneditable textareas behave like a textarea -.uneditable-textarea { - width: auto; - height: auto; -} - - -// Placeholder -// ------------------------- - -// Placeholder text gets special styles because when browsers invalidate entire lines if it doesn't understand a selector -input, -textarea { - @include placeholder(); -} - - -// CHECKBOXES & RADIOS -// ------------------- - -// Indent the labels to position radios/checkboxes as hanging -.radio, -.checkbox { - min-height: $baseLineHeight; // clear the floating input if there is no label text - padding-left: 20px; -} -.radio input[type="radio"], -.checkbox input[type="checkbox"] { - float: left; - margin-left: -20px; -} - -// Move the options list down to align with labels -.controls > .radio:first-child, -.controls > .checkbox:first-child { - padding-top: 5px; // has to be padding because margin collaspes -} - -// Radios and checkboxes on same line -// TODO v3: Convert .inline to .control-inline -.radio.inline, -.checkbox.inline { - display: inline-block; - padding-top: 5px; - margin-bottom: 0; - vertical-align: middle; -} -.radio.inline + .radio.inline, -.checkbox.inline + .checkbox.inline { - margin-left: 10px; // space out consecutive inline controls -} - - - -// INPUT SIZES -// ----------- - -// General classes for quick sizes -.input-mini { width: 60px; } -.input-small { width: 90px; } -.input-medium { width: 150px; } -.input-large { width: 210px; } -.input-xlarge { width: 270px; } -.input-xxlarge { width: 530px; } - -// Grid style input sizes -input[class*="span"], -select[class*="span"], -textarea[class*="span"], -.uneditable-input[class*="span"], -// Redeclare since the fluid row class is more specific -.row-fluid input[class*="span"], -.row-fluid select[class*="span"], -.row-fluid textarea[class*="span"], -.row-fluid .uneditable-input[class*="span"] { - float: none; - margin-left: 0; -} -// Ensure input-prepend/append never wraps -.input-append input[class*="span"], -.input-append .uneditable-input[class*="span"], -.input-prepend input[class*="span"], -.input-prepend .uneditable-input[class*="span"], -.row-fluid input[class*="span"], -.row-fluid select[class*="span"], -.row-fluid textarea[class*="span"], -.row-fluid .uneditable-input[class*="span"], -.row-fluid .input-prepend [class*="span"], -.row-fluid .input-append [class*="span"] { - display: inline-block; -} - - - -// GRID SIZING FOR INPUTS -// ---------------------- - -// Grid sizes -@include grid-input($gridColumnWidth, $gridGutterWidth); - -// Control row for multiple inputs per line -.controls-row { - @include clearfix(); // Clear the float from controls -} - -// Float to collapse white-space for proper grid alignment -.controls-row [class*="span"], -// Redeclare the fluid grid collapse since we undo the float for inputs -.row-fluid .controls-row [class*="span"] { - float: left; -} -// Explicity set top padding on all checkboxes/radios, not just first-child -.controls-row .checkbox[class*="span"], -.controls-row .radio[class*="span"] { - padding-top: 5px; -} - - - - -// DISABLED STATE -// -------------- - -// Disabled and read-only inputs -input[disabled], -select[disabled], -textarea[disabled], -input[readonly], -select[readonly], -textarea[readonly] { - cursor: not-allowed; - background-color: $inputDisabledBackground; -} -// Explicitly reset the colors here -input[type="radio"][disabled], -input[type="checkbox"][disabled], -input[type="radio"][readonly], -input[type="checkbox"][readonly] { - background-color: transparent; -} - - - - -// FORM FIELD FEEDBACK STATES -// -------------------------- - -// Warning -.control-group.warning { - @include formFieldState($warningText, $warningText, $warningBackground); -} -// Error -.control-group.error { - @include formFieldState($errorText, $errorText, $errorBackground); -} -// Success -.control-group.success { - @include formFieldState($successText, $successText, $successBackground); -} -// Info -.control-group.info { - @include formFieldState($infoText, $infoText, $infoBackground); -} - -// HTML5 invalid states -// Shares styles with the .control-group.error above -input:focus:invalid, -textarea:focus:invalid, -select:focus:invalid { - color: #b94a48; - border-color: #ee5f5b; - &:focus { - border-color: darken(#ee5f5b, 10%); - @include box-shadow(0 0 6px lighten(#ee5f5b, 20%)); - } -} - - - -// FORM ACTIONS -// ------------ - -.form-actions { - padding: ($baseLineHeight - 1) 20px $baseLineHeight; - margin-top: $baseLineHeight; - margin-bottom: $baseLineHeight; - background-color: $formActionsBackground; - border-top: 1px solid #e5e5e5; - @include clearfix(); // Adding clearfix to allow for .pull-right button containers -} - - - -// HELP TEXT -// --------- - -.help-block, -.help-inline { - color: lighten($textColor, 15%); // lighten the text some for contrast -} - -.help-block { - display: block; // account for any element using help-block - margin-bottom: $baseLineHeight / 2; -} - -.help-inline { - display: inline-block; - @include ie7-inline-block(); - vertical-align: middle; - padding-left: 5px; -} - - - -// INPUT GROUPS -// ------------ - -// Allow us to put symbols and text within the input field for a cleaner look -.input-append, -.input-prepend { - display: inline-block; - margin-bottom: $baseLineHeight / 2; - vertical-align: middle; - font-size: 0; // white space collapse hack - white-space: nowrap; // Prevent span and input from separating - - // Reset the white space collapse hack - input, - select, - .uneditable-input, - .dropdown-menu, - .popover { - font-size: $baseFontSize; - } - - input, - select, - .uneditable-input { - position: relative; // placed here by default so that on :focus we can place the input above the .add-on for full border and box-shadow goodness - margin-bottom: 0; // prevent bottom margin from screwing up alignment in stacked forms - *margin-left: 0; - vertical-align: top; - @include border-radius(0 $inputBorderRadius $inputBorderRadius 0); - // Make input on top when focused so blue border and shadow always show - &:focus { - z-index: 2; - } - } - .add-on { - display: inline-block; - width: auto; - height: $baseLineHeight; - min-width: 16px; - padding: 4px 5px; - font-size: $baseFontSize; - font-weight: normal; - line-height: $baseLineHeight; - text-align: center; - text-shadow: 0 1px 0 $white; - background-color: $grayLighter; - border: 1px solid #ccc; - } - .add-on, - .btn, - .btn-group > .dropdown-toggle { - vertical-align: top; - @include border-radius(0); - } - .active { - background-color: lighten($green, 30); - border-color: $green; - } -} - -.input-prepend { - .add-on, - .btn { - margin-right: -1px; - } - .add-on:first-child, - .btn:first-child { - // FYI, `.btn:first-child` accounts for a button group that's prepended - @include border-radius($inputBorderRadius 0 0 $inputBorderRadius); - } -} - -.input-append { - input, - select, - .uneditable-input { - @include border-radius($inputBorderRadius 0 0 $inputBorderRadius); - + .btn-group .btn:last-child { - @include border-radius(0 $inputBorderRadius $inputBorderRadius 0); - } - } - .add-on, - .btn, - .btn-group { - margin-left: -1px; - } - .add-on:last-child, - .btn:last-child, - .btn-group:last-child > .dropdown-toggle { - @include border-radius(0 $inputBorderRadius $inputBorderRadius 0); - } -} - -// Remove all border-radius for inputs with both prepend and append -.input-prepend.input-append { - input, - select, - .uneditable-input { - @include border-radius(0); - + .btn-group .btn { - @include border-radius(0 $inputBorderRadius $inputBorderRadius 0); - } - } - .add-on:first-child, - .btn:first-child { - margin-right: -1px; - @include border-radius($inputBorderRadius 0 0 $inputBorderRadius); - } - .add-on:last-child, - .btn:last-child { - margin-left: -1px; - @include border-radius(0 $inputBorderRadius $inputBorderRadius 0); - } - .btn-group:first-child { - margin-left: 0; - } -} - - - - -// SEARCH FORM -// ----------- - -input.search-query { - padding-right: 14px; - padding-right: 4px \9; - padding-left: 14px; - padding-left: 4px \9; /* IE7-8 doesn't have border-radius, so don't indent the padding */ - margin-bottom: 0; // Remove the default margin on all inputs - @include border-radius(15px); -} - -/* Allow for input prepend/append in search forms */ -.form-search .input-append .search-query, -.form-search .input-prepend .search-query { - @include border-radius(0); // Override due to specificity -} -.form-search .input-append .search-query { - @include border-radius(14px 0 0 14px); -} -.form-search .input-append .btn { - @include border-radius(0 14px 14px 0); -} -.form-search .input-prepend .search-query { - @include border-radius(0 14px 14px 0); -} -.form-search .input-prepend .btn { - @include border-radius(14px 0 0 14px); -} - - - - -// HORIZONTAL & VERTICAL FORMS -// --------------------------- - -// Common properties -// ----------------- - -.form-search, -.form-inline, -.form-horizontal { - input, - textarea, - select, - .help-inline, - .uneditable-input, - .input-prepend, - .input-append { - display: inline-block; - @include ie7-inline-block(); - margin-bottom: 0; - vertical-align: middle; - } - // Re-hide hidden elements due to specifity - .hide { - display: none; - } -} -.form-search label, -.form-inline label, -.form-search .btn-group, -.form-inline .btn-group { - display: inline-block; -} -// Remove margin for input-prepend/-append -.form-search .input-append, -.form-inline .input-append, -.form-search .input-prepend, -.form-inline .input-prepend { - margin-bottom: 0; -} -// Inline checkbox/radio labels (remove padding on left) -.form-search .radio, -.form-search .checkbox, -.form-inline .radio, -.form-inline .checkbox { - padding-left: 0; - margin-bottom: 0; - vertical-align: middle; -} -// Remove float and margin, set to inline-block -.form-search .radio input[type="radio"], -.form-search .checkbox input[type="checkbox"], -.form-inline .radio input[type="radio"], -.form-inline .checkbox input[type="checkbox"] { - float: left; - margin-right: 3px; - margin-left: 0; -} - - -// Margin to space out fieldsets -.control-group { - margin-bottom: $baseLineHeight / 2; -} - -// Legend collapses margin, so next element is responsible for spacing -legend + .control-group { - margin-top: $baseLineHeight; - -webkit-margin-top-collapse: separate; -} - -// Horizontal-specific styles -// -------------------------- - -.form-horizontal { - // Increase spacing between groups - .control-group { - margin-bottom: $baseLineHeight; - @include clearfix(); - } - // Float the labels left - .control-label { - float: left; - width: $horizontalComponentOffset - 20; - padding-top: 5px; - text-align: right; - } - // Move over all input controls and content - .controls { - // Super jank IE7 fix to ensure the inputs in .input-append and input-prepend - // don't inherit the margin of the parent, in this case .controls - *display: inline-block; - *padding-left: 20px; - margin-left: $horizontalComponentOffset; - *margin-left: 0; - &:first-child { - *padding-left: $horizontalComponentOffset; - } - } - // Remove bottom margin on block level help text since that's accounted for on .control-group - .help-block { - margin-bottom: 0; - } - // And apply it only to .help-block instances that follow a form control - input, - select, - textarea, - .uneditable-input, - .input-prepend, - .input-append { - + .help-block { - margin-top: $baseLineHeight / 2; - } - } - // Move over buttons in .form-actions to align with .controls - .form-actions { - padding-left: $horizontalComponentOffset; - } -} diff --git a/vendor/styles/bootstrap/_grid.scss b/vendor/styles/bootstrap/_grid.scss deleted file mode 100644 index f2b910a..0000000 --- a/vendor/styles/bootstrap/_grid.scss +++ /dev/null @@ -1,21 +0,0 @@ -// -// Grid system -// -------------------------------------------------- - - -// Fixed (940px) -@include grid-core($gridColumnWidth, $gridGutterWidth); - -// Fluid (940px) -@include grid-fluid($fluidGridColumnWidth, $fluidGridGutterWidth); - -// Reset utility classes due to specificity -[class*="span"].hide, -.row-fluid [class*="span"].hide { - display: none; -} - -[class*="span"].pull-right, -.row-fluid [class*="span"].pull-right { - float: right; -} diff --git a/vendor/styles/bootstrap/_hero-unit.scss b/vendor/styles/bootstrap/_hero-unit.scss deleted file mode 100644 index 274527e..0000000 --- a/vendor/styles/bootstrap/_hero-unit.scss +++ /dev/null @@ -1,25 +0,0 @@ -// -// Hero unit -// -------------------------------------------------- - - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: $baseLineHeight * 1.5; - color: $heroUnitLeadColor; - background-color: $heroUnitBackground; - @include border-radius(6px); - h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - color: $heroUnitHeadingColor; - letter-spacing: -1px; - } - li { - line-height: $baseLineHeight * 1.5; // Reset since we specify in type.scss - } -} diff --git a/vendor/styles/bootstrap/_labels-badges.scss b/vendor/styles/bootstrap/_labels-badges.scss deleted file mode 100644 index 8f17e58..0000000 --- a/vendor/styles/bootstrap/_labels-badges.scss +++ /dev/null @@ -1,83 +0,0 @@ -// -// Labels and badges -// -------------------------------------------------- - - -// Base classes -.label, -.badge { - display: inline-block; - padding: 2px 4px; - font-size: $baseFontSize * .846; - font-weight: bold; - line-height: 14px; // ensure proper line-height if floated - color: $white; - vertical-align: baseline; - white-space: nowrap; - text-shadow: 0 -1px 0 rgba(0,0,0,.25); - background-color: $grayLight; -} -// Set unique padding and border-radii -.label { - @include border-radius(3px); -} -.badge { - padding-left: 9px; - padding-right: 9px; - @include border-radius(9px); -} - -// Empty labels/badges collapse -.label, -.badge { - &:empty { - display: none; - } -} - -// Hover/focus state, but only for links -a { - &.label:hover, - &.label:focus, - &.badge:hover, - &.badge:focus { - color: $white; - text-decoration: none; - cursor: pointer; - } -} - -// Colors -// Only give background-color difference to links (and to simplify, we don't qualifty with `a` but [href] attribute) -@each $item in label, badge { - // Important (red) - .#{$item}-important { background-color: $errorText; } - .#{$item}-important[href] { background-color: darken($errorText, 10%); } - // Warnings (orange) - .#{$item}-warning { background-color: $orange; } - .#{$item}-warning[href] { background-color: darken($orange, 10%); } - // Success (green) - .#{$item}-success { background-color: $successText; } - .#{$item}-success[href] { background-color: darken($successText, 10%); } - // Info (turquoise) - .#{$item}-info { background-color: $infoText; } - .#{$item}-info[href] { background-color: darken($infoText, 10%); } - // Inverse (black) - .#{$item}-inverse { background-color: $grayDark; } - .#{$item}-inverse[href] { background-color: darken($grayDark, 10%); } -} - -// Quick fix for labels/badges in buttons -.btn { - .label, - .badge { - position: relative; - top: -1px; - } -} -.btn-mini { - .label, - .badge { - top: 0; - } -} diff --git a/vendor/styles/bootstrap/_layouts.scss b/vendor/styles/bootstrap/_layouts.scss deleted file mode 100644 index 5ea4d00..0000000 --- a/vendor/styles/bootstrap/_layouts.scss +++ /dev/null @@ -1,16 +0,0 @@ -// -// Layouts -// -------------------------------------------------- - - -// Container (centered, fixed-width layouts) -.container { - @include container-fixed(); -} - -// Fluid layouts (left aligned, with sidebar, min- & max-width content) -.container-fluid { - padding-right: $gridGutterWidth; - padding-left: $gridGutterWidth; - @include clearfix(); -} diff --git a/vendor/styles/bootstrap/_media.scss b/vendor/styles/bootstrap/_media.scss deleted file mode 100644 index e461e44..0000000 --- a/vendor/styles/bootstrap/_media.scss +++ /dev/null @@ -1,55 +0,0 @@ -// Media objects -// Source: http://stubbornella.org/content/?p=497 -// -------------------------------------------------- - - -// Common styles -// ------------------------- - -// Clear the floats -.media, -.media-body { - overflow: hidden; - *overflow: visible; - zoom: 1; -} - -// Proper spacing between instances of .media -.media, -.media .media { - margin-top: 15px; -} -.media:first-child { - margin-top: 0; -} - -// For images and videos, set to block -.media-object { - display: block; -} - -// Reset margins on headings for tighter default spacing -.media-heading { - margin: 0 0 5px; -} - - -// Media image alignment -// ------------------------- - -.media > .pull-left { - margin-right: 10px; -} -.media > .pull-right { - margin-left: 10px; -} - - -// Media list variation -// ------------------------- - -// Undo default ul/ol styles -.media-list { - margin-left: 0; - list-style: none; -} diff --git a/vendor/styles/bootstrap/_mixins.scss b/vendor/styles/bootstrap/_mixins.scss deleted file mode 100644 index a3ccb1d..0000000 --- a/vendor/styles/bootstrap/_mixins.scss +++ /dev/null @@ -1,690 +0,0 @@ -// -// Mixins -// -------------------------------------------------- - - -// UTILITY MIXINS -// -------------------------------------------------- - -// Clearfix -// -------- -// For clearing floats like a boss h5bp.com/q -@mixin clearfix { - *zoom: 1; - &:before, - &:after { - display: table; - content: ""; - // Fixes Opera/contenteditable bug: - // http://nicolasgallagher.com/micro-clearfix-hack/#comment-36952 - line-height: 0; - } - &:after { - clear: both; - } -} - -// Webkit-style focus -// ------------------ -@mixin tab-focus() { - // Default - outline: thin dotted #333; - // Webkit - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -// Center-align a block level element -// ---------------------------------- -@mixin center-block() { - display: block; - margin-left: auto; - margin-right: auto; -} - -// IE7 inline-block -// ---------------- -@mixin ie7-inline-block() { - *display: inline; /* IE7 inline-block hack */ - *zoom: 1; -} - -// IE7 likes to collapse whitespace on either side of the inline-block elements. -// Ems because we're attempting to match the width of a space character. Left -// version is for form buttons, which typically come after other elements, and -// right version is for icons, which come before. Applying both is ok, but it will -// mean that space between those elements will be .6em (~2 space characters) in IE7, -// instead of the 1 space in other browsers. -@mixin ie7-restore-left-whitespace() { - *margin-left: .3em; - - &:first-child { - *margin-left: 0; - } -} - -@mixin ie7-restore-right-whitespace() { - *margin-right: .3em; -} - -// Sizing shortcuts -// ------------------------- -@mixin size($height, $width) { - width: $width; - height: $height; -} -@mixin square($size) { - @include size($size, $size); -} - -// Placeholder text -// ------------------------- -@mixin placeholder($color: $placeholderText) { - &:-moz-placeholder { - color: $color; - } - &:-ms-input-placeholder { - color: $color; - } - &::-webkit-input-placeholder { - color: $color; - } -} - -// Text overflow -// ------------------------- -// Requires inline-block or block for proper styling -@mixin text-overflow() { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -// CSS image replacement -// ------------------------- -// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757 -@mixin hide-text { - font: 0/0 a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; -} - - -// FONTS -// -------------------------------------------------- - -@mixin font-family-serif() { - font-family: $serifFontFamily; -} -@mixin font-family-sans-serif() { - font-family: $sansFontFamily; -} -@mixin font-family-monospace() { - font-family: $monoFontFamily; -} -@mixin font-shorthand($size: $baseFontSize, $weight: normal, $lineHeight: $baseLineHeight) { - font-size: $size; - font-weight: $weight; - line-height: $lineHeight; -} -@mixin font-serif($size: $baseFontSize, $weight: normal, $lineHeight: $baseLineHeight) { - @include font-family-serif(); - @include font-shorthand($size, $weight, $lineHeight); -} -@mixin font-sans-serif($size: $baseFontSize, $weight: normal, $lineHeight: $baseLineHeight) { - @include font-family-sans-serif(); - @include font-shorthand($size, $weight, $lineHeight); -} -@mixin font-monospace($size: $baseFontSize, $weight: normal, $lineHeight: $baseLineHeight) { - @include font-family-monospace(); - @include font-shorthand($size, $weight, $lineHeight); -} - - -// FORMS -// -------------------------------------------------- - -// Block level inputs -@mixin input-block-level { - display: block; - width: 100%; - min-height: $inputHeight; // Make inputs at least the height of their button counterpart (base line-height + padding + border) - @include box-sizing(border-box); // Makes inputs behave like true block-level elements -} - - - -// Mixin for form field states -@mixin formFieldState($textColor: #555, $borderColor: #ccc, $backgroundColor: #f5f5f5) { - // Set the text color - .control-label, - .help-block, - .help-inline { - color: $textColor; - } - // Style inputs accordingly - .checkbox, - .radio, - input, - select, - textarea { - color: $textColor; - } - input, - select, - textarea { - border-color: $borderColor; - @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work - &:focus { - border-color: darken($borderColor, 10%); - @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten($borderColor, 20%)); - } - } - // Give a small background color for input-prepend/-append - .input-prepend .add-on, - .input-append .add-on { - color: $textColor; - background-color: $backgroundColor; - border-color: $textColor; - } -} - - - -// CSS3 PROPERTIES -// -------------------------------------------------- - -// Border Radius -@mixin border-radius($radius) { - -webkit-border-radius: $radius; - -moz-border-radius: $radius; - border-radius: $radius; -} - -// Single Corner Border Radius -@mixin border-top-left-radius($radius) { - -webkit-border-top-left-radius: $radius; - -moz-border-radius-topleft: $radius; - border-top-left-radius: $radius; -} -@mixin border-top-right-radius($radius) { - -webkit-border-top-right-radius: $radius; - -moz-border-radius-topright: $radius; - border-top-right-radius: $radius; -} -@mixin border-bottom-right-radius($radius) { - -webkit-border-bottom-right-radius: $radius; - -moz-border-radius-bottomright: $radius; - border-bottom-right-radius: $radius; -} -@mixin border-bottom-left-radius($radius) { - -webkit-border-bottom-left-radius: $radius; - -moz-border-radius-bottomleft: $radius; - border-bottom-left-radius: $radius; -} - -// Single Side Border Radius -@mixin border-top-radius($radius) { - @include border-top-right-radius($radius); - @include border-top-left-radius($radius); -} -@mixin border-right-radius($radius) { - @include border-top-right-radius($radius); - @include border-bottom-right-radius($radius); -} -@mixin border-bottom-radius($radius) { - @include border-bottom-right-radius($radius); - @include border-bottom-left-radius($radius); -} -@mixin border-left-radius($radius) { - @include border-top-left-radius($radius); - @include border-bottom-left-radius($radius); -} - -// Drop shadows -@mixin box-shadow($shadow...) { - -webkit-box-shadow: $shadow; - -moz-box-shadow: $shadow; - box-shadow: $shadow; -} - -// Transitions -@mixin transition($transition...) { - -webkit-transition: $transition; - -moz-transition: $transition; - -o-transition: $transition; - transition: $transition; -} -@mixin transition-delay($transition-delay) { - -webkit-transition-delay: $transition-delay; - -moz-transition-delay: $transition-delay; - -o-transition-delay: $transition-delay; - transition-delay: $transition-delay; -} -@mixin transition-duration($transition-duration) { - -webkit-transition-duration: $transition-duration; - -moz-transition-duration: $transition-duration; - -o-transition-duration: $transition-duration; - transition-duration: $transition-duration; -} - -// Transformations -@mixin rotate($degrees) { - -webkit-transform: rotate($degrees); - -moz-transform: rotate($degrees); - -ms-transform: rotate($degrees); - -o-transform: rotate($degrees); - transform: rotate($degrees); -} -@mixin scale($ratio) { - -webkit-transform: scale($ratio); - -moz-transform: scale($ratio); - -ms-transform: scale($ratio); - -o-transform: scale($ratio); - transform: scale($ratio); -} -@mixin translate($x, $y) { - -webkit-transform: translate($x, $y); - -moz-transform: translate($x, $y); - -ms-transform: translate($x, $y); - -o-transform: translate($x, $y); - transform: translate($x, $y); -} -@mixin skew($x, $y) { - -webkit-transform: skew($x, $y); - -moz-transform: skew($x, $y); - -ms-transform: skewX($x) skewY($y); // See https://github.com/twitter/bootstrap/issues/4885 - -o-transform: skew($x, $y); - transform: skew($x, $y); - -webkit-backface-visibility: hidden; // See https://github.com/twitter/bootstrap/issues/5319 -} -@mixin translate3d($x, $y, $z) { - -webkit-transform: translate3d($x, $y, $z); - -moz-transform: translate3d($x, $y, $z); - -o-transform: translate3d($x, $y, $z); - transform: translate3d($x, $y, $z); -} - -// Backface visibility -// Prevent browsers from flickering when using CSS 3D transforms. -// Default value is `visible`, but can be changed to `hidden -// See git pull https://github.com/dannykeane/bootstrap.git backface-visibility for examples -@mixin backface-visibility($visibility){ - -webkit-backface-visibility: $visibility; - -moz-backface-visibility: $visibility; - backface-visibility: $visibility; -} - -// Background clipping -// Heads up: FF 3.6 and under need "padding" instead of "padding-box" -@mixin background-clip($clip) { - -webkit-background-clip: $clip; - -moz-background-clip: $clip; - background-clip: $clip; -} - -// Background sizing -@mixin background-size($size) { - -webkit-background-size: $size; - -moz-background-size: $size; - -o-background-size: $size; - background-size: $size; -} - - -// Box sizing -@mixin box-sizing($boxmodel) { - -webkit-box-sizing: $boxmodel; - -moz-box-sizing: $boxmodel; - box-sizing: $boxmodel; -} - -// User select -// For selecting text on the page -@mixin user-select($select) { - -webkit-user-select: $select; - -moz-user-select: $select; - -ms-user-select: $select; - -o-user-select: $select; - user-select: $select; -} - -// Resize anything -@mixin resizable($direction) { - resize: $direction; // Options: horizontal, vertical, both - overflow: auto; // Safari fix -} - -// CSS3 Content Columns -@mixin content-columns($columnCount, $columnGap: $gridGutterWidth) { - -webkit-column-count: $columnCount; - -moz-column-count: $columnCount; - column-count: $columnCount; - -webkit-column-gap: $columnGap; - -moz-column-gap: $columnGap; - column-gap: $columnGap; -} - -// Optional hyphenation -@mixin hyphens($mode: auto) { - word-wrap: break-word; - -webkit-hyphens: $mode; - -moz-hyphens: $mode; - -ms-hyphens: $mode; - -o-hyphens: $mode; - hyphens: $mode; -} - -// Opacity -@mixin opacity($opacity) { - opacity: $opacity / 100; - filter: alpha(opacity=$opacity); -} - - - -// BACKGROUNDS -// -------------------------------------------------- - -// Add an alphatransparency value to any background or border color (via Elyse Holladay) -@mixin translucent-background($color: $white, $alpha: 1) { - background-color: hsla(hue($color), saturation($color), lightness($color), $alpha); -} - -@mixin translucent-border($color: $white, $alpha: 1) { - border-color: hsla(hue($color), saturation($color), lightness($color), $alpha); - @include background-clip(padding-box); -} - -// Gradient Bar Colors for buttons and alerts -@mixin gradientBar($primaryColor, $secondaryColor, $textColor: #fff, $textShadow: 0 -1px 0 rgba(0,0,0,.25)) { - color: $textColor; - text-shadow: $textShadow; - @include gradient-vertical($primaryColor, $secondaryColor); - border-color: $secondaryColor $secondaryColor darken($secondaryColor, 15%); - border-color: rgba(0,0,0,.1) rgba(0,0,0,.1) fade-in(rgba(0,0,0,.1), 0.15); -} - -// Gradients -@mixin gradient-horizontal($startColor: #555, $endColor: #333) { - background-color: $endColor; - background-image: -moz-linear-gradient(left, $startColor, $endColor); // FF 3.6+ - background-image: -webkit-gradient(linear, 0 0, 100% 0, from($startColor), to($endColor)); // Safari 4+, Chrome 2+ - background-image: -webkit-linear-gradient(left, $startColor, $endColor); // Safari 5.1+, Chrome 10+ - background-image: -o-linear-gradient(left, $startColor, $endColor); // Opera 11.10 - background-image: linear-gradient(to right, $startColor, $endColor); // Standard, IE10 - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($startColor)}', endColorstr='#{ie-hex-str($endColor)}', GradientType=1); // IE9 and down -} -@mixin gradient-vertical($startColor: #555, $endColor: #333) { - background-color: mix($startColor, $endColor, 60%); - background-image: -moz-linear-gradient(top, $startColor, $endColor); // FF 3.6+ - background-image: -webkit-gradient(linear, 0 0, 0 100%, from($startColor), to($endColor)); // Safari 4+, Chrome 2+ - background-image: -webkit-linear-gradient(top, $startColor, $endColor); // Safari 5.1+, Chrome 10+ - background-image: -o-linear-gradient(top, $startColor, $endColor); // Opera 11.10 - background-image: linear-gradient(to bottom, $startColor, $endColor); // Standard, IE10 - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($startColor)}', endColorstr='#{ie-hex-str($endColor)}', GradientType=0); // IE9 and down -} -@mixin gradient-directional($startColor: #555, $endColor: #333, $deg: 45deg) { - background-color: $endColor; - background-repeat: repeat-x; - background-image: -moz-linear-gradient($deg, $startColor, $endColor); // FF 3.6+ - background-image: -webkit-linear-gradient($deg, $startColor, $endColor); // Safari 5.1+, Chrome 10+ - background-image: -o-linear-gradient($deg, $startColor, $endColor); // Opera 11.10 - background-image: linear-gradient($deg, $startColor, $endColor); // Standard, IE10 -} -@mixin gradient-vertical-three-colors($startColor: #00b3ee, $midColor: #7a43b6, $colorStop: 50%, $endColor: #c3325f) { - background-color: mix($midColor, $endColor, 80%); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from($startColor), color-stop($colorStop, $midColor), to($endColor)); - background-image: -webkit-linear-gradient($startColor, $midColor $colorStop, $endColor); - background-image: -moz-linear-gradient(top, $startColor, $midColor $colorStop, $endColor); - background-image: -o-linear-gradient($startColor, $midColor $colorStop, $endColor); - background-image: linear-gradient($startColor, $midColor $colorStop, $endColor); - background-repeat: no-repeat; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($startColor)}', endColorstr='#{ie-hex-str($endColor)}', GradientType=0); // IE9 and down, gets no color-stop at all for proper fallback -} -@mixin gradient-radial($innerColor: #555, $outerColor: #333) { - background-color: $outerColor; - background-image: -webkit-gradient(radial, center center, 0, center center, 460, from($innerColor), to($outerColor)); - background-image: -webkit-radial-gradient(circle, $innerColor, $outerColor); - background-image: -moz-radial-gradient(circle, $innerColor, $outerColor); - background-image: -o-radial-gradient(circle, $innerColor, $outerColor); - background-repeat: no-repeat; -} -@mixin gradient-striped($color: #555, $angle: 45deg) { - background-color: $color; - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,.15)), color-stop(.75, rgba(255,255,255,.15)), color-stop(.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient($angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient($angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient($angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); - background-image: linear-gradient($angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); -} - -// Reset filters for IE -@mixin reset-filter() { - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -} - - - -// COMPONENT MIXINS -// -------------------------------------------------- - -// Horizontal dividers -// ------------------------- -// Dividers (basically an hr) within dropdowns and nav lists -@mixin nav-divider($top: #e5e5e5, $bottom: $white) { - // IE7 needs a set width since we gave a height. Restricting just - // to IE7 to keep the 1px left/right space in other browsers. - // It is unclear where IE is getting the extra space that we need - // to negative-margin away, but so it goes. - *width: 100%; - height: 1px; - margin: (($baseLineHeight / 2) - 1) 1px; // 8px 1px - *margin: -5px 0 5px; - overflow: hidden; - background-color: $top; - border-bottom: 1px solid $bottom; -} - -// Button backgrounds -// ------------------ -@mixin buttonBackground($startColor, $endColor, $textColor: #fff, $textShadow: 0 -1px 0 rgba(0,0,0,.25)) { - // gradientBar will set the background to a pleasing blend of these, to support IE<=9 - @include gradientBar($startColor, $endColor, $textColor, $textShadow); - *background-color: $endColor; /* Darken IE7 buttons by default so they stand out more given they won't have borders */ - @include reset-filter(); - - // in these cases the gradient won't cover the background, so we override - &:hover, &:active, &.active, &.disabled, &[disabled] { - color: $textColor; - background-color: $endColor; - *background-color: darken($endColor, 5%); - } - - // IE 7 + 8 can't handle box-shadow to show active, so we darken a bit ourselves - &:active, - &.active { - background-color: darken($endColor, 10%) \9; - } -} - -// Navbar vertical align -// ------------------------- -// Vertically center elements in the navbar. -// Example: an element has a height of 30px, so write out `.navbarVerticalAlign(30px);` to calculate the appropriate top margin. -@mixin navbarVerticalAlign($elementHeight) { - margin-top: ($navbarHeight - $elementHeight) / 2; -} - - - -// Grid System -// ----------- - -// Centered container element -@mixin container-fixed() { - margin-right: auto; - margin-left: auto; - @include clearfix(); -} - -// Table columns -@mixin tableColumns($columnSpan: 1) { - float: none; // undo default grid column styles - width: (($gridColumnWidth) * $columnSpan) + ($gridGutterWidth * ($columnSpan - 1)) - 16; // 16 is total padding on left and right of table cells - margin-left: 0; // undo default grid column styles -} - -// Make a Grid -// Use .makeRow and .makeColumn to assign semantic layouts grid system behavior -@mixin makeRow() { - margin-left: $gridGutterWidth * -1; - @include clearfix(); -} -@mixin makeColumn($columns: 1, $offset: 0) { - float: left; - margin-left: ($gridColumnWidth * $offset) + ($gridGutterWidth * ($offset - 1)) + ($gridGutterWidth * 2); - width: ($gridColumnWidth * $columns) + ($gridGutterWidth * ($columns - 1)); -} - -// The Grid -@mixin grid-core($gridColumnWidth, $gridGutterWidth) { - .row { - margin-left: $gridGutterWidth * -1; - @include clearfix(); - } - - [class*="span"] { - float: left; - min-height: 1px; // prevent collapsing columns - margin-left: $gridGutterWidth; - } - - // Set the container width, and override it for fixed navbars in media queries - .container, - .navbar-static-top .container, - .navbar-fixed-top .container, - .navbar-fixed-bottom .container { - @include grid-core-span($gridColumns, $gridColumnWidth, $gridGutterWidth); - } - - // generate .spanX and .offsetX - @include grid-core-span-x($gridColumns, $gridColumnWidth, $gridGutterWidth); - @include grid-core-offset-x($gridColumns, $gridColumnWidth, $gridGutterWidth); -} - -@mixin grid-core-span-x($gridColumns, $gridColumnWidth, $gridGutterWidth) { - @while $gridColumns > 0 { - .span#{$gridColumns} { @include grid-core-span($gridColumns, $gridColumnWidth, $gridGutterWidth)} - $gridColumns: $gridColumns - 1; - } -} - -@mixin grid-core-offset-x($gridColumns, $gridColumnWidth, $gridGutterWidth) { - @while $gridColumns > 0 { - .offset#{$gridColumns} { @include grid-core-offset($gridColumns, $gridColumnWidth, $gridGutterWidth); } - $gridColumns: $gridColumns - 1; - } -} - -@mixin grid-core-span($columns, $gridColumnWidth, $gridGutterWidth) { - width: ($gridColumnWidth * $columns) + ($gridGutterWidth * ($columns - 1)); -} - -@mixin grid-core-offset($columns, $gridColumnWidth, $gridGutterWidth) { - margin-left: ($gridColumnWidth * $columns) + ($gridGutterWidth * ($columns + 1)); -} - - - -@mixin grid-fluid($fluidGridColumnWidth, $fluidGridGutterWidth) { - .row-fluid { - width: 100%; - @include clearfix(); - [class*="span"] { - @include input-block-level(); - float: left; - margin-left: $fluidGridGutterWidth; - *margin-left: $fluidGridGutterWidth - (.5 / $gridRowWidth * 100px * 1%); - } - [class*="span"]:first-child { - margin-left: 0; - } - - // Space grid-sized controls properly if multiple per line - .controls-row [class*="span"] + [class*="span"] { - margin-left: $fluidGridGutterWidth; - } - - // generate .spanX and .offsetX - @include grid-fluid-span-x($gridColumns, $fluidGridColumnWidth, $fluidGridGutterWidth); - @include grid-fluid-offset-x($gridColumns, $fluidGridColumnWidth, $fluidGridGutterWidth); - } -} - -@mixin grid-fluid-span-x($gridColumns, $fluidGridColumnWidth, $fluidGridGutterWidth) { - @while $gridColumns > 0 { - .span#{$gridColumns} { @include grid-fluid-span($gridColumns, $fluidGridColumnWidth, $fluidGridGutterWidth); } - $gridColumns: $gridColumns - 1; - } -} - -@mixin grid-fluid-offset-x($gridColumns, $fluidGridColumnWidth, $fluidGridGutterWidth) { - @while $gridColumns > 0 { - .offset#{$gridColumns} { @include grid-fluid-offset($gridColumns, $fluidGridColumnWidth, $fluidGridGutterWidth); } - .offset#{$gridColumns}:first-child { @include grid-fluid-offset-first-child($gridColumns, $fluidGridColumnWidth, $fluidGridGutterWidth); } - $gridColumns: $gridColumns - 1; - } -} - -@mixin grid-fluid-span($columns, $fluidGridColumnWidth, $fluidGridGutterWidth) { - width: ($fluidGridColumnWidth * $columns) + ($fluidGridGutterWidth * ($columns - 1)); - *width: ($fluidGridColumnWidth * $columns) + ($fluidGridGutterWidth * ($columns - 1)) - (.5 / $gridRowWidth * 100px * 1%); -} - -@mixin grid-fluid-offset($columns, $fluidGridColumnWidth, $fluidGridGutterWidth) { - margin-left: ($fluidGridColumnWidth * $columns) + ($fluidGridGutterWidth * ($columns - 1)) + ($fluidGridGutterWidth * 2); - *margin-left: ($fluidGridColumnWidth * $columns) + ($fluidGridGutterWidth * ($columns - 1)) - (.5 / $gridRowWidth * 100px * 1%) + ($fluidGridGutterWidth * 2) - (.5 / $gridRowWidth * 100px * 1%); -} - -@mixin grid-fluid-offset-first-child($columns, $fluidGridColumnWidth, $fluidGridGutterWidth) { - margin-left: ($fluidGridColumnWidth * $columns) + ($fluidGridGutterWidth * ($columns - 1)) + ($fluidGridGutterWidth); - *margin-left: ($fluidGridColumnWidth * $columns) + ($fluidGridGutterWidth * ($columns - 1)) - (.5 / $gridRowWidth * 100px * 1%) + $fluidGridGutterWidth - (.5 / $gridRowWidth * 100px * 1%); -} - - - -@mixin grid-input($gridColumnWidth, $gridGutterWidth) { - input, - textarea, - .uneditable-input { - margin-left: 0; // override margin-left from core grid system - } - - // Space grid-sized controls properly if multiple per line - .controls-row [class*="span"] + [class*="span"] { - margin-left: $gridGutterWidth; - } - - // generate .spanX - @include grid-input-span-x($gridColumns, $gridColumnWidth, $gridGutterWidth); -} - -@mixin grid-input-span-x($gridColumns, $gridColumnWidth, $gridGutterWidth) { - @while $gridColumns > 0 { - input.span#{$gridColumns}, - textarea.span#{$gridColumns}, - .uneditable-input.span#{$gridColumns} { - @include grid-input-span($gridColumns, $gridColumnWidth, $gridGutterWidth); - } - $gridColumns: $gridColumns - 1; - } -} - -@mixin grid-input-span($columns, $gridColumnWidth, $gridGutterWidth) { - width: (($gridColumnWidth) * $columns) + ($gridGutterWidth * ($columns - 1)) - 14; -} diff --git a/vendor/styles/bootstrap/_modals.scss b/vendor/styles/bootstrap/_modals.scss deleted file mode 100644 index 749baa6..0000000 --- a/vendor/styles/bootstrap/_modals.scss +++ /dev/null @@ -1,95 +0,0 @@ -// -// Modals -// -------------------------------------------------- - -// Background -.modal-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: $zindexModalBackdrop; - background-color: $black; - // Fade for backdrop - &.fade { opacity: 0; } -} - -.modal-backdrop, -.modal-backdrop.fade.in { - @include opacity(80); -} - -// Base modal -.modal { - position: fixed; - top: 10%; - left: 50%; - z-index: $zindexModal; - width: 560px; - margin-left: -280px; - background-color: $white; - border: 1px solid #999; - border: 1px solid rgba(0,0,0,.3); - *border: 1px solid #999; /* IE6-7 */ - @include border-radius(6px); - @include box-shadow(0 3px 7px rgba(0,0,0,0.3)); - @include background-clip(padding-box); - // Remove focus outline from opened modal - outline: none; - - &.fade { - @include transition(opacity .3s linear, top .3s ease-out); - top: -25%; - } - &.fade.in { top: 10%; } -} -.modal-header { - padding: 9px 15px; - border-bottom: 1px solid #eee; - // Close icon - .close { margin-top: 2px; } - // Heading - h3 { - margin: 0; - line-height: 30px; - } -} - -// Body (where all modal content resides) -.modal-body { - position: relative; - overflow-y: auto; - max-height: 400px; - padding: 15px; -} -// Remove bottom margin if need be -.modal-form { - margin-bottom: 0; -} - -// Footer (for actions) -.modal-footer { - padding: 14px 15px 15px; - margin-bottom: 0; - text-align: right; // right align buttons - background-color: #f5f5f5; - border-top: 1px solid #ddd; - @include border-radius(0 0 6px 6px); - @include box-shadow(inset 0 1px 0 $white); - @include clearfix(); // clear it in case folks use .pull-* classes on buttons - - // Properly space out buttons - .btn + .btn { - margin-left: 5px; - margin-bottom: 0; // account for input[type="submit"] which gets the bottom margin like all other inputs - } - // but override that for button groups - .btn-group .btn + .btn { - margin-left: -1px; - } - // and override it for block buttons as well - .btn-block + .btn-block { - margin-left: 0; - } -} diff --git a/vendor/styles/bootstrap/_navbar.scss b/vendor/styles/bootstrap/_navbar.scss deleted file mode 100644 index a65aa4a..0000000 --- a/vendor/styles/bootstrap/_navbar.scss +++ /dev/null @@ -1,497 +0,0 @@ -// -// Navbars (Redux) -// -------------------------------------------------- - - -// COMMON STYLES -// ------------- - -// Base class and wrapper -.navbar { - overflow: visible; - margin-bottom: $baseLineHeight; - - // Fix for IE7's bad z-indexing so dropdowns don't appear below content that follows the navbar - *position: relative; - *z-index: 2; -} - -// Inner for background effects -// Gradient is applied to its own element because overflow visible is not honored by IE when filter is present -.navbar-inner { - min-height: $navbarHeight; - padding-left: 20px; - padding-right: 20px; - @include gradient-vertical($navbarBackgroundHighlight, $navbarBackground); - border: 1px solid $navbarBorder; - @include border-radius($baseBorderRadius); - @include box-shadow(0 1px 4px rgba(0,0,0,.065)); - - // Prevent floats from breaking the navbar - @include clearfix(); -} - -// Set width to auto for default container -// We then reset it for fixed navbars in the #gridSystem mixin -.navbar .container { - width: auto; -} - -// Override the default collapsed state -.nav-collapse.collapse { - height: auto; - overflow: visible; -} - - -// Brand: website or project name -// ------------------------- -.navbar .brand { - float: left; - display: block; - // Vertically center the text given $navbarHeight - padding: (($navbarHeight - $baseLineHeight) / 2) 20px (($navbarHeight - $baseLineHeight) / 2); - margin-left: -20px; // negative indent to left-align the text down the page - font-size: 20px; - font-weight: 200; - color: $navbarBrandColor; - text-shadow: 0 1px 0 $navbarBackgroundHighlight; - &:hover, - &:focus { - text-decoration: none; - } -} - -// Plain text in topbar -// ------------------------- -.navbar-text { - margin-bottom: 0; - line-height: $navbarHeight; - color: $navbarText; -} - -// Janky solution for now to account for links outside the .nav -// ------------------------- -.navbar-link { - color: $navbarLinkColor; - &:hover, - &:focus { - color: $navbarLinkColorHover; - } -} - -// Dividers in navbar -// ------------------------- -.navbar .divider-vertical { - height: $navbarHeight; - margin: 0 9px; - border-left: 1px solid $navbarBackground; - border-right: 1px solid $navbarBackgroundHighlight; -} - -// Buttons in navbar -// ------------------------- -.navbar .btn, -.navbar .btn-group { - @include navbarVerticalAlign(30px); // Vertically center in navbar -} -.navbar .btn-group .btn, -.navbar .input-prepend .btn, -.navbar .input-append .btn, -.navbar .input-prepend .btn-group, -.navbar .input-append .btn-group { - margin-top: 0; // then undo the margin here so we don't accidentally double it -} - -// Navbar forms -// ------------------------- -.navbar-form { - margin-bottom: 0; // remove default bottom margin - @include clearfix(); - input, - select, - .radio, - .checkbox { - @include navbarVerticalAlign(30px); // Vertically center in navbar - } - input, - select, - .btn { - display: inline-block; - margin-bottom: 0; - } - input[type="image"], - input[type="checkbox"], - input[type="radio"] { - margin-top: 3px; - } - .input-append, - .input-prepend { - margin-top: 5px; - white-space: nowrap; // preven two items from separating within a .navbar-form that has .pull-left - input { - margin-top: 0; // remove the margin on top since it's on the parent - } - } -} - -// Navbar search -// ------------------------- -.navbar-search { - position: relative; - float: left; - @include navbarVerticalAlign(30px); // Vertically center in navbar - margin-bottom: 0; - .search-query { - margin-bottom: 0; - padding: 4px 14px; - @include font-sans-serif(13px, normal, 1); - @include border-radius(15px); // redeclare because of specificity of the type attribute - } -} - - - -// Static navbar -// ------------------------- - -.navbar-static-top { - position: static; - margin-bottom: 0; // remove 18px margin for default navbar - .navbar-inner { - @include border-radius(0); - } -} - - - -// Fixed navbar -// ------------------------- - -// Shared (top/bottom) styles -.navbar-fixed-top, -.navbar-fixed-bottom { - position: fixed; - right: 0; - left: 0; - z-index: $zindexFixedNavbar; - margin-bottom: 0; // remove 18px margin for default navbar -} -.navbar-fixed-top .navbar-inner, -.navbar-static-top .navbar-inner { - border-width: 0 0 1px; -} -.navbar-fixed-bottom .navbar-inner { - border-width: 1px 0 0; -} -.navbar-fixed-top .navbar-inner, -.navbar-fixed-bottom .navbar-inner { - padding-left: 0; - padding-right: 0; - @include border-radius(0); -} - -// Reset container width -// Required here as we reset the width earlier on and the grid mixins don't override early enough -.navbar-static-top .container, -.navbar-fixed-top .container, -.navbar-fixed-bottom .container { - @include grid-core-span($gridColumns, $gridColumnWidth, $gridGutterWidth); -} - -// Fixed to top -.navbar-fixed-top { - top: 0; -} -.navbar-fixed-top, -.navbar-static-top { - .navbar-inner { - @include box-shadow(0 1px 10px rgba(0,0,0,.1)); - } -} - -// Fixed to bottom -.navbar-fixed-bottom { - bottom: 0; - .navbar-inner { - @include box-shadow(0 -1px 10px rgba(0,0,0,.1)); - } -} - - - -// NAVIGATION -// ---------- - -.navbar .nav { - position: relative; - left: 0; - display: block; - float: left; - margin: 0 10px 0 0; -} -.navbar .nav.pull-right { - float: right; // redeclare due to specificity - margin-right: 0; // remove margin on float right nav -} -.navbar .nav > li { - float: left; -} - -// Links -.navbar .nav > li > a { - float: none; - // Vertically center the text given $navbarHeight - padding: (($navbarHeight - $baseLineHeight) / 2) 15px (($navbarHeight - $baseLineHeight) / 2); - color: $navbarLinkColor; - text-decoration: none; - text-shadow: 0 1px 0 $navbarBackgroundHighlight; -} -.navbar .nav .dropdown-toggle .caret { - margin-top: 8px; -} - -// Hover/focus -.navbar .nav > li > a:focus, -.navbar .nav > li > a:hover { - background-color: $navbarLinkBackgroundHover; // "transparent" is default to differentiate :hover/:focus from .active - color: $navbarLinkColorHover; - text-decoration: none; -} - -// Active nav items -.navbar .nav > .active > a, -.navbar .nav > .active > a:hover, -.navbar .nav > .active > a:focus { - color: $navbarLinkColorActive; - text-decoration: none; - background-color: $navbarLinkBackgroundActive; - @include box-shadow(inset 0 3px 8px rgba(0,0,0,.125)); -} - -// Navbar button for toggling navbar items in responsive layouts -// These definitions need to come after '.navbar .btn' -.navbar .btn-navbar { - display: none; - float: right; - padding: 7px 10px; - margin-left: 5px; - margin-right: 5px; - @include buttonBackground(darken($navbarBackgroundHighlight, 5%), darken($navbarBackground, 5%)); - @include box-shadow(inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075)); -} -.navbar .btn-navbar .icon-bar { - display: block; - width: 18px; - height: 2px; - background-color: #f5f5f5; - @include border-radius(1px); - @include box-shadow(0 1px 0 rgba(0,0,0,.25)); -} -.btn-navbar .icon-bar + .icon-bar { - margin-top: 3px; -} - - - -// Dropdown menus -// -------------- - -// Menu position and menu carets -.navbar .nav > li > .dropdown-menu { - &:before { - content: ''; - display: inline-block; - border-left: 7px solid transparent; - border-right: 7px solid transparent; - border-bottom: 7px solid #ccc; - border-bottom-color: $dropdownBorder; - position: absolute; - top: -7px; - left: 9px; - } - &:after { - content: ''; - display: inline-block; - border-left: 6px solid transparent; - border-right: 6px solid transparent; - border-bottom: 6px solid $dropdownBackground; - position: absolute; - top: -6px; - left: 10px; - } -} -// Menu position and menu caret support for dropups via extra dropup class -.navbar-fixed-bottom .nav > li > .dropdown-menu { - &:before { - border-top: 7px solid #ccc; - border-top-color: $dropdownBorder; - border-bottom: 0; - bottom: -7px; - top: auto; - } - &:after { - border-top: 6px solid $dropdownBackground; - border-bottom: 0; - bottom: -6px; - top: auto; - } -} - -// Caret should match text color on hover/focus -.navbar .nav li.dropdown > a:hover .caret, -.navbar .nav li.dropdown > a:focus .caret { - border-top-color: $navbarLinkColorActive; - border-bottom-color: $navbarLinkColorActive; -} - -// Remove background color from open dropdown -.navbar .nav li.dropdown.open > .dropdown-toggle, -.navbar .nav li.dropdown.active > .dropdown-toggle, -.navbar .nav li.dropdown.open.active > .dropdown-toggle { - background-color: $navbarLinkBackgroundActive; - color: $navbarLinkColorActive; -} -.navbar .nav li.dropdown > .dropdown-toggle .caret { - border-top-color: $navbarLinkColor; - border-bottom-color: $navbarLinkColor; -} -.navbar .nav li.dropdown.open > .dropdown-toggle .caret, -.navbar .nav li.dropdown.active > .dropdown-toggle .caret, -.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret { - border-top-color: $navbarLinkColorActive; - border-bottom-color: $navbarLinkColorActive; -} - -// Right aligned menus need alt position -.navbar .pull-right > li > .dropdown-menu, -.navbar .nav > li > .dropdown-menu.pull-right { - left: auto; - right: 0; - &:before { - left: auto; - right: 12px; - } - &:after { - left: auto; - right: 13px; - } - .dropdown-menu { - left: auto; - right: 100%; - margin-left: 0; - margin-right: -1px; - @include border-radius(6px 0 6px 6px); - } -} - - -// Inverted navbar -// ------------------------- - -.navbar-inverse { - - .navbar-inner { - @include gradient-vertical($navbarInverseBackgroundHighlight, $navbarInverseBackground); - border-color: $navbarInverseBorder; - } - - .brand, - .nav > li > a { - color: $navbarInverseLinkColor; - text-shadow: 0 -1px 0 rgba(0,0,0,.25); - &:hover, - &:focus { - color: $navbarInverseLinkColorHover; - } - } - - .brand { - color: $navbarInverseBrandColor; - } - - .navbar-text { - color: $navbarInverseText; - } - - .nav > li > a:focus, - .nav > li > a:hover { - background-color: $navbarInverseLinkBackgroundHover; - color: $navbarInverseLinkColorHover; - } - - .nav .active > a, - .nav .active > a:hover, - .nav .active > a:focus { - color: $navbarInverseLinkColorActive; - background-color: $navbarInverseLinkBackgroundActive; - } - - // Inline text links - .navbar-link { - color: $navbarInverseLinkColor; - &:hover, - &:focus { - color: $navbarInverseLinkColorHover; - } - } - - // Dividers in navbar - .divider-vertical { - border-left-color: $navbarInverseBackground; - border-right-color: $navbarInverseBackgroundHighlight; - } - - // Dropdowns - .nav li.dropdown.open > .dropdown-toggle, - .nav li.dropdown.active > .dropdown-toggle, - .nav li.dropdown.open.active > .dropdown-toggle { - background-color: $navbarInverseLinkBackgroundActive; - color: $navbarInverseLinkColorActive; - } - .nav li.dropdown > a:hover .caret, - .nav li.dropdown > a:focus .caret { - border-top-color: $navbarInverseLinkColorActive; - color: $navbarInverseLinkColorActive; - } - .nav li.dropdown > .dropdown-toggle .caret { - border-top-color: $navbarInverseLinkColor; - border-bottom-color: $navbarInverseLinkColor; - } - .nav li.dropdown.open > .dropdown-toggle .caret, - .nav li.dropdown.active > .dropdown-toggle .caret, - .nav li.dropdown.open.active > .dropdown-toggle .caret { - border-top-color: $navbarInverseLinkColorActive; - border-bottom-color: $navbarInverseLinkColorActive; - } - - // Navbar search - .navbar-search { - .search-query { - color: $white; - background-color: $navbarInverseSearchBackground; - border-color: $navbarInverseSearchBorder; - @include box-shadow(inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15)); - @include transition(none); - @include placeholder($navbarInverseSearchPlaceholderColor); - - // Focus states (we use .focused since IE7-8 and down doesn't support :focus) - &:focus, - &.focused { - padding: 5px 15px; - color: $grayDark; - text-shadow: 0 1px 0 $white; - background-color: $navbarInverseSearchBackgroundFocus; - border: 0; - @include box-shadow(0 0 3px rgba(0,0,0,.15)); - outline: 0; - } - } - } - - // Navbar collapse button - .btn-navbar { - @include buttonBackground(darken($navbarInverseBackgroundHighlight, 5%), darken($navbarInverseBackground, 5%)); - } - -} diff --git a/vendor/styles/bootstrap/_navs.scss b/vendor/styles/bootstrap/_navs.scss deleted file mode 100644 index 31c4451..0000000 --- a/vendor/styles/bootstrap/_navs.scss +++ /dev/null @@ -1,409 +0,0 @@ -// -// Navs -// -------------------------------------------------- - - -// BASE CLASS -// ---------- - -.nav { - margin-left: 0; - margin-bottom: $baseLineHeight; - list-style: none; -} - -// Make links block level -.nav > li > a { - display: block; -} -.nav > li > a:hover, -.nav > li > a:focus { - text-decoration: none; - background-color: $grayLighter; -} - -// Prevent IE8 from misplacing imgs -// See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989 -.nav > li > a > img { - max-width: none; -} - -// Redeclare pull classes because of specifity -.nav > .pull-right { - float: right; -} - -// Nav headers (for dropdowns and lists) -.nav-header { - display: block; - padding: 3px 15px; - font-size: 11px; - font-weight: bold; - line-height: $baseLineHeight; - color: $grayLight; - text-shadow: 0 1px 0 rgba(255,255,255,.5); - text-transform: uppercase; -} -// Space them out when they follow another list item (link) -.nav li + .nav-header { - margin-top: 9px; -} - - - -// NAV LIST -// -------- - -.nav-list { - padding-left: 15px; - padding-right: 15px; - margin-bottom: 0; -} -.nav-list > li > a, -.nav-list .nav-header { - margin-left: -15px; - margin-right: -15px; - text-shadow: 0 1px 0 rgba(255,255,255,.5); -} -.nav-list > li > a { - padding: 3px 15px; -} -.nav-list > .active > a, -.nav-list > .active > a:hover, -.nav-list > .active > a:focus { - color: $white; - text-shadow: 0 -1px 0 rgba(0,0,0,.2); - background-color: $linkColor; -} -.nav-list [class^="icon-"], -.nav-list [class*=" icon-"] { - margin-right: 2px; -} -// Dividers (basically an hr) within the dropdown -.nav-list .divider { - @include nav-divider(); -} - - - -// TABS AND PILLS -// ------------- - -// Common styles -.nav-tabs, -.nav-pills { - @include clearfix(); -} -.nav-tabs > li, -.nav-pills > li { - float: left; -} -.nav-tabs > li > a, -.nav-pills > li > a { - padding-right: 12px; - padding-left: 12px; - margin-right: 2px; - line-height: 14px; // keeps the overall height an even number -} - -// TABS -// ---- - -// Give the tabs something to sit on -.nav-tabs { - border-bottom: 1px solid #ddd; -} -// Make the list-items overlay the bottom border -.nav-tabs > li { - margin-bottom: -1px; -} -// Actual tabs (as links) -.nav-tabs > li > a { - padding-top: 8px; - padding-bottom: 8px; - line-height: $baseLineHeight; - border: 1px solid transparent; - @include border-radius(4px 4px 0 0); - &:hover, - &:focus { - border-color: $grayLighter $grayLighter #ddd; - } -} -// Active state, and it's :hover/:focus to override normal :hover/:focus -.nav-tabs > .active > a, -.nav-tabs > .active > a:hover, -.nav-tabs > .active > a:focus { - color: $gray; - background-color: $bodyBackground; - border: 1px solid #ddd; - border-bottom-color: transparent; - cursor: default; -} - - -// PILLS -// ----- - -// Links rendered as pills -.nav-pills > li > a { - padding-top: 8px; - padding-bottom: 8px; - margin-top: 2px; - margin-bottom: 2px; - @include border-radius(5px); -} - -// Active state -.nav-pills > .active > a, -.nav-pills > .active > a:hover, -.nav-pills > .active > a:focus { - color: $white; - background-color: $linkColor; -} - - - -// STACKED NAV -// ----------- - -// Stacked tabs and pills -.nav-stacked > li { - float: none; -} -.nav-stacked > li > a { - margin-right: 0; // no need for the gap between nav items -} - -// Tabs -.nav-tabs.nav-stacked { - border-bottom: 0; -} -.nav-tabs.nav-stacked > li > a { - border: 1px solid #ddd; - @include border-radius(0); -} -.nav-tabs.nav-stacked > li:first-child > a { - @include border-top-radius(4px); -} -.nav-tabs.nav-stacked > li:last-child > a { - @include border-bottom-radius(4px); -} -.nav-tabs.nav-stacked > li > a:hover, -.nav-tabs.nav-stacked > li > a:focus { - border-color: #ddd; - z-index: 2; -} - -// Pills -.nav-pills.nav-stacked > li > a { - margin-bottom: 3px; -} -.nav-pills.nav-stacked > li:last-child > a { - margin-bottom: 1px; // decrease margin to match sizing of stacked tabs -} - - - -// DROPDOWNS -// --------- - -.nav-tabs .dropdown-menu { - @include border-radius(0 0 6px 6px); // remove the top rounded corners here since there is a hard edge above the menu -} -.nav-pills .dropdown-menu { - @include border-radius(6px); // make rounded corners match the pills -} - -// Default dropdown links -// ------------------------- -// Make carets use linkColor to start -.nav .dropdown-toggle .caret { - border-top-color: $linkColor; - border-bottom-color: $linkColor; - margin-top: 6px; -} -.nav .dropdown-toggle:hover .caret, -.nav .dropdown-toggle:focus .caret { - border-top-color: $linkColorHover; - border-bottom-color: $linkColorHover; -} -/* move down carets for tabs */ -.nav-tabs .dropdown-toggle .caret { - margin-top: 8px; -} - -// Active dropdown links -// ------------------------- -.nav .active .dropdown-toggle .caret { - border-top-color: #fff; - border-bottom-color: #fff; -} -.nav-tabs .active .dropdown-toggle .caret { - border-top-color: $gray; - border-bottom-color: $gray; -} - -// Active:hover/:focus dropdown links -// ------------------------- -.nav > .dropdown.active > a:hover, -.nav > .dropdown.active > a:focus { - cursor: pointer; -} - -// Open dropdowns -// ------------------------- -.nav-tabs .open .dropdown-toggle, -.nav-pills .open .dropdown-toggle, -.nav > li.dropdown.open.active > a:hover, -.nav > li.dropdown.open.active > a:focus { - color: $white; - background-color: $grayLight; - border-color: $grayLight; -} -.nav li.dropdown.open .caret, -.nav li.dropdown.open.active .caret, -.nav li.dropdown.open a:hover .caret, -.nav li.dropdown.open a:focus .caret { - border-top-color: $white; - border-bottom-color: $white; - @include opacity(100); -} - -// Dropdowns in stacked tabs -.tabs-stacked .open > a:hover, -.tabs-stacked .open > a:focus { - border-color: $grayLight; -} - - - -// TABBABLE -// -------- - - -// COMMON STYLES -// ------------- - -// Clear any floats -.tabbable { - @include clearfix(); -} -.tab-content { - overflow: auto; // prevent content from running below tabs -} - -// Remove border on bottom, left, right -.tabs-below > .nav-tabs, -.tabs-right > .nav-tabs, -.tabs-left > .nav-tabs { - border-bottom: 0; -} - -// Show/hide tabbable areas -.tab-content > .tab-pane, -.pill-content > .pill-pane { - display: none; -} -.tab-content > .active, -.pill-content > .active { - display: block; -} - - -// BOTTOM -// ------ - -.tabs-below > .nav-tabs { - border-top: 1px solid #ddd; -} -.tabs-below > .nav-tabs > li { - margin-top: -1px; - margin-bottom: 0; -} -.tabs-below > .nav-tabs > li > a { - @include border-radius(0 0 4px 4px); - &:hover, - &:focus { - border-bottom-color: transparent; - border-top-color: #ddd; - } -} -.tabs-below > .nav-tabs > .active > a, -.tabs-below > .nav-tabs > .active > a:hover, -.tabs-below > .nav-tabs > .active > a:focus { - border-color: transparent #ddd #ddd #ddd; -} - -// LEFT & RIGHT -// ------------ - -// Common styles -.tabs-left > .nav-tabs > li, -.tabs-right > .nav-tabs > li { - float: none; -} -.tabs-left > .nav-tabs > li > a, -.tabs-right > .nav-tabs > li > a { - min-width: 74px; - margin-right: 0; - margin-bottom: 3px; -} - -// Tabs on the left -.tabs-left > .nav-tabs { - float: left; - margin-right: 19px; - border-right: 1px solid #ddd; -} -.tabs-left > .nav-tabs > li > a { - margin-right: -1px; - @include border-radius(4px 0 0 4px); -} -.tabs-left > .nav-tabs > li > a:hover, -.tabs-left > .nav-tabs > li > a:focus { - border-color: $grayLighter #ddd $grayLighter $grayLighter; -} -.tabs-left > .nav-tabs .active > a, -.tabs-left > .nav-tabs .active > a:hover, -.tabs-left > .nav-tabs .active > a:focus { - border-color: #ddd transparent #ddd #ddd; - *border-right-color: $white; -} - -// Tabs on the right -.tabs-right > .nav-tabs { - float: right; - margin-left: 19px; - border-left: 1px solid #ddd; -} -.tabs-right > .nav-tabs > li > a { - margin-left: -1px; - @include border-radius(0 4px 4px 0); -} -.tabs-right > .nav-tabs > li > a:hover, -.tabs-right > .nav-tabs > li > a:focus { - border-color: $grayLighter $grayLighter $grayLighter #ddd; -} -.tabs-right > .nav-tabs .active > a, -.tabs-right > .nav-tabs .active > a:hover, -.tabs-right > .nav-tabs .active > a:focus { - border-color: #ddd #ddd #ddd transparent; - *border-left-color: $white; -} - - - -// DISABLED STATES -// --------------- - -// Gray out text -.nav > .disabled > a { - color: $grayLight; -} -// Nuke hover/focus effects -.nav > .disabled > a:hover, -.nav > .disabled > a:focus { - text-decoration: none; - background-color: transparent; - cursor: default; -} diff --git a/vendor/styles/bootstrap/_pager.scss b/vendor/styles/bootstrap/_pager.scss deleted file mode 100644 index 46df08f..0000000 --- a/vendor/styles/bootstrap/_pager.scss +++ /dev/null @@ -1,43 +0,0 @@ -// -// Pager pagination -// -------------------------------------------------- - - -.pager { - margin: $baseLineHeight 0; - list-style: none; - text-align: center; - @include clearfix(); -} -.pager li { - display: inline; -} -.pager li > a, -.pager li > span { - display: inline-block; - padding: 5px 14px; - background-color: #fff; - border: 1px solid #ddd; - @include border-radius(15px); -} -.pager li > a:hover, -.pager li > a:focus { - text-decoration: none; - background-color: #f5f5f5; -} -.pager .next > a, -.pager .next > span { - float: right; -} -.pager .previous > a, -.pager .previous > span { - float: left; -} -.pager .disabled > a, -.pager .disabled > a:hover, -.pager .disabled > a:focus, -.pager .disabled > span { - color: $grayLight; - background-color: #fff; - cursor: default; -} diff --git a/vendor/styles/bootstrap/_pagination.scss b/vendor/styles/bootstrap/_pagination.scss deleted file mode 100644 index 8ab33ba..0000000 --- a/vendor/styles/bootstrap/_pagination.scss +++ /dev/null @@ -1,123 +0,0 @@ -// -// Pagination (multiple pages) -// -------------------------------------------------- - -// Space out pagination from surrounding content -.pagination { - margin: $baseLineHeight 0; -} - -.pagination ul { - // Allow for text-based alignment - display: inline-block; - @include ie7-inline-block(); - // Reset default ul styles - margin-left: 0; - margin-bottom: 0; - // Visuals - @include border-radius($baseBorderRadius); - @include box-shadow(0 1px 2px rgba(0,0,0,.05)); -} -.pagination ul > li { - display: inline; // Remove list-style and block-level defaults -} -.pagination ul > li > a, -.pagination ul > li > span { - float: left; // Collapse white-space - padding: 4px 12px; - line-height: $baseLineHeight; - text-decoration: none; - background-color: $paginationBackground; - border: 1px solid $paginationBorder; - border-left-width: 0; -} -.pagination ul > li > a:hover, -.pagination ul > li > a:focus, -.pagination ul > .active > a, -.pagination ul > .active > span { - background-color: $paginationActiveBackground; -} -.pagination ul > .active > a, -.pagination ul > .active > span { - color: $grayLight; - cursor: default; -} -.pagination ul > .disabled > span, -.pagination ul > .disabled > a, -.pagination ul > .disabled > a:hover, -.pagination ul > .disabled > a:focus { - color: $grayLight; - background-color: transparent; - cursor: default; -} -.pagination ul > li:first-child > a, -.pagination ul > li:first-child > span { - border-left-width: 1px; - @include border-left-radius($baseBorderRadius); -} -.pagination ul > li:last-child > a, -.pagination ul > li:last-child > span { - @include border-right-radius($baseBorderRadius); -} - - -// Alignment -// -------------------------------------------------- - -.pagination-centered { - text-align: center; -} -.pagination-right { - text-align: right; -} - - -// Sizing -// -------------------------------------------------- - -// Large -.pagination-large { - ul > li > a, - ul > li > span { - padding: $paddingLarge; - font-size: $fontSizeLarge; - } - ul > li:first-child > a, - ul > li:first-child > span { - @include border-left-radius($borderRadiusLarge); - } - ul > li:last-child > a, - ul > li:last-child > span { - @include border-right-radius($borderRadiusLarge); - } -} - -// Small and mini -.pagination-mini, -.pagination-small { - ul > li:first-child > a, - ul > li:first-child > span { - @include border-left-radius($borderRadiusSmall); - } - ul > li:last-child > a, - ul > li:last-child > span { - @include border-right-radius($borderRadiusSmall); - } -} - -// Small -.pagination-small { - ul > li > a, - ul > li > span { - padding: $paddingSmall; - font-size: $fontSizeSmall; - } -} -// Mini -.pagination-mini { - ul > li > a, - ul > li > span { - padding: $paddingMini; - font-size: $fontSizeMini; - } -} diff --git a/vendor/styles/bootstrap/_popovers.scss b/vendor/styles/bootstrap/_popovers.scss deleted file mode 100644 index 18a1ca0..0000000 --- a/vendor/styles/bootstrap/_popovers.scss +++ /dev/null @@ -1,133 +0,0 @@ -// -// Popovers -// -------------------------------------------------- - - -.popover { - position: absolute; - top: 0; - left: 0; - z-index: $zindexPopover; - display: none; - max-width: 276px; - padding: 1px; - text-align: left; // Reset given new insertion method - background-color: $popoverBackground; - -webkit-background-clip: padding-box; - -moz-background-clip: padding; - background-clip: padding-box; - border: 1px solid #ccc; - border: 1px solid rgba(0,0,0,.2); - @include border-radius(6px); - @include box-shadow(0 5px 10px rgba(0,0,0,.2)); - - // Overrides for proper insertion - white-space: normal; - - // Offset the popover to account for the popover arrow - &.top { margin-top: -10px; } - &.right { margin-left: 10px; } - &.bottom { margin-top: 10px; } - &.left { margin-left: -10px; } -} - -.popover-title { - margin: 0; // reset heading margin - padding: 8px 14px; - font-size: 14px; - font-weight: normal; - line-height: 18px; - background-color: $popoverTitleBackground; - border-bottom: 1px solid darken($popoverTitleBackground, 5%); - @include border-radius(5px 5px 0 0); - - &:empty { - display: none; - } -} - -.popover-content { - padding: 9px 14px; -} - -// Arrows -// -// .arrow is outer, .arrow:after is inner - -.popover .arrow, -.popover .arrow:after { - position: absolute; - display: block; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} -.popover .arrow { - border-width: $popoverArrowOuterWidth; -} -.popover .arrow:after { - border-width: $popoverArrowWidth; - content: ""; -} - -.popover { - &.top .arrow { - left: 50%; - margin-left: -$popoverArrowOuterWidth; - border-bottom-width: 0; - border-top-color: #999; // IE8 fallback - border-top-color: $popoverArrowOuterColor; - bottom: -$popoverArrowOuterWidth; - &:after { - bottom: 1px; - margin-left: -$popoverArrowWidth; - border-bottom-width: 0; - border-top-color: $popoverArrowColor; - } - } - &.right .arrow { - top: 50%; - left: -$popoverArrowOuterWidth; - margin-top: -$popoverArrowOuterWidth; - border-left-width: 0; - border-right-color: #999; // IE8 fallback - border-right-color: $popoverArrowOuterColor; - &:after { - left: 1px; - bottom: -$popoverArrowWidth; - border-left-width: 0; - border-right-color: $popoverArrowColor; - } - } - &.bottom .arrow { - left: 50%; - margin-left: -$popoverArrowOuterWidth; - border-top-width: 0; - border-bottom-color: #999; // IE8 fallback - border-bottom-color: $popoverArrowOuterColor; - top: -$popoverArrowOuterWidth; - &:after { - top: 1px; - margin-left: -$popoverArrowWidth; - border-top-width: 0; - border-bottom-color: $popoverArrowColor; - } - } - - &.left .arrow { - top: 50%; - right: -$popoverArrowOuterWidth; - margin-top: -$popoverArrowOuterWidth; - border-right-width: 0; - border-left-color: #999; // IE8 fallback - border-left-color: $popoverArrowOuterColor; - &:after { - right: 1px; - border-right-width: 0; - border-left-color: $popoverArrowColor; - bottom: -$popoverArrowWidth; - } - } - -} diff --git a/vendor/styles/bootstrap/_progress-bars.scss b/vendor/styles/bootstrap/_progress-bars.scss deleted file mode 100644 index 6d9e70b..0000000 --- a/vendor/styles/bootstrap/_progress-bars.scss +++ /dev/null @@ -1,122 +0,0 @@ -// -// Progress bars -// -------------------------------------------------- - - -// ANIMATIONS -// ---------- - -// Webkit -@-webkit-keyframes progress-bar-stripes { - from { background-position: 40px 0; } - to { background-position: 0 0; } -} - -// Firefox -@-moz-keyframes progress-bar-stripes { - from { background-position: 40px 0; } - to { background-position: 0 0; } -} - -// IE9 -@-ms-keyframes progress-bar-stripes { - from { background-position: 40px 0; } - to { background-position: 0 0; } -} - -// Opera -@-o-keyframes progress-bar-stripes { - from { background-position: 0 0; } - to { background-position: 40px 0; } -} - -// Spec -@keyframes progress-bar-stripes { - from { background-position: 40px 0; } - to { background-position: 0 0; } -} - - - -// THE BARS -// -------- - -// Outer container -.progress { - overflow: hidden; - height: $baseLineHeight; - margin-bottom: $baseLineHeight; - @include gradient-vertical(#f5f5f5, #f9f9f9); - @include box-shadow(inset 0 1px 2px rgba(0,0,0,.1)); - @include border-radius($baseBorderRadius); -} - -// Bar of progress -.progress .bar { - width: 0%; - height: 100%; - color: $white; - float: left; - font-size: 12px; - text-align: center; - text-shadow: 0 -1px 0 rgba(0,0,0,.25); - @include gradient-vertical(#149bdf, #0480be); - @include box-shadow(inset 0 -1px 0 rgba(0,0,0,.15)); - @include box-sizing(border-box); - @include transition(width .6s ease); -} -.progress .bar + .bar { - @include box-shadow(inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15)); -} - -// Striped bars -.progress-striped .bar { - @include gradient-striped(#149bdf); - @include background-size(40px 40px); -} - -// Call animation for the active one -.progress.active .bar { - -webkit-animation: progress-bar-stripes 2s linear infinite; - -moz-animation: progress-bar-stripes 2s linear infinite; - -ms-animation: progress-bar-stripes 2s linear infinite; - -o-animation: progress-bar-stripes 2s linear infinite; - animation: progress-bar-stripes 2s linear infinite; -} - - - -// COLORS -// ------ - -// Danger (red) -.progress-danger .bar, .progress .bar-danger { - @include gradient-vertical(#ee5f5b, #c43c35); -} -.progress-danger.progress-striped .bar, .progress-striped .bar-danger { - @include gradient-striped(#ee5f5b); -} - -// Success (green) -.progress-success .bar, .progress .bar-success { - @include gradient-vertical(#62c462, #57a957); -} -.progress-success.progress-striped .bar, .progress-striped .bar-success { - @include gradient-striped(#62c462); -} - -// Info (teal) -.progress-info .bar, .progress .bar-info { - @include gradient-vertical(#5bc0de, #339bb9); -} -.progress-info.progress-striped .bar, .progress-striped .bar-info { - @include gradient-striped(#5bc0de); -} - -// Warning (orange) -.progress-warning .bar, .progress .bar-warning { - @include gradient-vertical(lighten($orange, 15%), $orange); -} -.progress-warning.progress-striped .bar, .progress-striped .bar-warning { - @include gradient-striped(lighten($orange, 15%)); -} diff --git a/vendor/styles/bootstrap/_reset.scss b/vendor/styles/bootstrap/_reset.scss deleted file mode 100644 index 2f0f029..0000000 --- a/vendor/styles/bootstrap/_reset.scss +++ /dev/null @@ -1,216 +0,0 @@ -// -// Reset CSS -// Adapted from http://github.com/necolas/normalize.css -// -------------------------------------------------- - - -// Display in IE6-9 and FF3 -// ------------------------- - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -nav, -section { - display: block; -} - -// Display block in IE6-9 and FF3 -// ------------------------- - -audio, -canvas, -video { - display: inline-block; - *display: inline; - *zoom: 1; -} - -// Prevents modern browsers from displaying 'audio' without controls -// ------------------------- - -audio:not([controls]) { - display: none; -} - -// Base settings -// ------------------------- - -html { - font-size: 100%; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; -} -// Focus states -a:focus { - @include tab-focus(); -} -// Hover & Active -a:hover, -a:active { - outline: 0; -} - -// Prevents sub and sup affecting line-height in all browsers -// ------------------------- - -sub, -sup { - position: relative; - font-size: 75%; - line-height: 0; - vertical-align: baseline; -} -sup { - top: -0.5em; -} -sub { - bottom: -0.25em; -} - -// Img border in a's and image quality -// ------------------------- - -img { - /* Responsive images (ensure images don't scale beyond their parents) */ - max-width: 100%; /* Part 1: Set a maxium relative to the parent */ - width: auto\9; /* IE7-8 need help adjusting responsive images */ - height: auto; /* Part 2: Scale the height according to the width, otherwise you get stretching */ - - vertical-align: middle; - border: 0; - -ms-interpolation-mode: bicubic; -} - -// Prevent max-width from affecting Google Maps -#map_canvas img, -.google-maps img { - max-width: none; -} - -// Forms -// ------------------------- - -// Font size in all browsers, margin changes, misc consistency -button, -input, -select, -textarea { - margin: 0; - font-size: 100%; - vertical-align: middle; -} -button, -input { - *overflow: visible; // Inner spacing ie IE6/7 - line-height: normal; // FF3/4 have !important on line-height in UA stylesheet -} -button::-moz-focus-inner, -input::-moz-focus-inner { // Inner padding and border oddities in FF3/4 - padding: 0; - border: 0; -} -button, -html input[type="button"], // Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` and `video` controls. -input[type="reset"], -input[type="submit"] { - -webkit-appearance: button; // Corrects inability to style clickable `input` types in iOS. - cursor: pointer; // Improves usability and consistency of cursor style between image-type `input` and others. -} -label, -select, -button, -input[type="button"], -input[type="reset"], -input[type="submit"], -input[type="radio"], -input[type="checkbox"] { - cursor: pointer; // Improves usability and consistency of cursor style between image-type `input` and others. -} -input[type="search"] { // Appearance in Safari/Chrome - @include box-sizing(content-box); - -webkit-appearance: textfield; -} -input[type="search"]::-webkit-search-decoration, -input[type="search"]::-webkit-search-cancel-button { - -webkit-appearance: none; // Inner-padding issues in Chrome OSX, Safari 5 -} -textarea { - overflow: auto; // Remove vertical scrollbar in IE6-9 - vertical-align: top; // Readability and alignment cross-browser -} - - -// Printing -// ------------------------- -// Source: https://github.com/h5bp/html5-boilerplate/blob/master/css/main.css - -@media print { - - * { - text-shadow: none !important; - color: #000 !important; // Black prints faster: h5bp.com/s - background: transparent !important; - box-shadow: none !important; - } - - a, - a:visited { - text-decoration: underline; - } - - a[href]:after { - content: " (" attr(href) ")"; - } - - abbr[title]:after { - content: " (" attr(title) ")"; - } - - // Don't show links for images, or javascript/internal links - .ir a:after, - a[href^="javascript:"]:after, - a[href^="#"]:after { - content: ""; - } - - pre, - blockquote { - border: 1px solid #999; - page-break-inside: avoid; - } - - thead { - display: table-header-group; // h5bp.com/t - } - - tr, - img { - page-break-inside: avoid; - } - - img { - max-width: 100% !important; - } - - @page { - margin: 0.5cm; - } - - p, - h2, - h3 { - orphans: 3; - widows: 3; - } - - h2, - h3 { - page-break-after: avoid; - } -} diff --git a/vendor/styles/bootstrap/_responsive-1200px-min.scss b/vendor/styles/bootstrap/_responsive-1200px-min.scss deleted file mode 100644 index be54ccc..0000000 --- a/vendor/styles/bootstrap/_responsive-1200px-min.scss +++ /dev/null @@ -1,28 +0,0 @@ -// -// Responsive: Large desktop and up -// -------------------------------------------------- - - -@media (min-width: 1200px) { - - // Fixed grid - @include grid-core($gridColumnWidth1200, $gridGutterWidth1200); - - // Fluid grid - @include grid-fluid($fluidGridColumnWidth1200, $fluidGridGutterWidth1200); - - // Input grid - @include grid-input($gridColumnWidth1200, $gridGutterWidth1200); - - // Thumbnails - .thumbnails { - margin-left: -$gridGutterWidth1200; - } - .thumbnails > li { - margin-left: $gridGutterWidth1200; - } - .row-fluid .thumbnails { - margin-left: 0; - } - -} diff --git a/vendor/styles/bootstrap/_responsive-767px-max.scss b/vendor/styles/bootstrap/_responsive-767px-max.scss deleted file mode 100644 index 54bf3b7..0000000 --- a/vendor/styles/bootstrap/_responsive-767px-max.scss +++ /dev/null @@ -1,193 +0,0 @@ -// -// Responsive: Landscape phone to desktop/tablet -// -------------------------------------------------- - - -@media (max-width: 767px) { - - // Padding to set content in a bit - body { - padding-left: 20px; - padding-right: 20px; - } - // Negative indent the now static "fixed" navbar - .navbar-fixed-top, - .navbar-fixed-bottom, - .navbar-static-top { - margin-left: -20px; - margin-right: -20px; - } - // Remove padding on container given explicit padding set on body - .container-fluid { - padding: 0; - } - - // TYPOGRAPHY - // ---------- - // Reset horizontal dl - .dl-horizontal { - dt { - float: none; - clear: none; - width: auto; - text-align: left; - } - dd { - margin-left: 0; - } - } - - // GRID & CONTAINERS - // ----------------- - // Remove width from containers - .container { - width: auto; - } - // Fluid rows - .row-fluid { - width: 100%; - } - // Undo negative margin on rows and thumbnails - .row, - .thumbnails { - margin-left: 0; - } - .thumbnails > li { - float: none; - margin-left: 0; // Reset the default margin for all li elements when no .span* classes are present - } - // Make all grid-sized elements block level again - [class*="span"], - .uneditable-input[class*="span"], // Makes uneditable inputs full-width when using grid sizing - .row-fluid [class*="span"] { - float: none; - display: block; - width: 100%; - margin-left: 0; - @include box-sizing(border-box); - } - .span12, - .row-fluid .span12 { - width: 100%; - @include box-sizing(border-box); - } - .row-fluid [class*="offset"]:first-child { - margin-left: 0; - } - - // FORM FIELDS - // ----------- - // Make span* classes full width - .input-large, - .input-xlarge, - .input-xxlarge, - input[class*="span"], - select[class*="span"], - textarea[class*="span"], - .uneditable-input { - @include input-block-level(); - } - // But don't let it screw up prepend/append inputs - .input-prepend input, - .input-append input, - .input-prepend input[class*="span"], - .input-append input[class*="span"] { - display: inline-block; // redeclare so they don't wrap to new lines - width: auto; - } - .controls-row [class*="span"] + [class*="span"] { - margin-left: 0; - } - - // Modals - .modal { - position: fixed; - top: 20px; - left: 20px; - right: 20px; - width: auto; - margin: 0; - &.fade { top: -100px; } - &.fade.in { top: 20px; } - } - -} - - - -// UP TO LANDSCAPE PHONE -// --------------------- - -@media (max-width: 480px) { - - // Smooth out the collapsing/expanding nav - .nav-collapse { - -webkit-transform: translate3d(0, 0, 0); // activate the GPU - } - - // Block level the page header small tag for readability - .page-header h1 small { - display: block; - line-height: $baseLineHeight; - } - - // Update checkboxes for iOS - input[type="checkbox"], - input[type="radio"] { - border: 1px solid #ccc; - } - - // Remove the horizontal form styles - .form-horizontal { - .control-label { - float: none; - width: auto; - padding-top: 0; - text-align: left; - } - // Move over all input controls and content - .controls { - margin-left: 0; - } - // Move the options list down to align with labels - .control-list { - padding-top: 0; // has to be padding because margin collaspes - } - // Move over buttons in .form-actions to align with .controls - .form-actions { - padding-left: 10px; - padding-right: 10px; - } - } - - // Medias - // Reset float and spacing to stack - .media .pull-left, - .media .pull-right { - float: none; - display: block; - margin-bottom: 10px; - } - // Remove side margins since we stack instead of indent - .media-object { - margin-right: 0; - margin-left: 0; - } - - // Modals - .modal { - top: 10px; - left: 10px; - right: 10px; - } - .modal-header .close { - padding: 10px; - margin: -10px; - } - - // Carousel - .carousel-caption { - position: static; - } - -} diff --git a/vendor/styles/bootstrap/_responsive-768px-979px.scss b/vendor/styles/bootstrap/_responsive-768px-979px.scss deleted file mode 100644 index 1ae409f..0000000 --- a/vendor/styles/bootstrap/_responsive-768px-979px.scss +++ /dev/null @@ -1,19 +0,0 @@ -// -// Responsive: Tablet to desktop -// -------------------------------------------------- - - -@media (min-width: 768px) and (max-width: 979px) { - - // Fixed grid - @include grid-core($gridColumnWidth768, $gridGutterWidth768); - - // Fluid grid - @include grid-fluid($fluidGridColumnWidth768, $fluidGridGutterWidth768); - - // Input grid - @include grid-input($gridColumnWidth768, $gridGutterWidth768); - - // No need to reset .thumbnails here since it's the same $gridGutterWidth - -} diff --git a/vendor/styles/bootstrap/_responsive-navbar.scss b/vendor/styles/bootstrap/_responsive-navbar.scss deleted file mode 100644 index 9898a16..0000000 --- a/vendor/styles/bootstrap/_responsive-navbar.scss +++ /dev/null @@ -1,189 +0,0 @@ -// -// Responsive: Navbar -// -------------------------------------------------- - - -// TABLETS AND BELOW -// ----------------- -@media (max-width: $navbarCollapseWidth) { - - // UNFIX THE TOPBAR - // ---------------- - // Remove any padding from the body - body { - padding-top: 0; - } - // Unfix the navbars - .navbar-fixed-top, - .navbar-fixed-bottom { - position: static; - } - .navbar-fixed-top { - margin-bottom: $baseLineHeight; - } - .navbar-fixed-bottom { - margin-top: $baseLineHeight; - } - .navbar-fixed-top .navbar-inner, - .navbar-fixed-bottom .navbar-inner { - padding: 5px; - } - .navbar .container { - width: auto; - padding: 0; - } - // Account for brand name - .navbar .brand { - padding-left: 10px; - padding-right: 10px; - margin: 0 0 0 -5px; - } - - // COLLAPSIBLE NAVBAR - // ------------------ - // Nav collapse clears brand - .nav-collapse { - clear: both; - } - // Block-level the nav - .nav-collapse .nav { - float: none; - margin: 0 0 ($baseLineHeight / 2); - } - .nav-collapse .nav > li { - float: none; - } - .nav-collapse .nav > li > a { - margin-bottom: 2px; - } - .nav-collapse .nav > .divider-vertical { - display: none; - } - .nav-collapse .nav .nav-header { - color: $navbarText; - text-shadow: none; - } - // Nav and dropdown links in navbar - .nav-collapse .nav > li > a, - .nav-collapse .dropdown-menu a { - padding: 9px 15px; - font-weight: bold; - color: $navbarLinkColor; - @include border-radius(3px); - } - // Buttons - .nav-collapse .btn { - padding: 4px 10px 4px; - font-weight: normal; - @include border-radius($baseBorderRadius); - } - .nav-collapse .dropdown-menu li + li a { - margin-bottom: 2px; - } - .nav-collapse .nav > li > a:hover, - .nav-collapse .nav > li > a:focus, - .nav-collapse .dropdown-menu a:hover, - .nav-collapse .dropdown-menu a:focus { - background-color: $navbarBackground; - } - .navbar-inverse .nav-collapse .nav > li > a, - .navbar-inverse .nav-collapse .dropdown-menu a { - color: $navbarInverseLinkColor; - } - .navbar-inverse .nav-collapse .nav > li > a:hover, - .navbar-inverse .nav-collapse .nav > li > a:focus, - .navbar-inverse .nav-collapse .dropdown-menu a:hover, - .navbar-inverse .nav-collapse .dropdown-menu a:focus { - background-color: $navbarInverseBackground; - } - // Buttons in the navbar - .nav-collapse.in .btn-group { - margin-top: 5px; - padding: 0; - } - // Dropdowns in the navbar - .nav-collapse .dropdown-menu { - position: static; - top: auto; - left: auto; - float: none; - display: none; - max-width: none; - margin: 0 15px; - padding: 0; - background-color: transparent; - border: none; - @include border-radius(0); - @include box-shadow(none); - } - .nav-collapse .open > .dropdown-menu { - display: block; - } - - .nav-collapse .dropdown-menu:before, - .nav-collapse .dropdown-menu:after { - display: none; - } - .nav-collapse .dropdown-menu .divider { - display: none; - } - .nav-collapse .nav > li > .dropdown-menu { - &:before, - &:after { - display: none; - } - } - // Forms in navbar - .nav-collapse .navbar-form, - .nav-collapse .navbar-search { - float: none; - padding: ($baseLineHeight / 2) 15px; - margin: ($baseLineHeight / 2) 0; - border-top: 1px solid $navbarBackground; - border-bottom: 1px solid $navbarBackground; - @include box-shadow(inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1)); - } - .navbar-inverse .nav-collapse .navbar-form, - .navbar-inverse .nav-collapse .navbar-search { - border-top-color: $navbarInverseBackground; - border-bottom-color: $navbarInverseBackground; - } - // Pull right (secondary) nav content - .navbar .nav-collapse .nav.pull-right { - float: none; - margin-left: 0; - } - // Hide everything in the navbar save .brand and toggle button */ - .nav-collapse, - .nav-collapse.collapse { - overflow: hidden; - height: 0; - } - // Navbar button - .navbar .btn-navbar { - display: block; - } - - // STATIC NAVBAR - // ------------- - .navbar-static .navbar-inner { - padding-left: 10px; - padding-right: 10px; - } - - -} - - -// DEFAULT DESKTOP -// --------------- - -@media (min-width: $navbarCollapseDesktopWidth) { - - // Required to make the collapsing navbar work on regular desktops - .nav-collapse.collapse { - height: auto !important; - overflow: visible !important; - } - -} diff --git a/vendor/styles/bootstrap/_responsive-utilities.scss b/vendor/styles/bootstrap/_responsive-utilities.scss deleted file mode 100644 index 689b265..0000000 --- a/vendor/styles/bootstrap/_responsive-utilities.scss +++ /dev/null @@ -1,74 +0,0 @@ -// -// Responsive: Utility classes -// -------------------------------------------------- - - -// IE10 Metro responsive -// Required for Windows 8 Metro split-screen snapping with IE10 -// Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/ -@-ms-viewport{ - width: device-width; -} - -// Hide from screenreaders and browsers -// Credit: HTML5 Boilerplate -.hidden { - display: none; - visibility: hidden; -} - -// Visibility utilities - -// For desktops -.visible-phone { display: none !important; } -.visible-tablet { display: none !important; } -.hidden-phone { } -.hidden-tablet { } -.hidden-desktop { display: none !important; } -.visible-desktop { display: inherit !important; } - -// Tablets & small desktops only -@media (min-width: 768px) and (max-width: 979px) { - // Hide everything else - .hidden-desktop { display: inherit !important; } - .visible-desktop { display: none !important ; } - // Show - .visible-tablet { display: inherit !important; } - // Hide - .hidden-tablet { display: none !important; } -} - -// Phones only -@media (max-width: 767px) { - // Hide everything else - .hidden-desktop { display: inherit !important; } - .visible-desktop { display: none !important; } - // Show - .visible-phone { display: inherit !important; } // Use inherit to restore previous behavior - // Hide - .hidden-phone { display: none !important; } -} - -// Print utilities -.visible-print { display: none !important; } -.hidden-print { } - -@media print { - .visible-print { display: inherit !important; } - .hidden-print { display: none !important; } -} - -// Clearing floats -.clearfix { - @include clearfix(); -} - -// Accessible yet invisible text -.hide-text { - @include hide-text(); -} - -// Uses box-sizing mixin, so must be defined here -.input-block-level { - @include input-block-level(); -} diff --git a/vendor/styles/bootstrap/_scaffolding.scss b/vendor/styles/bootstrap/_scaffolding.scss deleted file mode 100644 index 23d4a00..0000000 --- a/vendor/styles/bootstrap/_scaffolding.scss +++ /dev/null @@ -1,53 +0,0 @@ -// -// Scaffolding -// -------------------------------------------------- - - -// Body reset -// ------------------------- - -body { - margin: 0; - font-family: $baseFontFamily; - font-size: $baseFontSize; - line-height: $baseLineHeight; - color: $textColor; - background-color: $bodyBackground; -} - - -// Links -// ------------------------- - -a { - color: $linkColor; - text-decoration: none; -} -a:hover, -a:focus { - color: $linkColorHover; - text-decoration: underline; -} - - -// Images -// ------------------------- - -// Rounded corners -.img-rounded { - @include border-radius(6px); -} - -// Add polaroid-esque trim -.img-polaroid { - padding: 4px; - background-color: #fff; - border: 1px solid #ccc; - border: 1px solid rgba(0,0,0,.2); - @include box-shadow(0 1px 3px rgba(0,0,0,.1)); -} - -// Perfect circle -.img-circle { - @include border-radius(500px); // crank the border-radius so it works with most reasonably sized images -} diff --git a/vendor/styles/bootstrap/_sprites.scss b/vendor/styles/bootstrap/_sprites.scss deleted file mode 100644 index a64472d..0000000 --- a/vendor/styles/bootstrap/_sprites.scss +++ /dev/null @@ -1,197 +0,0 @@ -// -// Sprites -// -------------------------------------------------- - - -// ICONS -// ----- - -// All icons receive the styles of the tag with a base class -// of .i and are then given a unique class to add width, height, -// and background-position. Your resulting HTML will look like -// . - -// For the white version of the icons, just add the .icon-white class: -// - -[class^="icon-"], -[class*=" icon-"] { - display: inline-block; - width: 14px; - height: 14px; - @include ie7-restore-right-whitespace(); - line-height: 14px; - vertical-align: text-top; - background-image: url($iconSpritePath); - background-position: 14px 14px; - background-repeat: no-repeat; - margin-top: 1px; -} - -/* White icons with optional class, or on hover/focus/active states of certain elements */ -.icon-white, -.nav-pills > .active > a > [class^="icon-"], -.nav-pills > .active > a > [class*=" icon-"], -.nav-list > .active > a > [class^="icon-"], -.nav-list > .active > a > [class*=" icon-"], -.navbar-inverse .nav > .active > a > [class^="icon-"], -.navbar-inverse .nav > .active > a > [class*=" icon-"], -.dropdown-menu > li > a:hover > [class^="icon-"], -.dropdown-menu > li > a:focus > [class^="icon-"], -.dropdown-menu > li > a:hover > [class*=" icon-"], -.dropdown-menu > li > a:focus > [class*=" icon-"], -.dropdown-menu > .active > a > [class^="icon-"], -.dropdown-menu > .active > a > [class*=" icon-"], -.dropdown-submenu:hover > a > [class^="icon-"], -.dropdown-submenu:focus > a > [class^="icon-"], -.dropdown-submenu:hover > a > [class*=" icon-"], -.dropdown-submenu:focus > a > [class*=" icon-"] { - background-image: url($iconWhiteSpritePath); -} - -.icon-glass { background-position: 0 0; } -.icon-music { background-position: -24px 0; } -.icon-search { background-position: -48px 0; } -.icon-envelope { background-position: -72px 0; } -.icon-heart { background-position: -96px 0; } -.icon-star { background-position: -120px 0; } -.icon-star-empty { background-position: -144px 0; } -.icon-user { background-position: -168px 0; } -.icon-film { background-position: -192px 0; } -.icon-th-large { background-position: -216px 0; } -.icon-th { background-position: -240px 0; } -.icon-th-list { background-position: -264px 0; } -.icon-ok { background-position: -288px 0; } -.icon-remove { background-position: -312px 0; } -.icon-zoom-in { background-position: -336px 0; } -.icon-zoom-out { background-position: -360px 0; } -.icon-off { background-position: -384px 0; } -.icon-signal { background-position: -408px 0; } -.icon-cog { background-position: -432px 0; } -.icon-trash { background-position: -456px 0; } - -.icon-home { background-position: 0 -24px; } -.icon-file { background-position: -24px -24px; } -.icon-time { background-position: -48px -24px; } -.icon-road { background-position: -72px -24px; } -.icon-download-alt { background-position: -96px -24px; } -.icon-download { background-position: -120px -24px; } -.icon-upload { background-position: -144px -24px; } -.icon-inbox { background-position: -168px -24px; } -.icon-play-circle { background-position: -192px -24px; } -.icon-repeat { background-position: -216px -24px; } -.icon-refresh { background-position: -240px -24px; } -.icon-list-alt { background-position: -264px -24px; } -.icon-lock { background-position: -287px -24px; } // 1px off -.icon-flag { background-position: -312px -24px; } -.icon-headphones { background-position: -336px -24px; } -.icon-volume-off { background-position: -360px -24px; } -.icon-volume-down { background-position: -384px -24px; } -.icon-volume-up { background-position: -408px -24px; } -.icon-qrcode { background-position: -432px -24px; } -.icon-barcode { background-position: -456px -24px; } - -.icon-tag { background-position: 0 -48px; } -.icon-tags { background-position: -25px -48px; } // 1px off -.icon-book { background-position: -48px -48px; } -.icon-bookmark { background-position: -72px -48px; } -.icon-print { background-position: -96px -48px; } -.icon-camera { background-position: -120px -48px; } -.icon-font { background-position: -144px -48px; } -.icon-bold { background-position: -167px -48px; } // 1px off -.icon-italic { background-position: -192px -48px; } -.icon-text-height { background-position: -216px -48px; } -.icon-text-width { background-position: -240px -48px; } -.icon-align-left { background-position: -264px -48px; } -.icon-align-center { background-position: -288px -48px; } -.icon-align-right { background-position: -312px -48px; } -.icon-align-justify { background-position: -336px -48px; } -.icon-list { background-position: -360px -48px; } -.icon-indent-left { background-position: -384px -48px; } -.icon-indent-right { background-position: -408px -48px; } -.icon-facetime-video { background-position: -432px -48px; } -.icon-picture { background-position: -456px -48px; } - -.icon-pencil { background-position: 0 -72px; } -.icon-map-marker { background-position: -24px -72px; } -.icon-adjust { background-position: -48px -72px; } -.icon-tint { background-position: -72px -72px; } -.icon-edit { background-position: -96px -72px; } -.icon-share { background-position: -120px -72px; } -.icon-check { background-position: -144px -72px; } -.icon-move { background-position: -168px -72px; } -.icon-step-backward { background-position: -192px -72px; } -.icon-fast-backward { background-position: -216px -72px; } -.icon-backward { background-position: -240px -72px; } -.icon-play { background-position: -264px -72px; } -.icon-pause { background-position: -288px -72px; } -.icon-stop { background-position: -312px -72px; } -.icon-forward { background-position: -336px -72px; } -.icon-fast-forward { background-position: -360px -72px; } -.icon-step-forward { background-position: -384px -72px; } -.icon-eject { background-position: -408px -72px; } -.icon-chevron-left { background-position: -432px -72px; } -.icon-chevron-right { background-position: -456px -72px; } - -.icon-plus-sign { background-position: 0 -96px; } -.icon-minus-sign { background-position: -24px -96px; } -.icon-remove-sign { background-position: -48px -96px; } -.icon-ok-sign { background-position: -72px -96px; } -.icon-question-sign { background-position: -96px -96px; } -.icon-info-sign { background-position: -120px -96px; } -.icon-screenshot { background-position: -144px -96px; } -.icon-remove-circle { background-position: -168px -96px; } -.icon-ok-circle { background-position: -192px -96px; } -.icon-ban-circle { background-position: -216px -96px; } -.icon-arrow-left { background-position: -240px -96px; } -.icon-arrow-right { background-position: -264px -96px; } -.icon-arrow-up { background-position: -289px -96px; } // 1px off -.icon-arrow-down { background-position: -312px -96px; } -.icon-share-alt { background-position: -336px -96px; } -.icon-resize-full { background-position: -360px -96px; } -.icon-resize-small { background-position: -384px -96px; } -.icon-plus { background-position: -408px -96px; } -.icon-minus { background-position: -433px -96px; } -.icon-asterisk { background-position: -456px -96px; } - -.icon-exclamation-sign { background-position: 0 -120px; } -.icon-gift { background-position: -24px -120px; } -.icon-leaf { background-position: -48px -120px; } -.icon-fire { background-position: -72px -120px; } -.icon-eye-open { background-position: -96px -120px; } -.icon-eye-close { background-position: -120px -120px; } -.icon-warning-sign { background-position: -144px -120px; } -.icon-plane { background-position: -168px -120px; } -.icon-calendar { background-position: -192px -120px; } -.icon-random { background-position: -216px -120px; width: 16px; } -.icon-comment { background-position: -240px -120px; } -.icon-magnet { background-position: -264px -120px; } -.icon-chevron-up { background-position: -288px -120px; } -.icon-chevron-down { background-position: -313px -119px; } // 1px, 1px off -.icon-retweet { background-position: -336px -120px; } -.icon-shopping-cart { background-position: -360px -120px; } -.icon-folder-close { background-position: -384px -120px; width: 16px; } -.icon-folder-open { background-position: -408px -120px; width: 16px; } -.icon-resize-vertical { background-position: -432px -119px; } // 1px, 1px off -.icon-resize-horizontal { background-position: -456px -118px; } // 1px, 2px off - -.icon-hdd { background-position: 0 -144px; } -.icon-bullhorn { background-position: -24px -144px; } -.icon-bell { background-position: -48px -144px; } -.icon-certificate { background-position: -72px -144px; } -.icon-thumbs-up { background-position: -96px -144px; } -.icon-thumbs-down { background-position: -120px -144px; } -.icon-hand-right { background-position: -144px -144px; } -.icon-hand-left { background-position: -168px -144px; } -.icon-hand-up { background-position: -192px -144px; } -.icon-hand-down { background-position: -216px -144px; } -.icon-circle-arrow-right { background-position: -240px -144px; } -.icon-circle-arrow-left { background-position: -264px -144px; } -.icon-circle-arrow-up { background-position: -288px -144px; } -.icon-circle-arrow-down { background-position: -312px -144px; } -.icon-globe { background-position: -336px -144px; } -.icon-wrench { background-position: -360px -144px; } -.icon-tasks { background-position: -384px -144px; } -.icon-filter { background-position: -408px -144px; } -.icon-briefcase { background-position: -432px -144px; } -.icon-fullscreen { background-position: -456px -144px; } diff --git a/vendor/styles/bootstrap/_tables.scss b/vendor/styles/bootstrap/_tables.scss deleted file mode 100644 index 3db661e..0000000 --- a/vendor/styles/bootstrap/_tables.scss +++ /dev/null @@ -1,235 +0,0 @@ -// -// Tables -// -------------------------------------------------- - - -// BASE TABLES -// ----------------- - -table { - max-width: 100%; - background-color: $tableBackground; - border-collapse: collapse; - border-spacing: 0; -} - -// BASELINE STYLES -// --------------- - -.table { - width: 100%; - margin-bottom: $baseLineHeight; - // Cells - th, - td { - padding: 8px; - line-height: $baseLineHeight; - text-align: left; - vertical-align: top; - border-top: 1px solid $tableBorder; - } - th { - font-weight: bold; - } - // Bottom align for column headings - thead th { - vertical-align: bottom; - } - // Remove top border from thead by default - caption + thead tr:first-child th, - caption + thead tr:first-child td, - colgroup + thead tr:first-child th, - colgroup + thead tr:first-child td, - thead:first-child tr:first-child th, - thead:first-child tr:first-child td { - border-top: 0; - } - // Account for multiple tbody instances - tbody + tbody { - border-top: 2px solid $tableBorder; - } - - // Nesting - .table { - background-color: $bodyBackground; - } -} - - - -// CONDENSED TABLE W/ HALF PADDING -// ------------------------------- - -.table-condensed { - th, - td { - padding: 4px 5px; - } -} - - -// BORDERED VERSION -// ---------------- - -.table-bordered { - border: 1px solid $tableBorder; - border-collapse: separate; // Done so we can round those corners! - *border-collapse: collapse; // IE7 can't round corners anyway - border-left: 0; - @include border-radius($baseBorderRadius); - th, - td { - border-left: 1px solid $tableBorder; - } - // Prevent a double border - caption + thead tr:first-child th, - caption + tbody tr:first-child th, - caption + tbody tr:first-child td, - colgroup + thead tr:first-child th, - colgroup + tbody tr:first-child th, - colgroup + tbody tr:first-child td, - thead:first-child tr:first-child th, - tbody:first-child tr:first-child th, - tbody:first-child tr:first-child td { - border-top: 0; - } - // For first th/td in the first row in the first thead or tbody - thead:first-child tr:first-child > th:first-child, - tbody:first-child tr:first-child > td:first-child, - tbody:first-child tr:first-child > th:first-child { - @include border-top-left-radius($baseBorderRadius); - } - // For last th/td in the first row in the first thead or tbody - thead:first-child tr:first-child > th:last-child, - tbody:first-child tr:first-child > td:last-child, - tbody:first-child tr:first-child > th:last-child { - @include border-top-right-radius($baseBorderRadius); - } - // For first th/td (can be either) in the last row in the last thead, tbody, and tfoot - thead:last-child tr:last-child > th:first-child, - tbody:last-child tr:last-child > td:first-child, - tbody:last-child tr:last-child > th:first-child, - tfoot:last-child tr:last-child > td:first-child, - tfoot:last-child tr:last-child > th:first-child { - @include border-bottom-left-radius($baseBorderRadius); - } - // For last th/td (can be either) in the last row in the last thead, tbody, and tfoot - thead:last-child tr:last-child > th:last-child, - tbody:last-child tr:last-child > td:last-child, - tbody:last-child tr:last-child > th:last-child, - tfoot:last-child tr:last-child > td:last-child, - tfoot:last-child tr:last-child > th:last-child { - @include border-bottom-right-radius($baseBorderRadius); - } - - // Clear border-radius for first and last td in the last row in the last tbody for table with tfoot - tfoot + tbody:last-child tr:last-child td:first-child { - @include border-bottom-left-radius(0); - } - tfoot + tbody:last-child tr:last-child td:last-child { - @include border-bottom-right-radius(0); - } - - // Special fixes to round the left border on the first td/th - caption + thead tr:first-child th:first-child, - caption + tbody tr:first-child td:first-child, - colgroup + thead tr:first-child th:first-child, - colgroup + tbody tr:first-child td:first-child { - @include border-top-left-radius($baseBorderRadius); - } - caption + thead tr:first-child th:last-child, - caption + tbody tr:first-child td:last-child, - colgroup + thead tr:first-child th:last-child, - colgroup + tbody tr:first-child td:last-child { - @include border-top-right-radius($baseBorderRadius); - } - -} - - - - -// ZEBRA-STRIPING -// -------------- - -// Default zebra-stripe styles (alternating gray and transparent backgrounds) -.table-striped { - tbody { - > tr:nth-child(odd) > td, - > tr:nth-child(odd) > th { - background-color: $tableBackgroundAccent; - } - } -} - - -// HOVER EFFECT -// ------------ -// Placed here since it has to come after the potential zebra striping -.table-hover { - tbody { - tr:hover > td, - tr:hover > th { - background-color: $tableBackgroundHover; - } - } -} - - -// TABLE CELL SIZING -// ----------------- - -// Reset default grid behavior -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; // undo default grid column styles - margin-left: 0; // undo default grid column styles -} - -// Change the column widths to account for td/th padding -.table td, -.table th { - @for $i from 1 through 12 { - &.span#{$i} { @include tableColumns($i); } - } -} - - - -// TABLE BACKGROUNDS -// ----------------- -// Exact selectors below required to override .table-striped - -.table tbody tr { - &.success > td { - background-color: $successBackground; - } - &.error > td { - background-color: $errorBackground; - } - &.warning > td { - background-color: $warningBackground; - } - &.info > td { - background-color: $infoBackground; - } -} - -// Hover states for .table-hover -.table-hover tbody tr { - &.success:hover > td { - background-color: darken($successBackground, 5%); - } - &.error:hover > td { - background-color: darken($errorBackground, 5%); - } - &.warning:hover > td { - background-color: darken($warningBackground, 5%); - } - &.info:hover > td { - background-color: darken($infoBackground, 5%); - } -} diff --git a/vendor/styles/bootstrap/_thumbnails.scss b/vendor/styles/bootstrap/_thumbnails.scss deleted file mode 100644 index 6333d53..0000000 --- a/vendor/styles/bootstrap/_thumbnails.scss +++ /dev/null @@ -1,53 +0,0 @@ -// -// Thumbnails -// -------------------------------------------------- - - -// Note: `.thumbnails` and `.thumbnails > li` are overriden in responsive files - -// Make wrapper ul behave like the grid -.thumbnails { - margin-left: -$gridGutterWidth; - list-style: none; - @include clearfix(); -} -// Fluid rows have no left margin -.row-fluid .thumbnails { - margin-left: 0; -} - -// Float li to make thumbnails appear in a row -.thumbnails > li { - float: left; // Explicity set the float since we don't require .span* classes - margin-bottom: $baseLineHeight; - margin-left: $gridGutterWidth; -} - -// The actual thumbnail (can be `a` or `div`) -.thumbnail { - display: block; - padding: 4px; - line-height: $baseLineHeight; - border: 1px solid #ddd; - @include border-radius($baseBorderRadius); - @include box-shadow(0 1px 3px rgba(0,0,0,.055)); - @include transition(all .2s ease-in-out); -} -// Add a hover/focus state for linked versions only -a.thumbnail:hover, -a.thumbnail:focus { - border-color: $linkColor; - @include box-shadow(0 1px 4px rgba(0,105,214,.25)); -} - -// Images and captions -.thumbnail > img { - display: block; - max-width: 100%; - margin-left: auto; - margin-right: auto; -} -.thumbnail .caption { - padding: 9px; - color: $gray; -} diff --git a/vendor/styles/bootstrap/_tooltip.scss b/vendor/styles/bootstrap/_tooltip.scss deleted file mode 100644 index af2d64c..0000000 --- a/vendor/styles/bootstrap/_tooltip.scss +++ /dev/null @@ -1,70 +0,0 @@ -// -// Tooltips -// -------------------------------------------------- - - -// Base class -.tooltip { - position: absolute; - z-index: $zindexTooltip; - display: block; - visibility: visible; - font-size: 11px; - line-height: 1.4; - @include opacity(0); - &.in { @include opacity(80); } - &.top { margin-top: -3px; padding: 5px 0; } - &.right { margin-left: 3px; padding: 0 5px; } - &.bottom { margin-top: 3px; padding: 5px 0; } - &.left { margin-left: -3px; padding: 0 5px; } -} - -// Wrapper for the tooltip content -.tooltip-inner { - max-width: 200px; - padding: 8px; - color: $tooltipColor; - text-align: center; - text-decoration: none; - background-color: $tooltipBackground; - @include border-radius($baseBorderRadius); -} - -// Arrows -.tooltip-arrow { - position: absolute; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} -.tooltip { - &.top .tooltip-arrow { - bottom: 0; - left: 50%; - margin-left: -$tooltipArrowWidth; - border-width: $tooltipArrowWidth $tooltipArrowWidth 0; - border-top-color: $tooltipArrowColor; - } - &.right .tooltip-arrow { - top: 50%; - left: 0; - margin-top: -$tooltipArrowWidth; - border-width: $tooltipArrowWidth $tooltipArrowWidth $tooltipArrowWidth 0; - border-right-color: $tooltipArrowColor; - } - &.left .tooltip-arrow { - top: 50%; - right: 0; - margin-top: -$tooltipArrowWidth; - border-width: $tooltipArrowWidth 0 $tooltipArrowWidth $tooltipArrowWidth; - border-left-color: $tooltipArrowColor; - } - &.bottom .tooltip-arrow { - top: 0; - left: 50%; - margin-left: -$tooltipArrowWidth; - border-width: 0 $tooltipArrowWidth $tooltipArrowWidth; - border-bottom-color: $tooltipArrowColor; - } -} diff --git a/vendor/styles/bootstrap/_type.scss b/vendor/styles/bootstrap/_type.scss deleted file mode 100644 index f68e7ba..0000000 --- a/vendor/styles/bootstrap/_type.scss +++ /dev/null @@ -1,247 +0,0 @@ -// -// Typography -// -------------------------------------------------- - - -// Body text -// ------------------------- - -p { - margin: 0 0 $baseLineHeight / 2; -} -.lead { - margin-bottom: $baseLineHeight; - font-size: $baseFontSize * 1.5; - font-weight: 200; - line-height: $baseLineHeight * 1.5; -} - - -// Emphasis & misc -// ------------------------- - -// Ex: 14px base font * 85% = about 12px -small { font-size: 85%; } - -strong { font-weight: bold; } -em { font-style: italic; } -cite { font-style: normal; } - -// Utility classes -.muted { color: $grayLight; } -a.muted:hover, -a.muted:focus { color: darken($grayLight, 10%); } - -.text-warning { color: $warningText; } -a.text-warning:hover, -a.text-warning:focus { color: darken($warningText, 10%); } - -.text-error { color: $errorText; } -a.text-error:hover, -a.text-error:focus { color: darken($errorText, 10%); } - -.text-info { color: $infoText; } -a.text-info:hover, -a.text-info:focus { color: darken($infoText, 10%); } - -.text-success { color: $successText; } -a.text-success:hover, -a.text-success:focus { color: darken($successText, 10%); } - -.text-left { text-align: left; } -.text-right { text-align: right; } -.text-center { text-align: center; } - - -// Headings -// ------------------------- - -h1, h2, h3, h4, h5, h6 { - margin: ($baseLineHeight / 2) 0; - font-family: $headingsFontFamily; - font-weight: $headingsFontWeight; - line-height: $baseLineHeight; - color: $headingsColor; - text-rendering: optimizelegibility; // Fix the character spacing for headings - small { - font-weight: normal; - line-height: 1; - color: $grayLight; - } -} - -h1, -h2, -h3 { line-height: $baseLineHeight * 2; } - -h1 { font-size: $baseFontSize * 2.75; } // ~38px -h2 { font-size: $baseFontSize * 2.25; } // ~32px -h3 { font-size: $baseFontSize * 1.75; } // ~24px -h4 { font-size: $baseFontSize * 1.25; } // ~18px -h5 { font-size: $baseFontSize; } -h6 { font-size: $baseFontSize * 0.85; } // ~12px - -h1 small { font-size: $baseFontSize * 1.75; } // ~24px -h2 small { font-size: $baseFontSize * 1.25; } // ~18px -h3 small { font-size: $baseFontSize; } -h4 small { font-size: $baseFontSize; } - - -// Page header -// ------------------------- - -.page-header { - padding-bottom: ($baseLineHeight / 2) - 1; - margin: $baseLineHeight 0 ($baseLineHeight * 1.5); - border-bottom: 1px solid $grayLighter; -} - - - -// Lists -// -------------------------------------------------- - -// Unordered and Ordered lists -ul, ol { - padding: 0; - margin: 0 0 $baseLineHeight / 2 25px; -} -ul ul, -ul ol, -ol ol, -ol ul { - margin-bottom: 0; -} -li { - line-height: $baseLineHeight; -} - -// Remove default list styles -ul.unstyled, -ol.unstyled { - margin-left: 0; - list-style: none; -} - -// Single-line list items -ul.inline, -ol.inline { - margin-left: 0; - list-style: none; - > li { - display: inline-block; - @include ie7-inline-block(); - padding-left: 5px; - padding-right: 5px; - } -} - -// Description Lists -dl { - margin-bottom: $baseLineHeight; -} -dt, -dd { - line-height: $baseLineHeight; -} -dt { - font-weight: bold; -} -dd { - margin-left: $baseLineHeight / 2; -} -// Horizontal layout (like forms) -.dl-horizontal { - @include clearfix(); // Ensure dl clears floats if empty dd elements present - dt { - float: left; - width: $horizontalComponentOffset - 20; - clear: left; - text-align: right; - @include text-overflow(); - } - dd { - margin-left: $horizontalComponentOffset; - } -} - -// MISC -// ---- - -// Horizontal rules -hr { - margin: $baseLineHeight 0; - border: 0; - border-top: 1px solid $hrBorder; - border-bottom: 1px solid $white; -} - -// Abbreviations and acronyms -abbr[title], -// Added data-* attribute to help out our tooltip plugin, per https://github.com/twitter/bootstrap/issues/5257 -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted $grayLight; -} -abbr.initialism { - font-size: 90%; - text-transform: uppercase; -} - -// Blockquotes -blockquote { - padding: 0 0 0 15px; - margin: 0 0 $baseLineHeight; - border-left: 5px solid $grayLighter; - p { - margin-bottom: 0; - font-size: $baseFontSize * 1.25; - font-weight: 300; - line-height: 1.25; - } - small { - display: block; - line-height: $baseLineHeight; - color: $grayLight; - &:before { - content: '\2014 \00A0'; - } - } - - // Float right with text-align: right - &.pull-right { - float: right; - padding-right: 15px; - padding-left: 0; - border-right: 5px solid $grayLighter; - border-left: 0; - p, - small { - text-align: right; - } - small { - &:before { - content: ''; - } - &:after { - content: '\00A0 \2014'; - } - } - } -} - -// Quotes -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; -} - -// Addresses -address { - display: block; - margin-bottom: $baseLineHeight; - font-style: normal; - line-height: $baseLineHeight; -} diff --git a/vendor/styles/bootstrap/_utilities.scss b/vendor/styles/bootstrap/_utilities.scss deleted file mode 100644 index 1dec18b..0000000 --- a/vendor/styles/bootstrap/_utilities.scss +++ /dev/null @@ -1,45 +0,0 @@ -// -// Utility classes -// -------------------------------------------------- - - -// Quick floats -.pull-right { - float: right; -} -.pull-left { - float: left; -} - -// Toggling content -.hide { - display: none; -} -.show { - display: block; -} - -// Visibility -.invisible { - visibility: hidden; -} - -// For Affix plugin -.affix { - position: fixed; -} - -// Clearing floats -.clearfix { - @include clearfix(); -} - -// Accessible yet invisible text -.hide-text { - @include hide-text(); -} - -// Uses box-sizing mixin, so must be defined here -.input-block-level { - @include input-block-level(); -} diff --git a/vendor/styles/bootstrap/_variables.scss b/vendor/styles/bootstrap/_variables.scss deleted file mode 100644 index eebdc56..0000000 --- a/vendor/styles/bootstrap/_variables.scss +++ /dev/null @@ -1,301 +0,0 @@ -// -// Variables -// -------------------------------------------------- - - -// Global values -// -------------------------------------------------- - - -// Grays -// ------------------------- -$black: #000 !default; -$grayDarker: #222 !default; -$grayDark: #333 !default; -$gray: #555 !default; -$grayLight: #999 !default; -$grayLighter: #eee !default; -$white: #fff !default; - - -// Accent colors -// ------------------------- -$blue: #049cdb !default; -$blueDark: #0064cd !default; -$green: #46a546 !default; -$red: #9d261d !default; -$yellow: #ffc40d !default; -$orange: #f89406 !default; -$pink: #c3325f !default; -$purple: #7a43b6 !default; - - -// Scaffolding -// ------------------------- -$bodyBackground: $white !default; -$textColor: $grayDark !default; - - -// Links -// ------------------------- -$linkColor: #08c !default; -$linkColorHover: darken($linkColor, 15%) !default; - - -// Typography -// ------------------------- -$sansFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif !default; -$serifFontFamily: Georgia, "Times New Roman", Times, serif !default; -$monoFontFamily: Monaco, Menlo, Consolas, "Courier New", monospace !default; - -$baseFontSize: 14px !default; -$baseFontFamily: $sansFontFamily !default; -$baseLineHeight: 20px !default; -$altFontFamily: $serifFontFamily !default; - -$headingsFontFamily: inherit !default; // empty to use BS default, $baseFontFamily -$headingsFontWeight: bold !default; // instead of browser default, bold -$headingsColor: inherit !default; // empty to use BS default, $textColor - - -// Component sizing -// ------------------------- -// Based on 14px font-size and 20px line-height - -$fontSizeLarge: $baseFontSize * 1.25; // ~18px -$fontSizeSmall: $baseFontSize * 0.85; // ~12px -$fontSizeMini: $baseFontSize * 0.75; // ~11px - -$paddingLarge: 11px 19px !default; // 44px -$paddingSmall: 2px 10px !default; // 26px -$paddingMini: 0px 6px !default; // 22px - -$baseBorderRadius: 4px !default; -$borderRadiusLarge: 6px !default; -$borderRadiusSmall: 3px !default; - - -// Tables -// ------------------------- -$tableBackground: transparent !default; // overall background-color -$tableBackgroundAccent: #f9f9f9 !default; // for striping -$tableBackgroundHover: #f5f5f5 !default; // for hover -$tableBorder: #ddd !default; // table and cell border - -// Buttons -// ------------------------- -$btnBackground: $white !default; -$btnBackgroundHighlight: darken($white, 10%) !default; -$btnBorder: #ccc !default; - -$btnPrimaryBackground: $linkColor !default; -$btnPrimaryBackgroundHighlight: adjust-hue($btnPrimaryBackground, 20%) !default; - -$btnInfoBackground: #5bc0de !default; -$btnInfoBackgroundHighlight: #2f96b4 !default; - -$btnSuccessBackground: #62c462 !default; -$btnSuccessBackgroundHighlight: #51a351 !default; - -$btnWarningBackground: lighten($orange, 15%) !default; -$btnWarningBackgroundHighlight: $orange !default; - -$btnDangerBackground: #ee5f5b !default; -$btnDangerBackgroundHighlight: #bd362f !default; - -$btnInverseBackground: #444 !default; -$btnInverseBackgroundHighlight: $grayDarker !default; - - -// Forms -// ------------------------- -$inputBackground: $white !default; -$inputBorder: #ccc !default; -$inputBorderRadius: $baseBorderRadius !default; -$inputDisabledBackground: $grayLighter !default; -$formActionsBackground: #f5f5f5 !default; -$inputHeight: $baseLineHeight + 10px; // base line-height + 8px vertical padding + 2px top/bottom border - - -// Dropdowns -// ------------------------- -$dropdownBackground: $white !default; -$dropdownBorder: rgba(0,0,0,.2) !default; -$dropdownDividerTop: #e5e5e5 !default; -$dropdownDividerBottom: $white !default; - -$dropdownLinkColor: $grayDark !default; -$dropdownLinkColorHover: $white !default; -$dropdownLinkColorActive: $white !default; - -$dropdownLinkBackgroundActive: $linkColor !default; -$dropdownLinkBackgroundHover: $dropdownLinkBackgroundActive !default; - - - -// COMPONENT VARIABLES -// -------------------------------------------------- - - -// Z-index master list -// ------------------------- -// Used for a bird's eye view of components dependent on the z-axis -// Try to avoid customizing these :) -$zindexDropdown: 1000 !default; -$zindexPopover: 1010 !default; -$zindexTooltip: 1030 !default; -$zindexFixedNavbar: 1030 !default; -$zindexModalBackdrop: 1040 !default; -$zindexModal: 1050 !default; - - -// Sprite icons path -// ------------------------- -$iconSpritePath: image-path("glyphicons-halflings.png") !default; -$iconWhiteSpritePath: image-path("glyphicons-halflings-white.png") !default; - - -// Input placeholder text color -// ------------------------- -$placeholderText: $grayLight !default; - - -// Hr border color -// ------------------------- -$hrBorder: $grayLighter !default; - - -// Horizontal forms & lists -// ------------------------- -$horizontalComponentOffset: 180px !default; - - -// Wells -// ------------------------- -$wellBackground: #f5f5f5 !default; - - -// Navbar -// ------------------------- -$navbarCollapseWidth: 979px !default; -$navbarCollapseDesktopWidth: $navbarCollapseWidth + 1; - -$navbarHeight: 40px !default; -$navbarBackgroundHighlight: #ffffff !default; -$navbarBackground: darken($navbarBackgroundHighlight, 5%) !default; -$navbarBorder: darken($navbarBackground, 12%) !default; - -$navbarText: #777 !default; -$navbarLinkColor: #777 !default; -$navbarLinkColorHover: $grayDark !default; -$navbarLinkColorActive: $gray !default; -$navbarLinkBackgroundHover: transparent !default; -$navbarLinkBackgroundActive: darken($navbarBackground, 5%) !default; - -$navbarBrandColor: $navbarLinkColor !default; - -// Inverted navbar -$navbarInverseBackground: #111111 !default; -$navbarInverseBackgroundHighlight: #222222 !default; -$navbarInverseBorder: #252525 !default; - -$navbarInverseText: $grayLight !default; -$navbarInverseLinkColor: $grayLight !default; -$navbarInverseLinkColorHover: $white !default; -$navbarInverseLinkColorActive: $navbarInverseLinkColorHover !default; -$navbarInverseLinkBackgroundHover: transparent !default; -$navbarInverseLinkBackgroundActive: $navbarInverseBackground !default; - -$navbarInverseSearchBackground: lighten($navbarInverseBackground, 25%) !default; -$navbarInverseSearchBackgroundFocus: $white !default; -$navbarInverseSearchBorder: $navbarInverseBackground !default; -$navbarInverseSearchPlaceholderColor: #ccc !default; - -$navbarInverseBrandColor: $navbarInverseLinkColor !default; - - -// Pagination -// ------------------------- -$paginationBackground: #fff !default; -$paginationBorder: #ddd !default; -$paginationActiveBackground: #f5f5f5 !default; - - -// Hero unit -// ------------------------- -$heroUnitBackground: $grayLighter !default; -$heroUnitHeadingColor: inherit !default; -$heroUnitLeadColor: inherit !default; - - -// Form states and alerts -// ------------------------- -$warningText: #c09853 !default; -$warningBackground: #fcf8e3 !default; -$warningBorder: darken(adjust-hue($warningBackground, -10), 3%) !default; - -$errorText: #b94a48 !default; -$errorBackground: #f2dede !default; -$errorBorder: darken(adjust-hue($errorBackground, -10), 3%) !default; - -$successText: #468847 !default; -$successBackground: #dff0d8 !default; -$successBorder: darken(adjust-hue($successBackground, -10), 5%) !default; - -$infoText: #3a87ad !default; -$infoBackground: #d9edf7 !default; -$infoBorder: darken(adjust-hue($infoBackground, -10), 7%) !default; - - -// Tooltips and popovers -// ------------------------- -$tooltipColor: #fff !default; -$tooltipBackground: #000 !default; -$tooltipArrowWidth: 5px !default; -$tooltipArrowColor: $tooltipBackground !default; - -$popoverBackground: #fff !default; -$popoverArrowWidth: 10px !default; -$popoverArrowColor: #fff !default; -$popoverTitleBackground: darken($popoverBackground, 3%) !default; - -// Special enhancement for popovers -$popoverArrowOuterWidth: $popoverArrowWidth + 1 !default; -$popoverArrowOuterColor: rgba(0,0,0,.25) !default; - - - -// GRID -// -------------------------------------------------- - - -// Default 940px grid -// ------------------------- -$gridColumns: 12 !default; -$gridColumnWidth: 60px !default; -$gridGutterWidth: 20px !default; -$gridRowWidth: ($gridColumns * $gridColumnWidth) + ($gridGutterWidth * ($gridColumns - 1)) !default; - -// 1200px min -$gridColumnWidth1200: 70px !default; -$gridGutterWidth1200: 30px !default; -$gridRowWidth1200: ($gridColumns * $gridColumnWidth1200) + ($gridGutterWidth1200 * ($gridColumns - 1)) !default; - -// 768px-979px -$gridColumnWidth768: 42px !default; -$gridGutterWidth768: 20px !default; -$gridRowWidth768: ($gridColumns * $gridColumnWidth768) + ($gridGutterWidth768 * ($gridColumns - 1)) !default; - - -// Fluid grid -// ------------------------- -$fluidGridColumnWidth: percentage($gridColumnWidth/$gridRowWidth) !default; -$fluidGridGutterWidth: percentage($gridGutterWidth/$gridRowWidth) !default; - -// 1200px min -$fluidGridColumnWidth1200: percentage($gridColumnWidth1200/$gridRowWidth1200) !default; -$fluidGridGutterWidth1200: percentage($gridGutterWidth1200/$gridRowWidth1200) !default; - -// 768px-979px -$fluidGridColumnWidth768: percentage($gridColumnWidth768/$gridRowWidth768) !default; -$fluidGridGutterWidth768: percentage($gridGutterWidth768/$gridRowWidth768) !default; diff --git a/vendor/styles/bootstrap/_wells.scss b/vendor/styles/bootstrap/_wells.scss deleted file mode 100644 index 551e520..0000000 --- a/vendor/styles/bootstrap/_wells.scss +++ /dev/null @@ -1,29 +0,0 @@ -// -// Wells -// -------------------------------------------------- - - -// Base class -.well { - min-height: 20px; - padding: 19px; - margin-bottom: 20px; - background-color: $wellBackground; - border: 1px solid darken($wellBackground, 7%); - @include border-radius($baseBorderRadius); - @include box-shadow(inset 0 1px 1px rgba(0,0,0,.05)); - blockquote { - border-color: #ddd; - border-color: rgba(0,0,0,.15); - } -} - -// Sizes -.well-large { - padding: 24px; - @include border-radius($borderRadiusLarge); -} -.well-small { - padding: 9px; - @include border-radius($borderRadiusSmall); -} diff --git a/vendor/styles/metro/_theme-dark.styl b/vendor/styles/metro/_theme-dark.styl new file mode 100644 index 0000000..e13194d --- /dev/null +++ b/vendor/styles/metro/_theme-dark.styl @@ -0,0 +1,65 @@ +body + background #1d1d1d + +.text-rest-state + color #ffffff + +.text-rest2-state + color rgba(255, 255, 255, 0.6) + +.text-hover-state + color rgba(255, 255, 255, 0.8) + +.text-pressed-state + color rgba(255, 255, 255, 0.4) + +.link-text + color #9466ff + &:hover + color rgba(148, 102, 255, 0.8) + &:active + color rgba(148, 102, 255, 0.6) + +h1, +h2, +h3, +h4, +h5, +h6 + color #ffffff + +h1:hover, +h2:hover, +h3:hover, +h4:hover, +h5:hover, +h6:hover + color rgba(255, 255, 255, 0.8) + +h1:active, +h2:active, +h3:active, +h4:active, +h5:active, +h6:active + color rgba(255, 255, 255, 0.4) + +a, +.link + color #9466ff + +a:hover, +.link:hover + color rgba(148, 102, 255, 0.8) + +a:active, +.link:active + color rgba(148, 102, 255, 0.6) + +.page + .page-header + .page-header-content + .user-login + .name + color #fff + diff --git a/vendor/styles/metro/modern-responsive.styl b/vendor/styles/metro/modern-responsive.styl new file mode 100644 index 0000000..00d49b6 --- /dev/null +++ b/vendor/styles/metro/modern-responsive.styl @@ -0,0 +1,753 @@ +.fg-color-blue + color #2d89ef !important + +.fg-color-blueLight + color #eff4ff !important + +.fg-color-blueDark + color #2b5797 !important + +.fg-color-green + color #00a300 !important + +.fg-color-greenLight + color #99b433 !important + +.fg-color-greenDark + color #1e7145 !important + +.fg-color-red + color #b91d47 !important + +.fg-color-yellow + color #ffc40d !important + +.fg-color-orange + color #e3a21a !important + +.fg-color-orangeDark + color #da532c !important + +.fg-color-pink + color #9f00a7 !important + +.fg-color-pinkDark + color #7e3878 !important + +.fg-color-purple + color #603cba !important + +.fg-color-darken + color #1d1d1d !important + +.fg-color-lighten + color #d5e7ec !important + +.fg-color-white + color #ffffff !important + +.fg-color-grayDark + color #525252 !important + +.fg-color-magenta + color #ff0097 !important + +.fg-color-teal + color #00aba9 !important + +.fg-color-redLight + color #ee1111 !important + +.bg-color-blue + background-color #2d89ef !important + +.bg-color-blueLight + background-color #eff4ff !important + +.bg-color-blueDark + background-color #2b5797 !important + +.bg-color-green + background-color #00a300 !important + +.bg-color-greenLight + background-color #99b433 !important + +.bg-color-greenDark + background-color #1e7145 !important + +.bg-color-red + background-color #b91d47 !important + +.bg-color-yellow + background-color #ffc40d !important + +.bg-color-orange + background-color #e3a21a !important + +.bg-color-orangeDark + background-color #da532c !important + +.bg-color-pink + background-color #9f00a7 !important + +.bg-color-pinkDark + background-color #7e3878 !important + +.bg-color-purple + background-color #603cba !important + +.bg-color-darken + background-color #1d1d1d !important + +.bg-color-lighten + background-color #d5e7ec !important + +.bg-color-white + background-color #ffffff !important + +.bg-color-grayDark + background-color #525252 !important + +.bg-color-magenta + background-color #ff0097 !important + +.bg-color-teal + background-color #00aba9 !important + +.bg-color-redLight + background-color #ee1111 !important + +[class*=border-color] + border 2px solid + +.border-color-blue + border-color #2d89ef !important + +.border-color-blueLight + border-color #eff4ff !important + +.border-color-blueDark + border-color #2b5797 !important + +.border-color-green + border-color #00a300 !important + +.border-color-greenLight + border-color #99b433 !important + +.border-color-greenDark + border-color #1e7145 !important + +.border-color-red + border-color #b91d47 !important + +.border-color-yellow + border-color #ffc40d !important + +.border-color-orange + border-color #e3a21a !important + +.border-color-orangeDark + border-color #da532c !important + +.border-color-pink + border-color #9f00a7 !important + +.border-color-pinkDark + border-color #7e3878 !important + +.border-color-purple + border-color #603cba !important + +.border-color-darken + border-color #1d1d1d !important + +.border-color-lighten + border-color #d5e7ec !important + +.border-color-white + border-color #ffffff !important + +.border-color-grayDark + border-color #525252 !important + +.border-color-magenta + border-color #ff0097 !important + +.border-color-teal + border-color #00aba9 !important + +.border-color-redLight + border-color #ee1111 !important + +*:hover[class=outline-color] + outline 3px solid + +.outline-color-blue + outline-color #2d89ef !important + +.outline-color-blueLight + outline-color #eff4ff !important + +.outline-color-blueDark + outline-color #2b5797 !important + +.outline-color-green + outline-color #00a300 !important + +.outline-color-greenLight + outline-color #99b433 !important + +.outline-color-greenDark + outline-color #1e7145 !important + +.outline-color-red + outline-color #b91d47 !important + +.outline-color-yellow + outline-color #ffc40d !important + +.outline-color-orange + outline-color #e3a21a !important + +.outline-color-orangeDark + outline-color #da532c !important + +.outline-color-pink + outline-color #9f00a7 !important + +.outline-color-pinkDark + outline-color #7e3878 !important + +.outline-color-purple + outline-color #603cba !important + +.outline-color-darken + outline-color #1d1d1d !important + +.outline-color-lighten + outline-color #d5e7ec !important + +.outline-color-white + outline-color #ffffff !important + +.outline-color-grayDark + outline-color #525252 !important + +.outline-color-magenta + outline-color #ff0097 !important + +.outline-color-teal + outline-color #00aba9 !important + +.outline-color-redLight + outline-color #ee1111 !important + +@media + (min-width + &: + 1200px) + 980px) + .metrouicss .nav-bar .nav-bar-inner .pull-menu { + display none + (max-width + &: + 767px) + body { + padding-right 10px + padding-left 10px !important + +.metrouicss + .nav-bar + .nav-bar-inner + & > ul + &.menu + display block !important + display none + float none + margin 5px + display none + float none + margin 5px + & > li + display block + float none + width 100% + margin-left 0 + padding-left 5px + display block + float none + width 100% + margin-left 0 + padding-left 5px + a + display block + float none + display block + float none + .dropdown-menu + position relative + width 100% + border 0 + position relative + width 100% + border 0 + .pull-menu + display inline-block + display inline-block + & > .divider + float none + float none !important + .element + float none + float none + [data-role=dropdown] + margin-right 20px !important + margin-right 20px !important + & > a + cursor pointer + cursor pointer + &:before + position absolute + content "\203A" + display block + font-size 1.4em + left 100% + margin-left -10px + top 8px + -webkit-transform rotate(90deg) + -moz-transform rotate(90deg) + -ms-transform rotate(90deg) + -o-transform rotate(90deg) + transform rotate(90deg) + position absolute + content "\203A" + display block + font-size 1.4em + left 100% + margin-left -10px + top 8px + -webkit-transform rotate(90deg) + -moz-transform rotate(90deg) + -ms-transform rotate(90deg) + -o-transform rotate(90deg) + transform rotate(90deg) + .span2 + width 104px + .span3 + width 166px + .span4 + width 228px + .span5 + width 290px + .span6 + width 352px + .span7 + width 414px + .span8 + width 476px + .span9 + width 538px + .span10 + width 600px + .span11 + width 662px + .span12 + width 724px + .offset1 + margin-left 62px + .offset2 + margin-left 124px + .offset3 + margin-left 186px + .offset4 + margin-left 248px + .offset5 + margin-left 310px + .offset6 + margin-left 372px + .offset7 + margin-left 434px + .offset8 + margin-left 496px + .offset9 + margin-left 558px + .offset10 + margin-left 620px + .offset11 + margin-left 682px + .offset12 + margin-left 744px + table + thead + tr + th + font-size 9pt + font-size 8pt + tbody + tr + td + font-size 10pt + font-size 9pt + padding 2px 5px + h1 + font-size 30pt + font-size 26pt + line-height 18px + h2 + font-size 16pt + font-size 16pt + line-height 16px + .page-control + position relative + .menu-pull + background-image url("data:image/png + display block + width 24px + height 24px + float right + margin-top 10px + margin-right 10px + cursor pointer + .menu-pull-bar + display block + width 100% + height 44px + border 1px solid #CCC + border-bottom 0px + background-color rgba(217, 217, 217, 0.16) + padding 10px 0px 10px 20px + color #2D89EF + ul + width 100% + height auto + margin 0px + position relative + padding 0px 20px 10px 20px + border 1px solid #CCC + border-bottom 0px + border-top 0px + display none + li + display block + float left + width 100% + padding-left 0 + line-height 32px + position relative + height auto + &:first-child + margin-left 0px + &.active + border 0px + background-color rgba(0, 0, 0, 0) + a + color #1e1e1e + a + width 100% + text-align left + &:hover + background #464646 + color #fff + .frames + margin-top 0px + .tile + width 120px + height 120px + &.double + width 250px + &.triple + width 380px + &.quadro + width 510px + &.double-vertical + height 250px + &.triple-vertical + height 380px + &.quadro-vertical + height 510px + .tile-content + padding 5px 10px + &.icon + & > .tile-content + img + width 48px + height 48px + margin-left -24px + margin-top -24px + .page + &.secondary + .page-header + .page-header-content + height 60px + min-height 50px + h1 + left 40px + .page-region + .page-region-content + padding-left 0 + &.fixed-header + .page-header + position relative !important + .page-header-content + .user-login + float right + margin 35px 44px 0 0 + cursor pointer + .avatar + float right + border 1px #ccc solid + width 40px + height 40px + img + width 100% + height 100% + .name + float left + margin 0px 10px + text-align right + .first-name + font-family "Segoe UI Light", "Open Sans", sans-serif, sans + font-size 14pt + display block + margin 0 + .last-name + font-family "Open Sans", sans-serif, sans + font-size 8pt + display block + margin 0 + h1 + left 0 + .page-region + padding-top 20px + .horizontal-menu + height auto + & > ul + width 100% + display block + height auto + & > li + width 100% + float none + display block + position relative + border-bottom 1px #1e1e1e solid + &:last-child + border-bottom 1px transparent solid + a + width 100% + float none + li + ul + position relative + width 100% + border 0 + left 10px + h3 + font-size 13pt + line-height 16px + font-size 13pt + line-height 14px + .tile-group + max-width 400px + float none + +} + @media + (min-width + &: + 768px) + and + (max-width + &: + 979px) + .metrouicss .span1 { + width 42px + (max-width + &: + 480px) + .metrouicss .page.secondary .page-back { + width 24px + height 24px + left 0px !important + .place-left + float left !important + margin-right 10px + +.place-right + float right !important + margin-left 10px + +.scroll-y, +.scroll-vertical + overflow-y scroll + +.scroll-x, +.scroll-horizontal + overflow-x scroll + +.pos-rel + position relative + +.pos-abs + position absolute + +.pos-fix + position fixed + +.text-left + text-align left + +.text-right + text-align right + +.text-center + text-align center + +.text-justify + text-align justify + +.top-left + position absolute + top 0 + left 0 + +.top-right + position absolute + top 0 + right 0 + +.bottom-right + position absolute + bottom 0 + right 0 + +.bottom-left + position absolute + bottom 0 + left 0 + +.no-overflow + overflow hidden + +.no-display + display none + +.no-margin + margin 0 + +.no-padding + padding 0 + +.no-border + border 0 + +.no-border-all + border 0 + * + border 0 + +.as-block + display block + float none !important + +.as-inline-block + display inline-block + +.nlm + margin-left 0 !important + +.nrm + margin-right 0 !important + +.clearfix + *zoom 1 + &:after + clear both + +.clearfix:before, +.clearfix:after + display table + content "" + +.padding5 + padding 5px + +.padding10 + padding 10px + +.padding15 + padding 15px + +.padding20 + padding 20px + +.padding30 + padding 30px + +.padding40 + padding 40px + +.padding80 + padding 80px + +.selected + border 4px #2d89ef solid + &:after + width 0 + height 0 + border-top 40px solid #2d89ef + border-left 40px solid transparent + position absolute + display block + right 0 + content "." + top 0 + z-index 1001 + &:before + position absolute + content "\e08a" + color #fff + right 4px + font-family iconFont + z-index 1002 + +.border + border 1px #ccc solid + +.metrouicss [class*="span"], + .metrouicss .hero-unit + float none + display block + width 100% + margin-left 0 + margin-right 0 + +.metrouicss [class*="offset"], + .metrouicss .hero-unit + margin-left 0 + +.metrouicss .tile .brand > .badge, + .metrouicss .tile .tile-status > .badge + width 26px + height 28px + right 0 + font-size 9pt + +.metrouicss .tile .brand > .name, + .metrouicss .tile .tile-status > .name + margin-left 10px + +.metrouicss .tile .brand > .icon, + .metrouicss .tile .tile-status > .icon + width 24px + height 24px + margin 5px 10px + +.metrouicss .tile .brand > .text, + .metrouicss .tile .tile-status > .text + left 40px + right 40px + font-size 8pt + diff --git a/vendor/styles/metro/modern.styl b/vendor/styles/metro/modern.styl new file mode 100644 index 0000000..e39db2d --- /dev/null +++ b/vendor/styles/metro/modern.styl @@ -0,0 +1,6316 @@ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section, +summary + display block + +audio, +canvas, +video + display inline-block + *display inline + *zoom 1 + +audio + &:not([controls]) + display none + height 0 + +[hidden] + display none + +html + font-size 100% + -webkit-text-size-adjust 100% + -ms-text-size-adjust 100% + +html, +button, +input, +select, +textarea + font-family sans-serif + +body + margin 0 + +a + &:focus + outline thin dotted + +a:hover, +a:active + outline 0 + +h1 + font-size 2em + margin 0.67em 0 + +h2 + font-size 1.5em + margin 0.83em 0 + +h3 + font-size 1.17em + margin 1em 0 + +h4 + font-size 1em + margin 1.33em 0 + +h5 + font-size 0.83em + margin 1.67em 0 + +h6 + font-size 0.75em + margin 2.33em 0 + +abbr[title] + border-bottom 1px dotted + +b, +strong + font-weight bold + +blockquote + margin 1em 40px + +dfn + font-style italic + +mark + background #ff0 + color #000 + +p, +pre + margin 1em 0 + +pre, +code, +kbd, +samp + font-family monospace, serif + _font-family 'courier new', monospace + font-size 1em + +pre + white-space pre + white-space pre-wrap + word-wrap break-word + +q + quotes none + +q:before, +q:after + content '' + content none + +small + font-size 75% + +sub, +sup + font-size 75% + line-height 0 + position relative + vertical-align baseline + +sup + top -0.5em + +sub + bottom -0.25em + +dl, +menu, +ol, +ul + margin 1em 0 + +dd + margin 0 0 0 40px + +menu, +ol, +ul + padding 0 0 0 40px + +nav ul, +nav ol + list-style none + list-style-image none + +img + border 0 + -ms-interpolation-mode bicubic + +svg + &:not(:root) + overflow hidden + +figure + margin 0 + +form + margin 0 + +fieldset + border 1px solid #c0c0c0 + margin 0 2px + padding 0.35em 0.625em 0.75em + +legend + border 0 + padding 0 + white-space normal + *margin-left -7px + +button, +input, +select, +textarea + font-size 100% + margin 0 + vertical-align baseline + *vertical-align middle + +button, +input + line-height normal + +button, +input[type="button"], +input[type="reset"], +input[type="submit"] + cursor pointer + -webkit-appearance button + *overflow visible + +button[disabled], +input[disabled] + cursor default + +input[type="checkbox"], +input[type="radio"] + box-sizing border-box + padding 0 + *height 13px + *width 13px + +input[type="search"] + -webkit-appearance textfield + -moz-box-sizing content-box + -webkit-box-sizing content-box + box-sizing content-box + +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button + -webkit-appearance none + +button::-moz-focus-inner, +input::-moz-focus-inner + border 0 + padding 0 + +textarea + overflow auto + vertical-align top + +table + border-collapse collapse + border-spacing 0 + +.metrouicss + .text-rest-state + color #000000 + .text-rest2-state + color rgba(0, 0, 0, 0.6) + .text-hover-state + color rgba(0, 0, 0, 0.8) + .text-pressed-state + color rgba(0, 0, 0, 0.4) + #font + .header + font-family 'Segoe UI Light', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 200 + font-size 42pt + letter-spacing 0.00em + line-height 44pt + font-smooth always + .navigation + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 11pt + letter-spacing 0.01em + line-height 13pt + font-smooth always + .link + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 11pt + font-smooth always + line-height 13pt + .control + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 9pt + font-smooth always + line-height 11pt + .small + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 300 + font-size 8pt + font-smooth always + line-height 10pt + .long-text + font-family 'PT Serif Caption', sans-serif, serif !important + font-weight 300 + font-size 10pt + letter-spacing 0.02em + line-height 12pt + font-smooth always + .long-text-smaller + font-family 'PT Serif Caption', sans-serif, serif !important + font-weight 300 + font-size 10pt + letter-spacing 0.02em + line-height 12pt + font-smooth always + font-size 9pt + line-height 11pt + .long-text-lead + font-family 'PT Serif Caption', sans-serif, serif !important + font-weight 300 + font-size 10pt + letter-spacing 0.02em + line-height 12pt + font-smooth always + font-size 20pt + line-height 22pt + #state + .link + color #2e92cf + &:hover + color rgba(45, 173, 237, 0.8) + &:active + color rgba(45, 173, 237, 0.6) + h1 + font-family 'Segoe UI Light', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 200 + font-size 42pt + letter-spacing 0.00em + line-height 44pt + font-smooth always + color #000000 + &:hover + color rgba(0, 0, 0, 0.8) + &:active + color rgba(0, 0, 0, 0.4) + h2 + font-family 'Segoe UI Light', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 200 + font-size 20pt + letter-spacing 0.01em + line-height 22pt + font-smooth always + color #000000 + &:hover + color rgba(0, 0, 0, 0.8) + &:active + color rgba(0, 0, 0, 0.4) + h3 + font-family 'Segoe UI Light', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 200 + font-size 20pt + letter-spacing 0.01em + line-height 22pt + font-smooth always + color rgba(0, 0, 0, 0.6) + font-size 16pt + line-height 24px + &:hover + color rgba(0, 0, 0, 0.8) + &:active + color rgba(0, 0, 0, 0.4) + h4 + font-family 'Segoe UI Semibold', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 600 + font-size 11pt + letter-spacing 0.01em + line-height 13pt + font-smooth always + color #000000 + color rgba(0, 0, 0, 0.6) + &:hover + color rgba(0, 0, 0, 0.8) + color rgba(0, 0, 0, 0.8) + &:active + color rgba(0, 0, 0, 0.4) + color rgba(0, 0, 0, 0.4) + h5 + font-family 'Segoe UI Semibold', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 600 + font-size 11pt + letter-spacing 0.01em + line-height 13pt + font-smooth always + color rgba(0, 0, 0, 0.6) + font-size 90% + &:hover + color rgba(0, 0, 0, 0.8) + &:active + color rgba(0, 0, 0, 0.4) + h6 + font-family 'Segoe UI Semibold', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 600 + font-size 11pt + letter-spacing 0.01em + line-height 13pt + font-smooth always + color rgba(0, 0, 0, 0.6) + font-size 80% + &:hover + color rgba(0, 0, 0, 0.8) + &:active + color rgba(0, 0, 0, 0.4) + p + margin 0 0 10px + &.long-text + font-family 'PT Serif Caption', sans-serif, serif !important + font-weight 300 + font-size 10pt + letter-spacing 0.02em + line-height 12pt + font-smooth always + &.indent + &:first-letter + padding-left 25px + .lead + font-size 120% + line-height 26px + abbr + &.initialism + font-size 90% + text-transform uppercase !important + abbr[title] + cursor help !important + address + display block + margin-bottom 20px + font-family 'Segoe UI Semilight', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 300 + font-size 11pt + letter-spacing 0.02em + line-height 14pt + font-smooth always + line-height 20px + font-style normal + blockquote + margin 0 + padding 5px 20px + border-left 4px #ccc solid + display block + background-color rgba(204, 204, 204, 0.1) + p + margin-bottom 0 + small + &:before + content '\2014' + color rgba(0, 0, 0, 0.4) + margin-right 5px + &.place-right + float none !important + text-align right + border 0 + border-right 4px #ccc solid + small + text-align right + &:before + content "" + &:after + content '\2014' + color rgba(0, 0, 0, 0.4) + margin-left 5px + ul + list-style-position inside + list-style-type square + &:nth-child(1) + margin-left 25px + ul + list-style-type circle + ol + list-style-type decimal + &.icons + list-style-type none + li + line-height 24px + .place-left + float left !important + margin-right 10px + .place-right + float right !important + margin-left 10px + .pos-rel + position relative + .pos-abs + position absolute + .pos-fix + position fixed + .text-left + text-align left + .text-right + text-align right + .text-center + text-align center + .text-justify + text-align justify + .top-left + position absolute + top 0 + left 0 + .top-right + position absolute + top 0 + right 0 + .bottom-right + position absolute + bottom 0 + right 0 + .bottom-left + position absolute + bottom 0 + left 0 + .no-overflow + overflow hidden + .no-display + display none + .no-margin + margin 0 + .no-padding + padding 0 + .no-border + border 0 + .no-border-all + border 0 + * + border 0 + .as-block + display block + float none !important + .as-inline-block + display inline-block + .nlm + margin-left 0 !important + .nrm + margin-right 0 !important + .clearfix + *zoom 1 + &:after + clear both + .padding5 + padding 5px + .padding10 + padding 10px + .padding15 + padding 15px + .padding20 + padding 20px + .padding30 + padding 30px + .padding40 + padding 40px + .padding80 + padding 80px + .selected + border 4px #2d89ef solid + &:after + width 0 + height 0 + border-top 40px solid #2d89ef + border-left 40px solid transparent + position absolute + display block + right 0 + content "." + top 0 + z-index 1001 + &:before + position absolute + content "\e08a" + color #fff + right 4px + font-family iconFont + z-index 1002 + .border + border 1px #ccc solid + .icon-large + &:before + vertical-align -10% + font-size 1.3333333333333333em + .icon-muted + color #eeeeee + .icon-border + border solid 1px #eeeeee + padding .2em .25em .15em + .icon-2x + font-size 2em + &.icon-border + border-width 2px + .icon-3x + font-size 3em + &.icon-border + border-width 3px + .icon-4x + font-size 4em + &.icon-border + border-width 4px + .icon-home + &:before + content "\e000" + .icon-newspaper + &:before + content "\e001" + .icon-pencil + &:before + content "\e002" + .icon-droplet + &:before + content "\e003" + .icon-pictures + &:before + content "\e004" + .icon-camera + &:before + content "\e005" + .icon-music + &:before + content "\e006" + .icon-film + &:before + content "\e007" + .icon-camera-2 + &:before + content "\e008" + .icon-spades + &:before + content "\e009" + .icon-clubs + &:before + content "\e00a" + .icon-diamonds + &:before + content "\e00b" + .icon-broadcast + &:before + content "\e00c" + .icon-mic + &:before + content "\e00d" + .icon-book + &:before + content "\e00e" + .icon-file + &:before + content "\e00f" + .icon-new + &:before + content "\e010" + .icon-copy + &:before + content "\e011" + .icon-folder + &:before + content "\e012" + .icon-folder-2 + &:before + content "\e013" + .icon-tag + &:before + content "\e014" + .icon-cart + &:before + content "\e015" + .icon-basket + &:before + content "\e016" + .icon-calculate + &:before + content "\e017" + .icon-support + &:before + content "\e018" + .icon-phone + &:before + content "\e019" + .icon-mail + &:before + content "\e01a" + .icon-location + &:before + content "\e01b" + .icon-compass + &:before + content "\e01c" + .icon-history + &:before + content "\e01d" + .icon-clock + &:before + content "\e01e" + .icon-bell + &:before + content "\e01f" + .icon-calendar + &:before + content "\e020" + .icon-printer + &:before + content "\e021" + .icon-mouse + &:before + content "\e022" + .icon-screen + &:before + content "\e023" + .icon-laptop + &:before + content "\e024" + .icon-mobile + &:before + content "\e025" + .icon-cabinet + &:before + content "\e026" + .icon-drawer + &:before + content "\e027" + .icon-drawer-2 + &:before + content "\e028" + .icon-box + &:before + content "\e029" + .icon-box-add + &:before + content "\e02a" + .icon-box-remove + &:before + content "\e02b" + .icon-download + &:before + content "\e02c" + .icon-upload + &:before + content "\e02d" + .icon-database + &:before + content "\e02e" + .icon-flip + &:before + content "\e02f" + .icon-flip-2 + &:before + content "\e030" + .icon-undo + &:before + content "\e031" + .icon-redo + &:before + content "\e032" + .icon-forward + &:before + content "\e033" + .icon-reply + &:before + content "\e034" + .icon-reply-2 + &:before + content "\e035" + .icon-comments + &:before + content "\e036" + .icon-comments-2 + &:before + content "\e037" + .icon-comments-3 + &:before + content "\e038" + .icon-comments-4 + &:before + content "\e039" + .icon-comments-5 + &:before + content "\e03a" + .icon-user + &:before + content "\e03b" + .icon-user-2 + &:before + content "\e03c" + .icon-user-3 + &:before + content "\e03d" + .icon-busy + &:before + content "\e03e" + .icon-loading + &:before + content "\e03f" + .icon-loading-2 + &:before + content "\e040" + .icon-search + &:before + content "\e041" + .icon-zoom-in + &:before + content "\e042" + .icon-zoom-out + &:before + content "\e043" + .icon-key + &:before + content "\e044" + .icon-key-2 + &:before + content "\e045" + .icon-locked + &:before + content "\e046" + .icon-unlocked + &:before + content "\e047" + .icon-wrench + &:before + content "\e048" + .icon-equalizer + &:before + content "\e049" + .icon-cog + &:before + content "\e04a" + .icon-pie + &:before + content "\e04b" + .icon-bars + &:before + content "\e04c" + .icon-stats-up + &:before + content "\e04d" + .icon-gift + &:before + content "\e04e" + .icon-trophy + &:before + content "\e04f" + .icon-diamond + &:before + content "\e050" + .icon-coffee + &:before + content "\e051" + .icon-rocket + &:before + content "\e052" + .icon-meter-slow + &:before + content "\e053" + .icon-meter-medium + &:before + content "\e054" + .icon-meter-fast + &:before + content "\e055" + .icon-dashboard + &:before + content "\e056" + .icon-fire + &:before + content "\e057" + .icon-lab + &:before + content "\e058" + .icon-remove + &:before + content "\e059" + .icon-briefcase + &:before + content "\e05a" + .icon-briefcase-2 + &:before + content "\e05b" + .icon-cars + &:before + content "\e05c" + .icon-bus + &:before + content "\e05d" + .icon-cube + &:before + content "\e05e" + .icon-cube-2 + &:before + content "\e05f" + .icon-puzzle + &:before + content "\e060" + .icon-glasses + &:before + content "\e061" + .icon-glasses-2 + &:before + content "\e062" + .icon-accessibility + &:before + content "\e063" + .icon-accessibility-2 + &:before + content "\e064" + .icon-target + &:before + content "\e065" + .icon-target-2 + &:before + content "\e066" + .icon-lightning + &:before + content "\e067" + .icon-power + &:before + content "\e068" + .icon-power-2 + &:before + content "\e069" + .icon-clipboard + &:before + content "\e06a" + .icon-clipboard-2 + &:before + content "\e06b" + .icon-playlist + &:before + content "\e06c" + .icon-grid-view + &:before + content "\e06d" + .icon-tree-view + &:before + content "\e06e" + .icon-cloud + &:before + content "\e06f" + .icon-cloud-2 + &:before + content "\e070" + .icon-download-2 + &:before + content "\e071" + .icon-upload-2 + &:before + content "\e072" + .icon-upload-3 + &:before + content "\e073" + .icon-link + &:before + content "\e074" + .icon-link-2 + &:before + content "\e075" + .icon-flag + &:before + content "\e076" + .icon-flag-2 + &:before + content "\e077" + .icon-attachment + &:before + content "\e078" + .icon-eye + &:before + content "\e079" + .icon-bookmark + &:before + content "\e07a" + .icon-bookmark-2 + &:before + content "\e07b" + .icon-star + &:before + content "\e07c" + .icon-star-2 + &:before + content "\e07d" + .icon-star-3 + &:before + content "\e07e" + .icon-heart + &:before + content "\e07f" + .icon-heart-2 + &:before + content "\e080" + .icon-thumbs-up + &:before + content "\e081" + .icon-thumbs-down + &:before + content "\e082" + .icon-plus + &:before + content "\e083" + .icon-minus + &:before + content "\e084" + .icon-help + &:before + content "\e085" + .icon-help-2 + &:before + content "\e086" + .icon-blocked + &:before + content "\e087" + .icon-cancel + &:before + content "\e088" + .icon-cancel-2 + &:before + content "\e089" + .icon-checkmark + &:before + content "\e08a" + .icon-minus-2 + &:before + content "\e08b" + .icon-plus-2 + &:before + content "\e08c" + .icon-enter + &:before + content "\e08d" + .icon-exit + &:before + content "\e08e" + .icon-loop + &:before + content "\e08f" + .icon-arrow-up-left + &:before + content "\e090" + .icon-arrow-up + &:before + content "\e091" + .icon-arrow-up-right + &:before + content "\e092" + .icon-arrow-right + &:before + content "\e093" + .icon-arrow-down-right + &:before + content "\e094" + .icon-arrow-down + &:before + content "\e095" + .icon-arrow-down-left + &:before + content "\e096" + .icon-arrow-left + &:before + content "\e097" + .icon-arrow-up-2 + &:before + content "\e098" + .icon-arrow-right-2 + &:before + content "\e099" + .icon-arrow-down-2 + &:before + content "\e09a" + .icon-arrow-left-2 + &:before + content "\e09b" + .icon-arrow-up-3 + &:before + content "\e09c" + .icon-arrow-right-3 + &:before + content "\e09d" + .icon-arrow-down-3 + &:before + content "\e09e" + .icon-arrow-left-3 + &:before + content "\e09f" + .icon-menu + &:before + content "\e0a0" + .icon-enter-2 + &:before + content "\e0a1" + .icon-backspace + &:before + content "\e0a2" + .icon-backspace-2 + &:before + content "\e0a3" + .icon-tab + &:before + content "\e0a4" + .icon-tab-2 + &:before + content "\e0a5" + .icon-checkbox + &:before + content "\e0a6" + .icon-checkbox-unchecked + &:before + content "\e0a7" + .icon-checkbox-partial + &:before + content "\e0a8" + .icon-radio-checked + &:before + content "\e0a9" + .icon-radio-unchecked + &:before + content "\e0aa" + .icon-font + &:before + content "\e0ab" + .icon-paragraph-left + &:before + content "\e0ac" + .icon-paragraph-center + &:before + content "\e0ad" + .icon-paragraph-right + &:before + content "\e0ae" + .icon-paragraph-justify + &:before + content "\e0af" + .icon-left-to-right + &:before + content "\e0b0" + .icon-right-to-left + &:before + content "\e0b1" + .icon-share + &:before + content "\e0b2" + .icon-new-tab + &:before + content "\e0b3" + .icon-new-tab-2 + &:before + content "\e0b4" + .icon-embed + &:before + content "\e0b5" + .icon-code + &:before + content "\e0b6" + .icon-bluetooth + &:before + content "\e0b7" + .icon-share-2 + &:before + content "\e0b8" + .icon-share-3 + &:before + content "\e0b9" + .icon-mail-2 + &:before + content "\e0ba" + .icon-google + &:before + content "\e0bb" + .icon-google-plus + &:before + content "\e0bc" + .icon-google-drive + &:before + content "\e0bd" + .icon-facebook + &:before + content "\e0be" + .icon-instagram + &:before + content "\e0bf" + .icon-twitter + &:before + content "\e0c0" + .icon-feed + &:before + content "\e0c1" + .icon-youtube + &:before + content "\e0c2" + .icon-vimeo + &:before + content "\e0c3" + .icon-flickr + &:before + content "\e0c4" + .icon-picassa + &:before + content "\e0c5" + .icon-dribbble + &:before + content "\e0c6" + .icon-deviantart + &:before + content "\e0c7" + .icon-github + &:before + content "\e0c8" + .icon-github-2 + &:before + content "\e0c9" + .icon-github-3 + &:before + content "\e0ca" + .icon-github-4 + &:before + content "\e0cb" + .icon-github-5 + &:before + content "\e0cc" + .icon-git + &:before + content "\e0cd" + .icon-github-6 + &:before + content "\e0ce" + .icon-wordpress + &:before + content "\e0cf" + .icon-joomla + &:before + content "\e0d0" + .icon-blogger + &:before + content "\e0d1" + .icon-tumblr + &:before + content "\e0d2" + .icon-yahoo + &:before + content "\e0d3" + .icon-amazon + &:before + content "\e0d4" + .icon-tux + &:before + content "\e0d5" + .icon-apple + &:before + content "\e0d6" + .icon-finder + &:before + content "\e0d7" + .icon-android + &:before + content "\e0d8" + .icon-windows + &:before + content "\e0d9" + .icon-soundcloud + &:before + content "\e0da" + .icon-skype + &:before + content "\e0db" + .icon-reddit + &:before + content "\e0dc" + .icon-linkedin + &:before + content "\e0dd" + .icon-lastfm + &:before + content "\e0de" + .icon-delicious + &:before + content "\e0df" + .icon-stumbleupon + &:before + content "\e0e0" + .icon-pinterest + &:before + content "\e0e1" + .icon-xing + &:before + content "\e0e2" + .icon-flattr + &:before + content "\e0e3" + .icon-foursquare + &:before + content "\e0e4" + .icon-paypal + &:before + content "\e0e5" + .icon-yelp + &:before + content "\e0e6" + .icon-libreoffice + &:before + content "\e0e7" + .icon-file-pdf + &:before + content "\e0e8" + .icon-file-openoffice + &:before + content "\e0e9" + .icon-file-word + &:before + content "\e0ea" + .icon-file-excel + &:before + content "\e0eb" + .icon-file-powerpoint + &:before + content "\e0ec" + .icon-file-zip + &:before + content "\e0ed" + .icon-file-xml + &:before + content "\e0ee" + .icon-file-css + &:before + content "\e0ef" + .icon-html5 + &:before + content "\e0f0" + .icon-html5-2 + &:before + content "\e0f1" + .icon-css3 + &:before + content "\e0f2" + .icon-chrome + &:before + content "\e0f3" + .icon-firefox + &:before + content "\e0f4" + .icon-IE + &:before + content "\e0f5" + .icon-opera + &:before + content "\e0f6" + .icon-safari + &:before + content "\e0f7" + .icon-IcoMoon + &:before + content "\e0f8" + .icon-sunrise + &:before + content "\e0f9" + .icon-sun + &:before + content "\e0fa" + .icon-moon + &:before + content "\e0fb" + .icon-sun-2 + &:before + content "\e0fc" + .icon-windy + &:before + content "\e0fd" + .icon-wind + &:before + content "\e0fe" + .icon-snowflake + &:before + content "\e0ff" + .icon-cloudy + &:before + content "\e100" + .icon-cloud-3 + &:before + content "\e101" + .icon-weather + &:before + content "\e102" + .icon-weather-2 + &:before + content "\e103" + .icon-weather-3 + &:before + content "\e104" + .icon-lines + &:before + content "\e105" + .icon-cloud-4 + &:before + content "\e106" + .icon-lightning-2 + &:before + content "\e107" + .icon-lightning-3 + &:before + content "\e108" + .icon-rainy + &:before + content "\e109" + .icon-rainy-2 + &:before + content "\e10a" + .icon-windy-2 + &:before + content "\e10b" + .icon-windy-3 + &:before + content "\e10c" + .icon-snowy + &:before + content "\e10d" + .icon-snowy-2 + &:before + content "\e10e" + .icon-snowy-3 + &:before + content "\e10f" + .icon-weather-4 + &:before + content "\e110" + .icon-cloudy-2 + &:before + content "\e111" + .icon-cloud-5 + &:before + content "\e112" + .icon-lightning-4 + &:before + content "\e113" + .icon-sun-3 + &:before + content "\e114" + .icon-moon-2 + &:before + content "\e115" + .icon-cloudy-3 + &:before + content "\e116" + .icon-cloud-6 + &:before + content "\e117" + .icon-cloud-7 + &:before + content "\e118" + .icon-lightning-5 + &:before + content "\e119" + .icon-rainy-3 + &:before + content "\e11a" + .icon-rainy-4 + &:before + content "\e11b" + .icon-windy-4 + &:before + content "\e11c" + .icon-windy-5 + &:before + content "\e11d" + .icon-snowy-4 + &:before + content "\e11e" + .icon-snowy-5 + &:before + content "\e11f" + .icon-weather-5 + &:before + content "\e120" + .icon-cloudy-4 + &:before + content "\e121" + .icon-lightning-6 + &:before + content "\e122" + .icon-thermometer + &:before + content "\e123" + .icon-compass-2 + &:before + content "\e124" + .icon-none + &:before + content "\e125" + .icon-Celsius + &:before + content "\e126" + .icon-Fahrenheit + &:before + content "\e127" + .icon-forrst + &:before + content "\e128" + .icon-headphones + &:before + content "\e129" + .icon-bug + &:before + content "\e12a" + .icon-cart-2 + &:before + content "\e12b" + .icon-earth + &:before + content "\e12c" + .icon-battery + &:before + content "\e12d" + .icon-list + &:before + content "\e12e" + .icon-grid + &:before + content "\e12f" + .icon-alarm + &:before + content "\e130" + .icon-location-2 + &:before + content "\e131" + .icon-pointer + &:before + content "\e132" + .icon-diary + &:before + content "\e133" + .icon-eye-2 + &:before + content "\e134" + .icon-console + &:before + content "\e135" + .icon-location-3 + &:before + content "\e136" + .icon-move + &:before + content "\e137" + .icon-gift-2 + &:before + content "\e138" + .icon-monitor + &:before + content "\e139" + .icon-mobile-2 + &:before + content "\e13a" + .icon-switch + &:before + content "\e13b" + .icon-star-4 + &:before + content "\e13c" + .icon-address-book + &:before + content "\e13d" + .icon-shit + &:before + content "\e13e" + .icon-cone + &:before + content "\e13f" + .icon-credit-card + &:before + content "\e140" + .icon-type + &:before + content "\e141" + .icon-volume + &:before + content "\e142" + .icon-volume-2 + &:before + content "\e143" + .icon-locked-2 + &:before + content "\e144" + .icon-warning + &:before + content "\e145" + .icon-info + &:before + content "\e146" + .icon-filter + &:before + content "\e147" + .icon-bookmark-3 + &:before + content "\e148" + .icon-bookmark-4 + &:before + content "\e149" + .icon-stats + &:before + content "\e14a" + .icon-compass-3 + &:before + content "\e14b" + .icon-keyboard + &:before + content "\e14c" + .icon-award-fill + &:before + content "\e14d" + .icon-award-stroke + &:before + content "\e14e" + .icon-beaker-alt + &:before + content "\e14f" + .icon-beaker + &:before + content "\e150" + .icon-move-vertical + &:before + content "\e151" + .icon-move-horizontal + &:before + content "\e153" + .icon-steering-wheel + &:before + content "\e152" + .icon-volume-3 + &:before + content "\e154" + .icon-volume-mute + &:before + content "\e155" + .icon-play + &:before + content "\e156" + .icon-pause + &:before + content "\e157" + .icon-stop + &:before + content "\e158" + .icon-eject + &:before + content "\e159" + .icon-first + &:before + content "\e15a" + .icon-last + &:before + content "\e15b" + .icon-play-alt + &:before + content "\e15c" + .icon-battery-empty + &:before + content "\e15d" + .icon-battery-half + &:before + content "\e15e" + .icon-battery-full + &:before + content "\e15f" + .icon-battery-charging + &:before + content "\e160" + .icon-left-quote + &:before + content "\e161" + .icon-right-quote + &:before + content "\e162" + .icon-left-quote-alt + &:before + content "\e163" + .icon-right-quote-alt + &:before + content "\e164" + .icon-smiley + &:before + content "\e165" + .icon-umbrella + &:before + content "\e166" + .icon-info-2 + &:before + content "\e167" + .icon-chart-alt + &:before + content "\e168" + .icon-save + &:before + content "\e169" + .fg-color-blue + color #2d89ef !important + .fg-color-blueLight + color #eff4ff !important + .fg-color-blueDark + color #2b5797 !important + .fg-color-green + color #00a300 !important + .fg-color-greenLight + color #99b433 !important + .fg-color-greenDark + color #1e7145 !important + .fg-color-red + color #b91d47 !important + .fg-color-yellow + color #ffc40d !important + .fg-color-orange + color #e3a21a !important + .fg-color-orangeDark + color #da532c !important + .fg-color-pink + color #9f00a7 !important + .fg-color-pinkDark + color #7e3878 !important + .fg-color-purple + color #603cba !important + .fg-color-darken + color #1d1d1d !important + .fg-color-lighten + color #d5e7ec !important + .fg-color-white + color #ffffff !important + .fg-color-grayDark + color #525252 !important + .fg-color-magenta + color #ff0097 !important + .fg-color-teal + color #00aba9 !important + .fg-color-redLight + color #ee1111 !important + .bg-color-blue + background-color #2d89ef !important + .bg-color-blueLight + background-color #eff4ff !important + .bg-color-blueDark + background-color #2b5797 !important + .bg-color-green + background-color #00a300 !important + .bg-color-greenLight + background-color #99b433 !important + .bg-color-greenDark + background-color #1e7145 !important + .bg-color-red + background-color #b91d47 !important + .bg-color-yellow + background-color #ffc40d !important + .bg-color-orange + background-color #e3a21a !important + .bg-color-orangeDark + background-color #da532c !important + .bg-color-pink + background-color #9f00a7 !important + .bg-color-pinkDark + background-color #7e3878 !important + .bg-color-purple + background-color #603cba !important + .bg-color-darken + background-color #1d1d1d !important + .bg-color-lighten + background-color #d5e7ec !important + .bg-color-white + background-color #ffffff !important + .bg-color-grayDark + background-color #525252 !important + .bg-color-magenta + background-color #ff0097 !important + .bg-color-teal + background-color #00aba9 !important + .bg-color-redLight + background-color #ee1111 !important + [class*=border-color] + border 2px solid + .border-color-blue + border-color #2d89ef !important + .border-color-blueLight + border-color #eff4ff !important + .border-color-blueDark + border-color #2b5797 !important + .border-color-green + border-color #00a300 !important + .border-color-greenLight + border-color #99b433 !important + .border-color-greenDark + border-color #1e7145 !important + .border-color-red + border-color #b91d47 !important + .border-color-yellow + border-color #ffc40d !important + .border-color-orange + border-color #e3a21a !important + .border-color-orangeDark + border-color #da532c !important + .border-color-pink + border-color #9f00a7 !important + .border-color-pinkDark + border-color #7e3878 !important + .border-color-purple + border-color #603cba !important + .border-color-darken + border-color #1d1d1d !important + .border-color-lighten + border-color #d5e7ec !important + .border-color-white + border-color #ffffff !important + .border-color-grayDark + border-color #525252 !important + .border-color-magenta + border-color #ff0097 !important + .border-color-teal + border-color #00aba9 !important + .border-color-redLight + border-color #ee1111 !important + *:hover[class=outline-color] + outline 3px solid + .outline-color-blue + outline-color #2d89ef !important + .outline-color-blueLight + outline-color #eff4ff !important + .outline-color-blueDark + outline-color #2b5797 !important + .outline-color-green + outline-color #00a300 !important + .outline-color-greenLight + outline-color #99b433 !important + .outline-color-greenDark + outline-color #1e7145 !important + .outline-color-red + outline-color #b91d47 !important + .outline-color-yellow + outline-color #ffc40d !important + .outline-color-orange + outline-color #e3a21a !important + .outline-color-orangeDark + outline-color #da532c !important + .outline-color-pink + outline-color #9f00a7 !important + .outline-color-pinkDark + outline-color #7e3878 !important + .outline-color-purple + outline-color #603cba !important + .outline-color-darken + outline-color #1d1d1d !important + .outline-color-lighten + outline-color #d5e7ec !important + .outline-color-white + outline-color #ffffff !important + .outline-color-grayDark + outline-color #525252 !important + .outline-color-magenta + outline-color #ff0097 !important + .outline-color-teal + outline-color #00aba9 !important + .outline-color-redLight + outline-color #ee1111 !important + .item-margin + margin 0 10px 10px 0 + .column-margin + margin 0 20px 10px 0 + .group-margin + margin 0 80px 10px 0 + .brick + position relative + margin 0 10px 10px 0 + display block + float none !important + .short-brick + position relative + margin 0 10px 10px 0 + display block + float none !important + width 150px + height 150px + .medium-brick + position relative + margin 0 10px 10px 0 + display block + float none !important + width 310px + height 150px + .square + display block + float left + margin-right 10px + height 20px + width 20px + .one-column + -moz-columns 1 + -webkit-columns 1 + columns 1 + -moz-column-gap 20px + -webkit-column-gap 20px + column-gap 20px + .two-columns + -moz-columns 2 + -webkit-columns 2 + columns 2 + -moz-column-gap 20px + -webkit-column-gap 20px + column-gap 20px + .three-columns + -moz-columns 3 + -webkit-columns 3 + columns 3 + -moz-column-gap 20px + -webkit-column-gap 20px + column-gap 20px + .four-columns + -moz-columns 4 + -webkit-columns 4 + columns 4 + -moz-column-gap 20px + -webkit-column-gap 20px + column-gap 20px + .five-columns + -moz-columns 5 + -webkit-columns 5 + columns 5 + -moz-column-gap 20px + -webkit-column-gap 20px + column-gap 20px + .page + position relative + height 100% + min-height 100% + width 100% + *zoom 1 + &:after + clear both + .page-header + width 100% + position relative + display block + .page-header-content + height 100px + min-height 100px + width 100% + position relative + display block + h1 + small + font-size 12pt + margin-left 5px + &.sub-menu + cursor pointer + &:after + position absolute + content "\3009" + display inline-block + font-size 10pt + bottom -5px + right -15px + -webkit-transform rotate(90deg) + -moz-transform rotate(90deg) + -ms-transform rotate(90deg) + -o-transform rotate(90deg) + transform rotate(90deg) + & > .page-back + position absolute + top 34px + left 30px + .user-login + float right + margin 55px 44px 0 0 + cursor pointer + .avatar + float right + border 1px #ccc solid + width 40px + height 40px + .name + float left + margin -5px 10px 0 + text-align right + .first-name + font-family 'Segoe UI Light', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 200 + font-size 20pt + letter-spacing 0.01em + line-height 22pt + font-smooth always + display block + margin 0 + .last-name + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 9pt + font-smooth always + line-height 11pt + display block + margin 0 + .page-region + display block + .page-region-content + padding-top 10px + padding-left 0 + padding-right 0 + padding-bottom 20px + display block + height 100% + position relative + &.secondary + .page-region + .page-region-content + padding-left 120px + &.snapped + width 33.33% + height 100% + float left + border-right 1px #ccc solid + .page + .page-region + .page-region-content + padding-left 20px + &.fill + width 66.66% + height 100% + float right + border-left 1px #ccc solid + &.fixed-header + .page-header + position fixed + top 0 + left 0 + right 0 + .page-region + padding-top 140px + &.with-sidebar + .page-region + margin-left 220px + width auto + *zoom 1 + .page-region-content + padding-left 20px + &:after + clear both + .app-bar + position fixed + bottom 0 + left 0 + right 0 + min-height 100px + background-color #1d1d1d !important + .charms + position fixed + right 0 + top 0 + bottom 0 + height 100% + min-width 200px + width auto + &.place-left + left 0 + right auto + .message-dialog + position fixed + left 0 + right 0 + height auto + min-height 100px + top 30% + padding 10px 10px 0 + .error-bar + background-color #b91d47 !important + .warning-bar + background-color #ffc40d !important + .info-bar + background-color #2d89ef !important + .back-button + height 32px + width 32px + display block + background-image url(data:image/png + -webkit-background-size cover + -moz-background-size cover + -o-background-size cover + background-size cover + &.big + height 48px + width 48px + left 36px + top 40px + &.white + background-image url(data:image/png + a + &.button + &.big + padding 14px 10px + &.shortcut + padding 12px 0 + .label + font-size 9pt + .tool-button + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 9pt + font-smooth always + line-height 11pt + font-size 14px + display inline-block + padding 4px 12px + line-height 20px + vertical-align middle !important + min-width 90px + background-color #ccc + border 1px transparent solid + color #353535 + margin-right 10px + margin-bottom 10px + border-raduis 0 + cursor pointer + width auto + *zoom 1 + min-width 32px + min-height 32px + width 32px + height 32px + text-align center + position relative + padding 0 + &.mini + min-width 22px + width 22px + min-height 20px + min-width 20px + height 14px + font-size .75em !important + padding-top 0px !important + &.big + min-width 48px + width 48px + min-height 48px + height 48px + font-size 1.2em + &:after + clear both + &.standart + min-width 90px + min-height 32px + &.default + background-color #008287 + color #fff + &:focus + outline 0 + border 1px #353535 dotted + img + width 16px + height 16px + top 8px + .command-button + display inline-block + width 330px + text-align left + padding 10px 20px + height auto + color #000 + background-color #ccc + font-family 'Segoe UI Semilight', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 300 + font-size 11pt + letter-spacing 0.02em + line-height 14pt + font-smooth always + & > small + display block + font-family 'Segoe UI Semilight', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 300 + font-size 11pt + letter-spacing 0.02em + line-height 14pt + font-smooth always + font-size 10pt + color #505050 + &.default + & > small + color #ccc + .toolbar + *zoom 1 + a + padding 5px 0 + &:after + clear both + .toolbar-group + margin-right 20px + margin-bottom 10px + float left + .toolbar-vertical + width 33px + float left + margin-right 10px + *zoom 1 + a + padding 5px 0 + &:after + clear both + .toolbar-group + margin-bottom 20px + .image-button + position relative + border 0 + padding-right 45px + .button-set + a + padding 5px 0 + button + &.active + background-color #008287 + color #fff + .shortcuts + margin-bottom 10px + .shortcut + width 92px + height 92px + display inline-block + margin 0 10px 10px 0 + vertical-align top + text-decoration none + background #F3F3F3 + text-align center + cursor pointer + border 0 + border-bottom 2px transparent solid + position relative + &:hover + border-color red + &:active + background #F3F3F3 + top 1px + left 1px + & > .icon + margin-top .25em + margin-bottom .25em + color #888 + display block + float none + & > .label + display block + font-weight 400 + color #666 + & > .badge + position absolute + right 0 + top 0 + background-color #2d89ef + padding 5px + margin 0 !important + text-align center + display block + font-size 9pt + color #fff + line-height 11pt + .pagination + width auto + margin-bottom 10px + & > ul + margin-left 0 + list-style none + margin 0 + li + display inline-block + margin-right 1px + position relative + a + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 9pt + font-smooth always + line-height 11pt + font-size 14px + display inline-block + padding 4px 12px + line-height 20px + vertical-align middle !important + min-width 90px + background-color #ccc + border 1px transparent solid + color #353535 + margin-right 10px + margin-bottom 10px + border-raduis 0 + width auto + *zoom 1 + min-height 32px + width 32px + padding 0 + position relative + display block + float left + font-size 10pt + padding 5px + min-width 32px + height 32px + text-align center + vertical-align middle + cursor pointer + margin-right 1px + &.mini + min-height 20px + min-width 20px + height 14px + font-size .75em !important + padding-top 0px !important + min-width 22px + width 22px + min-height 20px + min-width 20px + height 14px + font-size .75em !important + padding-top 0px !important + &.big + min-height 48px + height 48px + font-size 1.2em + min-width 48px + width 48px + min-height 48px + height 48px + font-size 1.2em + &:after + clear both + &.standart + min-width 90px + min-height 32px + &.default + background-color #008287 + color #fff + &:focus + outline 0 + border 1px #353535 dotted + img + width 16px + height 16px + top 8px + &:hover + background-color #1d1d1d + color #ffffff + &:active + top 1px + left 1px + &.first + a + &:before + content "\AB" + margin-left -10px + &.prev + a + &:before + content "\2039" + &.next + a + &:before + content "\203A" + &.last + a + &:before + content "\BB" + margin-left -10px + &.active + a + background-color #008287 + color #ffffff + &.disabled + a + color #1e1e1e + &.spaces + a + background-color #ffffff + cursor default + table + width 100% + border-collapse separate + margin 0 0 20px + tbody + tr + border 1px #fff solid + td + font-family 'Segoe UI Semilight', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 300 + font-size 11pt + letter-spacing 0.02em + line-height 14pt + font-smooth always + padding 3px 10px + border-right 1px #ddd solid + border-bottom 1px #ddd solid + border-left 1px transparent solid + border-top 1px transparent solid + box-sizing border-box + &.right + text-align right + &.center + text-align center + &.last + border-right 1px transparent solid + &:last-child + border-right 1px transparent solid + &.success + background-color #00a300 !important + &.error + background-color #b91d47 !important + &.warning + background-color #e3a21a !important + &.info + background-color #2d89ef !important + &.selected-row + background-color rgba(28, 183, 236, 0.1) !important + td + border-top 1px #1c98cc solid + border-bottom 1px #1c98cc solid + &:first-child + border-left 1px #1c98cc solid + &:last-child + border-right 1px #1c98cc solid + &.striped + tbody + tr + &:nth-child(odd) + background-color #f9f9f9 + &.hovered + border-collapse separate !important + tbody + tr + &:hover + background-color rgba(28, 183, 236, 0.1) + td + border-top 1px #1c98cc solid + border-bottom 1px #1c98cc solid + &:first-child + border-left 1px #1c98cc solid + &:last-child + border-right 1px #1c98cc solid + &.bordered + border-collapse separate !important + border 1px #ccc solid !important + tbody + tr + &:last-child + td + border-bottom 0 + .ot + width 31% + .tt + width 65% + .cl + clear both + .item-padding + margin-right 20px + margin-bottom 5px + .column-padding + margin 0 10px + .group-padding + margin 0 40px + .span1 + width 60px + .span2 + width 140px + .span3 + width 220px + .span4 + width 300px + .span5 + width 380px + .span6 + width 460px + .span7 + width 540px + .span8 + width 620px + .span9 + width 700px + .span10 + width 780px + .span11 + width 860px + .span12 + width 940px + .offset1 + margin-left 80px + .offset2 + margin-left 160px + .offset3 + margin-left 240px + .offset4 + margin-left 320px + .offset5 + margin-left 400px + .offset6 + margin-left 480px + .offset7 + margin-left 560px + .offset8 + margin-left 640px + .offset9 + margin-left 720px + .offset10 + margin-left 800px + .offset11 + margin-left 880px + .offset12 + margin-left 960px + [class*="span"] + float none + min-height 1px + margin-right 20px + margin-bottom 5px + *zoom 1 + & > img + max-width 100% + height auto + [class*="span"]:after + clear both + [class*="span"]:last-child + margin-right 0 + .grid + margin 0 0 20px + display block + height auto + width 100% + *zoom 1 + &.no-margin + margin 0 + &.margin-row + margin-bottom 5px + .grid + margin-top 2.5px + margin-bottom 2.5px + .group + margin-right 80px + float left + width auto + height auto + min-height 1px + .row + width 100% + *zoom 1 + &:after + clear both + [class*="span"] + float left + &.element-border + [class*="span"] + border 1px #ccc dotted + &:after + clear both + .hero-unit + position relative + margin 0 0 10px + padding 20px + background-color #f1f1f1 + width 100% + *zoom 1 + &:after + clear both + .dropdown-menu + position absolute + background-color #fff + margin-left 0 + list-style none + top 100% + z-index 11010 + float left + border 1px solid rgba(0, 0, 0, 0.2) + box-shadow 0 5px 10px rgba(0, 0, 0, 0.2) + min-width 160px + padding-bottom 5px + padding-top 5px + padding-left 0 + display none + &.place-right + right 0 + left auto + a + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 11pt + letter-spacing 0.01em + line-height 13pt + font-smooth always + color #000000 + display block + width 100% + padding 3px 20px + white-space nowrap + font-size 14px + cursor pointer + &:hover + color rgba(0, 0, 0, 0.8) + background-color #2d89ef !important + color #ffffff !important + &:active + color rgba(0, 0, 0, 0.4) + li + display list-item + line-height 20px + .divider + height 1px + margin 9px 1px + overflow hidden + background-color #e5e5e5 + &.open + display block !important + .nav-bar + background-color #2d89ef + position relative + top 0 + width 100% + display block + margin 0 + padding 0 + z-index 1000 + *zoom 1 + .nav-bar-inner + *zoom 1 + & > ul + &.menu + margin-left 0 + list-style none + padding 0 + margin 0 + & > li + display block + float left + margin-right 5px + position relative + padding 5px 15px 5px 5px + a + display block + float left + color #ffffff + font-size 10pt + ul + &.dropdown-menu + z-index 1001 + border 0 + left 0px + li + a + display block + float none + color #1e1e1e + padding 3px 20px + &.open + display block !important + [data-role=dropdown] + margin-right 20px !important + & > a + cursor pointer + &:before + position absolute + content "\203A" + display block + font-size 1.4em + left 100% + margin-left -10px + top 8px + -webkit-transform rotate(90deg) + -moz-transform rotate(90deg) + -ms-transform rotate(90deg) + -o-transform rotate(90deg) + transform rotate(90deg) + .pull-menu + display none + float right + color #fff + cursor pointer + font 1.8em sans-serif + margin-right 0px + position relative + height 20px + width 20px + line-height 20px + &:before + content "\2261" + position absolute + font-size 20pt + top 5px + left 0 + &:after + clear both + &.container + width 940px + margin auto + &.bg-color-blue + .nav-bar-inner + .menu + li + a + &:hover + background-color #2d89ef !important + &.bg-color-blueLight + .nav-bar-inner + .menu + li + a + &:hover + background-color #eff4ff !important + &.bg-color-blueDark + .nav-bar-inner + .menu + li + a + &:hover + background-color #2b5797 !important + &.bg-color-green + .nav-bar-inner + .menu + li + a + &:hover + background-color #00a300 !important + &.bg-color-greenLight + .nav-bar-inner + .menu + li + a + &:hover + background-color #99b433 !important + &.bg-color-greenDark + .nav-bar-inner + .menu + li + a + &:hover + background-color #1e7145 !important + &.bg-color-red + .nav-bar-inner + .menu + li + a + &:hover + background-color #b91d47 !important + &.bg-color-yellow + .nav-bar-inner + .menu + li + a + &:hover + background-color #ffc40d !important + &.bg-color-orange + .nav-bar-inner + .menu + li + a + &:hover + background-color #e3a21a !important + &.bg-color-orangeDark + .nav-bar-inner + .menu + li + a + &:hover + background-color #da532c !important + &.bg-color-pink + .nav-bar-inner + .menu + li + a + &:hover + background-color #9f00a7 !important + &.bg-color-pinkDark + .nav-bar-inner + .menu + li + a + &:hover + background-color #7e3878 !important + &.bg-color-purple + .nav-bar-inner + .menu + li + a + &:hover + background-color #603cba !important + &.bg-color-darken + .nav-bar-inner + .menu + li + a + &:hover + background-color #1d1d1d !important + &.bg-color-lighten + .nav-bar-inner + .menu + li + a + &:hover + background-color #d5e7ec !important + &.bg-color-white + .nav-bar-inner + .menu + li + &:hover + background-color #e6e6e6 !important + a + color #1d1d1d !important + &:hover + background-color #e6e6e6 !important + .element + color #1d1d1d !important + .pull-menu + color #1d1d1d !important + &.bg-color-grayDark + .nav-bar-inner + .menu + li + a + &:hover + background-color #525252 !important + &.bg-color-magenta + .nav-bar-inner + .menu + li + a + &:hover + background-color #ff0097 !important + &.bg-color-teal + .nav-bar-inner + .menu + li + a + &:hover + background-color #00aba9 !important + &.bg-color-redLight + .nav-bar-inner + .menu + li + a + &:hover + background-color #ee1111 !important + &:after + clear both + &.fixed-top + top 0 + bottom auto + &.fixed-bottom + bottom 0 + top auto + .side-nav + ul + margin 0 + padding 0 + list-style none + margin-bottom 20px + .title + color #4f4f4f + font-family Segoe UI, Arial, Verdana, Tahoma, sans-serif + font-size 12pt + margin 0 0 5px 0 + border-bottom 1px #ccc solid + & > li + & > a + display block + padding 3px 10px 3px 0 + position relative + color #014E85 + padding-left 3px + font-size 10pt + &.close + & > li + display none + & > li[class^=title] + display list-item + .page-sidebar + display block + width 213px + float left + min-height 100% !important + height auto + background-color #EBEBEB + padding-top 10px + padding-bottom 10px + margin-top 10px + margin-left 7px + a + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 11pt + letter-spacing 0.01em + line-height 13pt + font-smooth always + color #000000 + display block + width 100% + padding 5px 20px 5px 10px + white-space nowrap + font-size 14px + cursor pointer + &:hover + color rgba(0, 0, 0, 0.8) + background-color #2d89ef !important + color #ffffff !important + &:active + color rgba(0, 0, 0, 0.4) + li + display list-item + line-height 20px + position relative + & > ul + & > li + & > a + font-size 1.1em + &.sticker + &:before + content "." + position absolute + width 7px + height 28px + left -7px + text-indent -9999px + border-top-left-radius 10px + border-bottom-left-radius 10px + background-color #ebebeb + &.sticker-color-blue + &:before + background-color #2d89ef + &.sticker-color-blueLight + &:before + background-color #eff4ff + &.sticker-color-blueDark + &:before + background-color #2b5797 + &.sticker-color-green + &:before + background-color #00a300 !important + &.sticker-color-greenLight + &:before + background-color #99b433 !important + &.sticker-color-greenDark + &:before + background-color #1e7145 !important + &.sticker-color-red + &:before + background-color #b91d47 !important + &.sticker-color-yellow + &:before + background-color #ffc40d !important + &.sticker-color-orange + &:before + background-color #e3a21a !important + &.sticker-color-orangeDark + &:before + background-color #da532c !important + &.sticker-color-pink + &:before + background-color #9f00a7 !important + &.sticker-color-pinkDark + &:before + background-color #7e3878 !important + &.sticker-color-purple + &:before + background-color #603cba !important + &.sticker-color-darken + &:before + background-color #1d1d1d !important + &.sticker-color-white + &:before + background-color #ffffff !important + &.sticker-color-grayDark + &:before + background-color #525252 !important + &.dropdown + position relative + &:after + content "" + display block + position absolute + top 6px + left 100% + margin-left -20px + width 16px + height 16px + background no-repeat + background-position 0 -1586px + z-index 200 + &.active + &:after + background-position 0 -676px + .divider + height 1px + margin 9px 1px + overflow hidden + background-color #e5e5e5 + ul + margin-left 0 + list-style none + background-color #EBEBEB + &.sub-menu + padding-top 5px + padding-bottom 5px + a + padding 5px 20px 5px 25px + &.light + background-color #f9f9f9 !important + .sidebar-dropdown-menu + display none + &.open + display block + .replies + margin-left 0 + list-style none + .notices + list-style none + margin 0 + padding 0 + .tile-group + margin 0 + margin-right 80px + float left + width auto + height auto + min-height 1px + width 802px + .tile + display block + float left + background-color #525252 + width 150px + height 150px + cursor pointer + box-shadow inset 0px 0px 1px #FFFFCC + text-decoration none + color #ffffff + position relative + font-family 'Segoe UI Semilight', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 300 + font-size 11pt + letter-spacing 0.02em + line-height 14pt + font-smooth always + margin 0 10px 10px 0 + overflow hidden + * + color #ffffff + .tile-content + width 100% + height 100% + padding 0 + padding-bottom 30px + vertical-align top + padding 10px 15px + overflow hidden + text-overflow ellipsis + position relative + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 9pt + font-smooth always + line-height 11pt + color #000000 + color #ffffff + line-height 16px + &:hover + color rgba(0, 0, 0, 0.8) + color #ffffff + &:active + color rgba(0, 0, 0, 0.4) + p + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 9pt + font-smooth always + line-height 11pt + color #000000 + color #ffffff + line-height 16px + overflow hidden + text-overflow ellipsis + &:hover + color rgba(0, 0, 0, 0.8) + color #ffffff + &:active + color rgba(0, 0, 0, 0.4) + &.icon + & > .tile-content + padding 0 + & > img + position absolute + width 64px + height 64px + top 50% + left 50% + margin-left -32px + margin-top -32px + & > i + position absolute + width 64px + height 64px + top 50% + left 50% + margin-left -32px + margin-top -32px + font-size 64px + &.image-set + & > .tile-content + margin 0 + padding 0 + width 25% !important + height 50% + float left + border 1px #1e1e1e solid + & > img + min-width 100% + width 100% + height auto + min-height 100% + .tile-content + &:first-child + width 50% !important + float left + height 100% + &.double + width 310px + &.triple + width 470px + &.quadro + width 630px + &.double-vertical + height 310px + &.triple-vertical + height 470px + &.quadro-vertical + height 630px + &:hover + outline 3px #3a3a3a solid + .input-control + margin-right 0px + margin-bottom 10px + position relative + &.checkbox + display inline-block + margin-right 10px + margin-bottom 10px + cursor pointer + & > input[type=checkbox] + position absolute + opacity 0 + .helper + padding-left 23px + position relative + &:before + position absolute + display block + height 20px + width 20px + content "" + text-indent -9999px + border 2px #d9d9d9 solid + z-index 1 + opacity 1 + top 0 + left 0 + input[type="checkbox"]:checked + & ~ .helper + &:after + position absolute + display block + content "\e08a" + font-size 10pt + heigth 14px + width 14px + line-height 14px + z-index 2 + top 50% + margin-top -6px + left 0 + margin-left 4px + font-family iconFont + input[type="checkbox"]:not(:checked) + & ~ .helper + &:after + display none + input[type="checkbox"]:disabled + & ~ .helper + &:before + cursor default + background #e6e6e6 + input[type=checkbox]:disabled + & ~ .helper + &:after + color #8a8a8a + input[type=checkbox]:focus + & ~ .helper + &:before + border-color #919191 + &:hover + input[type=checkbox]:not(:disabled) + & ~ .helper + &:before + border-color #919191 + &:active + input[type=checkbox]:not(:disabled) + & ~ .helper + &:before + border-color #1e1e1e + &.intermediate + input[type="checkbox"] + & ~ .helper + &:after + position absolute !important + display block !important + content "" !important + color #1a1a1a !important + z-index 2 !important + font-size 16px !important + font-weight bold !important + left 5px !important + margin-left 0 !important + top 50% !important + margin-top -5px !important + background-color #1a1a1a !important + width 10px !important + height 10px !important + input[type="checkbox"]:disabled + & ~ .helper + &:after + background-color #9a9a9a !important + &.radio + display inline-block + margin-right 10px + margin-bottom 10px + cursor pointer + & > input[type=radio] + position absolute + opacity 0 + .helper + padding-left 23px + position relative + &:before + position absolute + display block + height 20px + width 20px + content "" + text-indent -9999px + border 2px #d9d9d9 solid + z-index 1 + opacity 1 + top 0 + left 0 + border-radius 100% + input[type="radio"]:checked + & ~ .helper + &:after + position absolute + display block + content "" + color #1a1a1a + z-index 2 + font-size 16px + font-weight bold + left 5px + margin-left 0 + top 50% + margin-top -5px + background-color #1a1a1a + width 10px + height 10px + border-radius 100% + input[type="radio"]:disabled + & ~ .helper + &:before + cursor default + background #e6e6e6 + &:after + background-color #8a8a8a + input[type="radio"]:focus + & ~ .helper + &:before + border-color #919191 + &:hover + input + &:not(:disabled) + & ~ .helper + &:before + border-color #919191 + &:active + input + &:not(:disabled) + & ~ .helper + &:before + border-color #1e1e1e + &.switch + display inline-block + margin-right 10px + margin-bottom 10px + cursor pointer + position relative + & > input[type=checkbox] + position absolute + opacity 0 + .helper + padding-left 52px + position relative + &:before + position absolute + left 0 + top 2px + display block + content "" + width 43px + height 16px + outline 2px #a6a6a6 solid + border 1px #fff solid + cursor pointer + background #008287 + margin-left 2px + z-index 1 + input[type="checkbox"] + & ~ .helper + &:after + position absolute + left 36px + top 2px + display block + content "" + width 9px + height 16px + outline 2px #333 solid + border 1px #333 solid + cursor pointer + background #333 + z-index 2 + input[type="checkbox"]:not(:checked) + & ~ .helper + &:after + left 2px !important + &:before + background #a6a6a6 !important + input[type="checkbox"]:disabled + & ~ .helper + &:after + background #a6a6a6 !important + outline 2px #a6a6a6 solid !important + border 1px #a6a6a6 solid !important + &:before + cursor default !important + background #e0e0e0 !important + outline 2px #ccc solid !important + input[type="checkbox"]:focus + & ~ .helper + &:before + outline 2px #747474 solid !important + & > input[type=password]::-ms-reveal + display none + & > select + padding-right 5px + & > textarea + padding-right 5px + min-height 100px + &.text + .btn-search + &:before + content "\e041" + .btn-date + &:before + content "\e020" + label + font-family 'Segoe UI Semilight', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 300 + font-size 11pt + letter-spacing 0.02em + line-height 14pt + font-smooth always + margin-right 10px + margin-bottom 10px + fieldset + position relative + margin-top 30px + border 2px #eaeaea solid + padding 10px + legend + padding-left 10px + padding-right 10px + font-family 'Segoe UI Semilight', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 300 + font-size 11pt + letter-spacing 0.02em + line-height 14pt + font-smooth always + color #cfcfcf + position absolute + top -25px + left -10px + input[type=submit] + background-color #008287 + color #fff + .image-collection + position relative + margin-left 0 + list-style none + *zoom 1 + &:after + clear both + &.p16x9 + & > div + width 220px + height 121px + &.p4x3 + & > div + width 220px + height 165px + .image-container + position relative + padding 5px 5px 50px + background-color #1e1e1e + width 220px + margin-right 20px + margin-bottom 20px + img + width 100% + height auto + & > .overlay + position absolute + bottom 0 + left 0 + right 0 + height 50px + font-size 8pt + color #fff + line-height 14px + padding 0 5px + overflow hidden + text-overflow ellipsis + &.light + background-color #ccc + & > .overlay + color #1e1e1e + .card + width 75px + height 105px + border 1px #eaeaea solid + border-radius 0px + position relative + float left + display block + margin-right 10px + margin-bottom 10px + cursor pointer + background #fff + font-family 'Segoe UI Light', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 200 + font-size 20pt + letter-spacing 0.01em + line-height 22pt + font-smooth always + font-family Tahoma, Arial, sans-serif + line-height 18pt + &:hover + box-shadow 1px 1px 1px #ccc + .suit + padding 0 + font-size 80px + position absolute + right 5px + bottom 30px + &:after + position relative + bottom 10px + .small-suit + &:after + top 5px + left 13px + position absolute + &:before + top 22px + left 10px + position absolute + &.two + .small-suit + &:after + content "2" + &.three + .small-suit + &:after + content "3" + &.four + .small-suit + &:after + content "4" + &.five + .small-suit + &:after + content "5" + &.six + .small-suit + &:after + content "6" + &.seven + .small-suit + &:after + content "7" + &.eight + .small-suit + &:after + content "8" + &.nine + .small-suit + &:after + content "9" + &.ten + .small-suit + &:after + content "10" + margin-left -7px + &.jack + .small-suit + &:after + content "J" + &.dame + .small-suit + &:after + content "Q" + &.king + .small-suit + &:after + content "K" + &.ace + .small-suit + &:after + content "A" + &.joker + background #ffffff url(data:image/jpeg + &.back + background-color #b91d47 + background-image -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)) + background-image -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent) + background-image -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent) + background-image -ms-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent) + background-image -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent) + background-image linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent) + &.spades + .small-suit + &:after + color black + &:before + font-family iconFont + content "\e009" + color black + .suit + &:after + font-size 40pt + font-family iconFont + content "\e009" + color black + &.clubs + .small-suit + &:after + color black + &:before + font-family iconFont + content "\e00a" + color black + .suit + &:after + font-size 40pt + font-family iconFont + content "\e00a" + color black + &.diamonds + .small-suit + &:after + color red + &:before + font-family iconFont + content "\e00b" + color red + .suit + &:after + font-size 40pt + font-family iconFont + content "\e00b" + color red + &.hearts + .small-suit + &:after + color red + &:before + font-family iconFont + content "\e07f" + color red + .suit + &:after + font-size 40pt + font-family iconFont + content "\e07f" + color red + .red + color red + .black + color black + code + padding 2px 4px + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 9pt + font-smooth always + line-height 11pt + color #d14 + background-color #f7f7f9 + border 1px #e1e1e8 solid + pre + display block + padding 10px + margin 0 + line-height 14pt + word-break break-all + word-wrap break-word + white-space pre + white-space pre-wrap + background-color #f5f5f5 + border 1px solid rgba(0, 0, 0, 0.15) + &.prettyprint + margin-bottom 10px + code + padding 0 + color inherit + background-color transparent + border 0 + .page-control + position relative + *zoom 1 + &:after + clear both + & > ul + margin-left 0 + list-style none + *zoom 1 + position absolute + z-index 5 + width 100% + background-color rgba(217, 217, 217, 0.16) + height 31px + &:after + clear both + li + float left + display block + text-align center + height 100% + &:first-child + margin-left 20px + img + float left + width 16px + height 16px + margin-right 5px + margin-top 3px + &.active + border 1px #ccc solid + border-bottom 0 + background-color #fff + &.tabs-right + & > ul + li + float right !important + margin-left 10px + .frames + margin-top 30px + width 100% + min-height 50px + border 1px #ccc solid + .frame + width 100% + min-height 100% + height auto + display none + padding 20px + &.active + display block + ul + display block + overflow visible + .accordion + margin-left 0 + list-style none + *zoom 1 + margin-bottom 10px + &:after + clear both + & > li + margin-bottom 5px + display block + & > a + display block + height 32px + background url(data:image/png + background-color rgba(217, 217, 217, 0.16) + padding-left 36px + padding-top 5px + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 11pt + letter-spacing 0.01em + line-height 13pt + font-smooth always + & > div + border 1px #ccc dotted + padding 10px + margin-top 5px + display none + &.active + & > a + background-image url(data:image/png + background-color #d9d9d9 + & > div + display block + &.dark + & > li + & > a + background-color #464646 + background-image url(data:image/png + color #fff + &.active + & > a + background-color #1e1e1e + background-image url(data:image/png + .static-rating + background url(data:image/png + height 26px + width 134px + margin-bottom 10px + *zoom 1 + .rating-value + background url(data:image/png + background-position left -26px + height 26px + width 0 + &.small + background url(data:image/png + height 12px + width 70px + margin-bottom 5px + .rating-value + background url(data:image/png + background-position left -13px + height 12px + width 0 + &:after + clear both + .rating + *zoom 1 + a + float left + display block + width 26px + height 26px + position relative + background url(data:image/png + &.rated + background-position 0 -26px + &.hover + background-position 0 -52px + &.small + a + float left + display block + width 12px + height 12px + position relative + background url(data:image/png + &.rated + background-position 0 -13px + &.hover + background-position 0 -26px + &:after + clear both + .progress-bar + height 5px + width 100% + margin-bottom 10px + *zoom 1 + .bar + float left + width 0 + background-color #008287 + height 100% + &:after + clear both + .carousel + display block + position relative + margin-bottom 20px + .slides + width 100% + height 100% + overflow hidden + position relative + .slide + position absolute + left 0 + top 0 + width 100% + height 100% + &.image + img + width 100% + height 100% + .description + position absolute + left 0 + right 0 + bottom 0 + padding 10px + background rgba(0, 0, 0, 0.7) + color #fff + .control + position absolute + top 50% + left 15px + width 40px + height 45px + margin-top -20px + font-size 48pt + font-weight 100 + line-height 30px + color #fff + text-align center + cursor pointer + opacity .75 + &.right + left auto + right 15px + &:hover + opacity 1 + .markers + & > ul + margin-left 0 + list-style none + position absolute + top 100% + left 0 + padding-top 10px + li + display block + float left + margin-right 5px + a + width 32px + height 6px + background-color red + display block + float left + &.active + a + background-color #1e1e1e + .listview + margin-left 0 + list-style none + *zoom 1 + li + margin-bottom 10px + border 4px transparent solid + padding 10px + width 300px + position relative + display block + cursor pointer + *zoom 1 + .icon + width 48px + height 48px + font-size 40px + float left + img + width 100% + height 100% + i + margin-top 10px + .data + margin-left 55px + h4 + margin 0 + padding 0 0 2px 0 + p + margin 0 + font-size 9pt + &:hover + outline 3px #ccc solid + &:active + outline 3px #3e3e3e solid + &:after + clear both + div + &.badge + position absolute + left -4px + top -4px + background-color #2d89ef + padding 5px + margin 0 !important + text-align center + display block + font-size 9pt + color #ffffff + &.strech + padding 0 5px + &.right + right -4px + left auto + &.bottom + top auto + bottom -4px + &.image + li + width 380px + .icon + width 100px + height 100px + border 1px #ccc solid + .data + margin-left 110px + h4 + margin-bottom 4px + p + line-height 16px + font-size 10pt + margin-bottom 5px + &.iconic + li + .icon + width 32px + height 32px + border 1px #ccc solid + .data + margin-left 40px + &.fluid + li + float left + margin-right 10px + & > li + &.selected + border 4px #2d89ef solid + &:after + width 0 + height 0 + border-top 40px solid #2d89ef + border-left 40px solid transparent + position absolute + display block + right 0 + content "" + top 0 + z-index 1001 + &:before + position absolute + content "\e08a" + color #fff + right 4px + top 0 + font-family iconFont + z-index 1002 + display block + &:after + clear both + .slider + height 12px + width auto + position relative + background-color #c6c6c6 + margin-bottom 10px + .marker + height 12px + width 12px + cursor pointer + position absolute + top 0 + left 0 + background-color #000000 + z-index 3 + .complete + height 100% + width auto + background-color #00828b + z-index 2 + &.vertical + height auto + width 12px + .complete + position absolute + height auto + width 12px + bottom 0 + &:hover + .complete + background-color #219297 + .dialog + position absolute + top 40% + left 40% + min-width 150px + min-height 155px + z-index 1000 + box-shadow 0 5px 10px rgba(0, 0, 0, 0.2) + .header + font-family 'Segoe UI Light', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 200 + font-size 20pt + letter-spacing 0.01em + line-height 22pt + font-smooth always + width auto + height 35px + padding 0px 35px 5px 5px + font-size 18px + white-space nowrap + overflow hidden + background-color #2D89EF + color #fff + border 1px solid #2D89EF + border-bottom 0 none + div + position absolute + right -5px + top 5px + button + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 9pt + font-smooth always + line-height 11pt + font-size 14px + display inline-block + padding 4px 12px + line-height 20px + vertical-align middle !important + min-width 90px + background-color #ccc + border 1px transparent solid + color #353535 + margin-right 10px + margin-bottom 10px + border-raduis 0 + cursor pointer + width auto + *zoom 1 + min-width 32px + min-height 32px + width 32px + height 32px + text-align center + position relative + padding 0 + width 24px !important + height 24px !important + min-height 24px + min-width 24px + &.mini + min-height 20px + min-width 20px + height 14px + font-size .75em !important + padding-top 0px !important + min-width 22px + width 22px + min-height 20px + min-width 20px + height 14px + font-size .75em !important + padding-top 0px !important + &.big + min-height 48px + height 48px + font-size 1.2em + min-width 48px + width 48px + min-height 48px + height 48px + font-size 1.2em + &:after + clear both + &.standart + min-width 90px + min-height 32px + &.default + background-color #008287 + color #fff + &:focus + outline 0 + border 1px #353535 dotted + img + width 16px + height 16px + top 8px + .content + min-height 85px + padding 20px + background-color #FFFFFF + border-left 1px solid rgba(0, 0, 0, 0.2) + border-right 1px solid rgba(0, 0, 0, 0.2) + font-family 'Segoe UI Semilight', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 300 + font-size 11pt + letter-spacing 0.02em + line-height 14pt + font-smooth always + .action + position relative + bottom 0 + width auto + height 40px + font-size 18px + text-align center + white-space nowrap + overflow hidden + background-color #FFFFFF + border-left 1px solid rgba(0, 0, 0, 0.2) + border-right 1px solid rgba(0, 0, 0, 0.2) + border-bottom 1px solid rgba(0, 0, 0, 0.2) + #dialogOverlay + width 100% + height 100% + position fixed + top 0 + left 0 + background-color rgba(235, 235, 235, 0.5) + z-index 1 + .calendar + background-color #ffffff !important + table + border 1px #ccc solid + width 100% + border-collapse collapse + margin 0 + tr + height 1px + tr + &:empty + display none + td + cursor pointer + position relative + height 100% + span + font-size 8px !important + line-height 10px + position absolute + top 0 + right 0 + padding 1px 3px + background-color #b91d47 !important + color #ffffff !important + .out + background #ececf0 + cursor default + .empty-day + border 0 !important + display none + .weekdays + td + background-color #eff4ff !important + font-weight bold !important + .current-day + background-color #00a300 !important + color #ffffff !important + .event + background-color #2d89ef !important + color #ffffff !important + .datepicker + position relative + +@font-face + font-family "PT Serif Caption" + font-style normal + font-weight 400 + src local("PT Serif Caption"), local("PTSerif-Caption"), url(https://themes.googleusercontent.com/static/fonts/ptserifcaption/v4/7xkFOeTxxO1GMC1suOUYWWhBabBbEjGd1iRmpyoZukE.woff) format('woff') + font-family "Open Sans" + font-style normal + font-weight 700 + src local("Open Sans Bold"), local("OpenSans-Bold"), url(https://themes.googleusercontent.com/static/fonts/opensans/v6/k3k702ZOKiLJc3WVjuplzJ1r3JsPcQLi8jytr04NNhU.woff) format('woff') + font-family "Open Sans" + font-style normal + font-weight 300 + src local("Open Sans Light"), local("OpenSans-Light"), url(https://themes.googleusercontent.com/static/fonts/opensans/v6/DXI1ORHCpsQm3Vp6mXoaTZ1r3JsPcQLi8jytr04NNhU.woff) format('woff') + font-family "Open Sans" + font-style normal + font-weight 800 + src local("Open Sans Extrabold"), local("OpenSans-Extrabold"), url(https://themes.googleusercontent.com/static/fonts/opensans/v6/EInbV5DfGHOiMmvb1Xr-hp1r3JsPcQLi8jytr04NNhU.woff) format('woff') + font-family "Open Sans" + font-style normal + font-weight 400 + src local("Open Sans"), local("OpenSans"), url(https://themes.googleusercontent.com/static/fonts/opensans/v6/K88pR3goAWT7BTt32Z01mz8E0i7KZn-EPnyo3HZu7kw.woff) format('woff') + font-family "iconFont" + src url('../fonts/iconFont.eot') + src url('../fonts/iconFont.eot?#iefix') format('embedded-opentype'), url('../fonts/iconFont.svg#iconFont') format('svg'), url('../fonts/iconFont.woff') format('woff'), url('../fonts/iconFont.ttf') format('truetype') + font-weight normal + font-style normal + +.metrouicss #font .subheader, +.metrouicss #font .subheader-secondary + font-family 'Segoe UI Light', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 200 + font-size 20pt + letter-spacing 0.01em + line-height 22pt + font-smooth always + +.metrouicss #font .subheader-smaller, +.metrouicss #font .subheader-secondary-smaller + font-family 'Segoe UI Light', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 200 + letter-spacing 0.01em + line-height 18pt + font-size 16pt + font-smooth always + +.metrouicss #font .small-subheader, +.metrouicss #font .small-subheader-secondary + font-family 'Segoe UI Semibold', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 600 + font-size 11pt + letter-spacing 0.01em + line-height 13pt + font-smooth always + +.metrouicss #font .body, +.metrouicss #font .body-secondary, +.metrouicss #font .normal + font-family 'Segoe UI Semilight', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 300 + font-size 11pt + letter-spacing 0.02em + line-height 14pt + font-smooth always + +.metrouicss #font .tertiary, +.metrouicss #font .tertiary-secondary + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 9pt + font-smooth always + line-height 11pt + +.metrouicss #state .header, +.metrouicss #state .subheader, +.metrouicss #state .small-subheader, +.metrouicss #state .navigation, +.metrouicss #state .body, +.metrouicss #state .tertiary + color #000000 + +.metrouicss #state .header:hover, +.metrouicss #state .subheader:hover, +.metrouicss #state .small-subheader:hover, +.metrouicss #state .navigation:hover, +.metrouicss #state .body:hover, +.metrouicss #state .tertiary:hover + color rgba(0, 0, 0, 0.8) + +.metrouicss #state .header:active, +.metrouicss #state .subheader:active, +.metrouicss #state .small-subheader:active, +.metrouicss #state .navigation:active, +.metrouicss #state .body:active, +.metrouicss #state .tertiary:active + color rgba(0, 0, 0, 0.4) + +.metrouicss #state .subheader-secondary, +.metrouicss #state .subheader-secondary-smaller, +.metrouicss #state .small-subheader, +.metrouicss #state .small-subheader-secondary, +.metrouicss #state .body-secondary, +.metrouicss #state .tertiary-secondary + color rgba(0, 0, 0, 0.6) + +.metrouicss #state .subheader-secondary:hover, +.metrouicss #state .subheader-secondary-smaller:hover, +.metrouicss #state .small-subheader:hover, +.metrouicss #state .small-subheader-secondary:hover, +.metrouicss #state .body-secondary:hover, +.metrouicss #state .tertiary-secondary:hover + color rgba(0, 0, 0, 0.8) + +.metrouicss #state .subheader-secondary:active, +.metrouicss #state .subheader-secondary-smaller:active, +.metrouicss #state .small-subheader:active, +.metrouicss #state .small-subheader-secondary:active, +.metrouicss #state .body-secondary:active, +.metrouicss #state .tertiary-secondary:active + color rgba(0, 0, 0, 0.4) + +.metrouicss a, +.metrouicss .link + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 11pt + font-smooth always + line-height 13pt + color #2e92cf + text-decoration none + +.metrouicss a:hover, +.metrouicss .link:hover + color rgba(45, 173, 237, 0.8) + +.metrouicss a:active, +.metrouicss .link:active + color rgba(45, 173, 237, 0.6) + +.metrouicss h1, +.metrouicss h2, +.metrouicss h3, +.metrouicss h4, +.metrouicss h5, +.metrouicss h6 + margin 0 0 10px 0 + padding 0 + +.metrouicss body, +.metrouicss p, +.metrouicss div + font-family 'Segoe UI Semilight', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 300 + font-size 11pt + letter-spacing 0.02em + line-height 14pt + font-smooth always + +.metrouicss .tertiary-info-text, +.metrouicss .tertiary-text + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 9pt + font-smooth always + line-height 11pt + color #000000 + +.metrouicss .tertiary-info-text:hover, +.metrouicss .tertiary-text:hover + color rgba(0, 0, 0, 0.8) + +.metrouicss .tertiary-info-text:active, +.metrouicss .tertiary-text:active + color rgba(0, 0, 0, 0.4) + +.metrouicss .tertiary-info-secondary-text, +.metrouicss .tertiary-secondary-text + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 9pt + font-smooth always + line-height 11pt + color rgba(0, 0, 0, 0.6) + +.metrouicss .tertiary-info-secondary-text:hover, +.metrouicss .tertiary-secondary-text:hover + color rgba(0, 0, 0, 0.8) + +.metrouicss .tertiary-info-secondary-text:active, +.metrouicss .tertiary-secondary-text:active + color rgba(0, 0, 0, 0.4) + +.metrouicss ul, +.metrouicss ol + padding 0 + margin 0 0 10px 0px + display block + list-style-position inside + +.metrouicss ul ul, +.metrouicss ul ol, +.metrouicss ol ol, +.metrouicss ol ul + margin-bottom 0 !important + +.metrouicss ul li, +.metrouicss ol li + display list-item + font-size 14px + line-height 20px + +.metrouicss ul.unstyled, +.metrouicss ol.unstyled, +.metrouicss .unstyled + margin-left 0 + list-style none + +.metrouicss .inline-tag, +.metrouicss .label + display inline-block + line-height inherit + font-size .75em + font-weight bold + padding 2px 4px + background-color #d5e7ec !important + color #4d4d4d + vertical-align 3% + +.metrouicss .inline-tag.success, +.metrouicss .label.success + background-color #00a300 !important + color #ffffff !important + +.metrouicss .inline-tag.warning, +.metrouicss .label.warning + background-color #e3a21a !important + color #ffffff !important + +.metrouicss .inline-tag.important, +.metrouicss .label.important, +.metrouicss .inline-tag.error, +.metrouicss .label.error + background-color #b91d47 !important + color #ffffff !important + +.metrouicss .inline-tag.info, +.metrouicss .label.info + background-color #2d89ef !important + color #ffffff !important + +.metrouicss .inline-tag.inverse, +.metrouicss .label.inverse + background-color #1d1d1d !important + color #ffffff !important + +.metrouicss .scroll-y, +.metrouicss .scroll-vertical + overflow-y scroll + +.metrouicss .scroll-x, +.metrouicss .scroll-horizontal + overflow-x scroll + +.metrouicss .clearfix:before, +.metrouicss .clearfix:after + display table + content "" + +.metrouicss [class^="icon-"], +.metrouicss [class*=" icon-"] + font-family "iconFont" + font-weight normal + font-style normal + text-decoration inherit + -webkit-font-smoothing antialiased + display inline-block + width auto + height auto + line-height normal + vertical-align baseline + background-image none + background-position 0% 0% + background-repeat repeat + margin-top 0 + position relative + +.metrouicss [class^="icon-"]:before, +.metrouicss [class*=" icon-"]:before + text-decoration inherit + display inline-block + speak none + +.metrouicss a [class^="icon-"], +.metrouicss a [class*=" icon-"] + display inline-block + +.metrouicss a [class^="icon-"], +.metrouicss button [class^="icon-"], +.metrouicss .button [class^="icon-"], +.metrouicss .page-control > ul > li [class^="icon-"], +.metrouicss a [class*=" icon-"], +.metrouicss button [class*=" icon-"], +.metrouicss .button [class*=" icon-"], +.metrouicss .page-control > ul > li [class*=" icon-"] + vertical-align -10% + font-size 1.2em + display inline-block + margin-right 5px + +.metrouicss a [class^="icon-"].icon-large, +.metrouicss button [class^="icon-"].icon-large, +.metrouicss .button [class^="icon-"].icon-large, +.metrouicss .page-control > ul > li [class^="icon-"].icon-large, +.metrouicss a [class*=" icon-"].icon-large, +.metrouicss button [class*=" icon-"].icon-large, +.metrouicss .button [class*=" icon-"].icon-large, +.metrouicss .page-control > ul > li [class*=" icon-"].icon-large + line-height .9em + +.metrouicss a.big [class^="icon-"], +.metrouicss button.big [class^="icon-"], +.metrouicss .button.big [class^="icon-"], +.metrouicss .page-control > ul > li.big [class^="icon-"], +.metrouicss a.big [class*=" icon-"], +.metrouicss button.big [class*=" icon-"], +.metrouicss .button.big [class*=" icon-"], +.metrouicss .page-control > ul > li.big [class*=" icon-"] + font-size 1.3333333333333333em + +.metrouicss li [class^="icon-"], +.metrouicss li [class*=" icon-"] + display inline-block + width 1.2em + text-align center + +.metrouicss li [class^="icon-"].icon-large, +.metrouicss li [class*=" icon-"].icon-large + width 1.5625em + +.metrouicss ol.icons li [class^="icon-"], +.metrouicss ol.icons li [class*=" icon-"] + vertical-align -10% + font-size 1.2em + +.metrouicss a [class^="icon-"].right, +.metrouicss button [class^="icon-"].right, +.metrouicss .button [class^="icon-"].right, +.metrouicss .page-control > ul > li [class^="icon-"].right, +.metrouicss a [class*=" icon-"].right, +.metrouicss button [class*=" icon-"].right, +.metrouicss .button [class*=" icon-"].right, +.metrouicss .page-control > ul > li [class*=" icon-"].right + margin-left 5px + margin-right auto + +.metrouicss .toolbar [class^="icon-"], +.metrouicss .toolbar [class*=" icon-"] + margin 0 !important + +.metrouicss .image-button [class^="icon-"], +.metrouicss .image-button [class*=" icon-"] + position absolute + right 0 + margin-left 32px + padding 5px + height 100% + top 0px + box-sizing border-box + border 1px transparent solid + z-index 2 + margin 0 + font-size 16px + +.metrouicss .shortcut > .icon [class^="icon-"], +.metrouicss .shortcut > .icon [class*=" icon-"] + font-size 32px + line-height 32px + height 32px + margin 0 !important + +.metrouicss *, +.metrouicss *:after, +.metrouicss *:before + -webkit-box-sizing border-box + -moz-box-sizing border-box + box-sizing border-box + +.metrouicss .page:before, +.metrouicss .page:after + display table + content "" + +.metrouicss .page .page-header .page-header-content h1, +.metrouicss .page .page-header .page-header-content h2, +.metrouicss .page .page-header .page-header-content h3, +.metrouicss .page .page-header .page-header-content h4, +.metrouicss .page .page-header .page-header-content h5 + position absolute + margin 0 + padding 0 + left 20px + bottom 0 + +.metrouicss .page .page-header .page-header-content .user-login .avatar img, +.metrouicss .page .page-header .page-header-content .user-login .avatar [class^="icon-"], +.metrouicss .page .page-header .page-header-content .user-login .avatar [class*=" icon-"] + width 100% + height 100% + +.metrouicss .page .page-header .page-header-content .user-login .avatar [class^="icon-"], +.metrouicss .page .page-header .page-header-content .user-login .avatar [class*=" icon-"] + margin-top 2px + font-size 30px + line-height 30px + display block + +.metrouicss .page.secondary .page-header .page-header-content h1, +.metrouicss .page.secondary .page-header .page-header-content h2, +.metrouicss .page.secondary .page-header .page-header-content h3, +.metrouicss .page.secondary .page-header .page-header-content h4, +.metrouicss .page.secondary .page-header .page-header-content h5 + position absolute + margin 0 + padding 0 + left 120px + bottom 0 + +.metrouicss .page.snapped .page .page-header .page-header-content h1, +.metrouicss .page.snapped .page .page-header .page-header-content h2, +.metrouicss .page.snapped .page .page-header .page-header-content h3, +.metrouicss .page.snapped .page .page-header .page-header-content h4, +.metrouicss .page.snapped .page .page-header .page-header-content h5 + margin-left 20px + +.metrouicss .page.with-sidebar .page-region:before, +.metrouicss .page.with-sidebar .page-region:after + display table + content "" + +.metrouicss .error-bar, +.metrouicss .warning-bar, +.metrouicss .info-bar + position fixed + top 0 + left 0 + right 0 + padding 10px 20px + color #fff + min-height 100px + +.metrouicss .modern-ui-logo, +.metrouicss .metro-ui-logo + height 28px + width 28px + display block + background-image url(data:image/png + -webkit-background-size cover + -moz-background-size cover + -o-background-size cover + background-size cover + +.metrouicss button, +.metrouicss .button + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 9pt + font-smooth always + line-height 11pt + font-size 14px + display inline-block + padding 4px 12px + line-height 20px + text-align center + vertical-align middle !important + min-width 90px + min-height 32px + height 32px + background-color #ccc + border 1px transparent solid + color #353535 + margin-right 10px + margin-bottom 10px + border-raduis 0 + cursor pointer + width auto + *zoom 1 + +.metrouicss button:before, +.metrouicss .button:before, +.metrouicss button:after, +.metrouicss .button:after + display table + content "" + +.metrouicss button:after, +.metrouicss .button:after + clear both + +.metrouicss button.standart, +.metrouicss .button.standart + min-width 90px + min-height 32px + +.metrouicss button:active, +.metrouicss .button:active, +.metrouicss button.default:active, +.metrouicss .button.default:active + top 1px + left 1px + +.metrouicss button:disabled, +.metrouicss .button:disabled, +.metrouicss button.disabled, +.metrouicss .button.disabled + background-color #eaeaea + color #bebebe + cursor not-allowed + +.metrouicss button.default, +.metrouicss .button.default + background-color #008287 + color #fff + +.metrouicss button:focus, +.metrouicss .button:focus + outline 0 + border 1px #353535 dotted + +.metrouicss a.button:hover, +.metrouicss a.button:active + color inherit + +.metrouicss button.mini, +.metrouicss .button.mini, +.metrouicss .tool-button.mini + min-height 20px + min-width 20px + height 14px + font-size .75em !important + padding-top 0px !important + +.metrouicss button.big, +.metrouicss .button.big, +.metrouicss .tool-button.big + min-height 48px + height 48px + font-size 1.2em + +.metrouicss .tool-button [class^="icon-"], +.metrouicss .tool-button [class*=" icon-"] + vertical-align -10% + font-size 1.2em + display inline-block + margin-right 5px + +.metrouicss .tool-button [class^="icon-"].icon-large, +.metrouicss .tool-button [class*=" icon-"].icon-large + line-height .9em + +.metrouicss .tool-button.big [class^="icon-"], +.metrouicss .tool-button.big [class*=" icon-"] + font-size 1.3333333333333333em + +.metrouicss .tool-button [class^="icon-"].right, +.metrouicss .tool-button [class*=" icon-"].right + margin-left 5px + margin-right auto + +.metrouicss .tool-button:before, +.metrouicss .tool-button:after + display table + content "" + +.metrouicss .tool-button:active, +.metrouicss .tool-button.default:active + top 1px + left 1px + +.metrouicss .tool-button:disabled, +.metrouicss .tool-button.disabled + background-color #eaeaea + color #bebebe + cursor not-allowed + +.metrouicss .toolbar a, +.metrouicss .toolbar button + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 9pt + font-smooth always + line-height 11pt + font-size 14px + display inline-block + padding 4px 12px + line-height 20px + vertical-align middle !important + min-width 90px + background-color #ccc + border 1px transparent solid + color #353535 + margin-right 10px + margin-bottom 10px + border-raduis 0 + cursor pointer + width auto + *zoom 1 + min-width 32px + min-height 32px + width 32px + height 32px + text-align center + position relative + padding 0 + margin-right 0px + +.metrouicss .toolbar a.mini, +.metrouicss .toolbar button.mini + min-height 20px + min-width 20px + height 14px + font-size .75em !important + padding-top 0px !important + min-width 22px + width 22px + min-height 20px + min-width 20px + height 14px + font-size .75em !important + padding-top 0px !important + +.metrouicss .toolbar a.big, +.metrouicss .toolbar button.big + min-height 48px + height 48px + font-size 1.2em + min-width 48px + width 48px + min-height 48px + height 48px + font-size 1.2em + +.metrouicss .toolbar a [class^="icon-"], +.metrouicss .toolbar button [class^="icon-"], +.metrouicss .toolbar a [class*=" icon-"], +.metrouicss .toolbar button [class*=" icon-"] + vertical-align -10% + font-size 1.2em + display inline-block + margin-right 5px + +.metrouicss .toolbar a [class^="icon-"].icon-large, +.metrouicss .toolbar button [class^="icon-"].icon-large, +.metrouicss .toolbar a [class*=" icon-"].icon-large, +.metrouicss .toolbar button [class*=" icon-"].icon-large + line-height .9em + +.metrouicss .toolbar a.big [class^="icon-"], +.metrouicss .toolbar button.big [class^="icon-"], +.metrouicss .toolbar a.big [class*=" icon-"], +.metrouicss .toolbar button.big [class*=" icon-"] + font-size 1.3333333333333333em + +.metrouicss .toolbar a [class^="icon-"].right, +.metrouicss .toolbar button [class^="icon-"].right, +.metrouicss .toolbar a [class*=" icon-"].right, +.metrouicss .toolbar button [class*=" icon-"].right + margin-left 5px + margin-right auto + +.metrouicss .toolbar a:before, +.metrouicss .toolbar button:before, +.metrouicss .toolbar a:after, +.metrouicss .toolbar button:after + display table + content "" + +.metrouicss .toolbar a:after, +.metrouicss .toolbar button:after + clear both + +.metrouicss .toolbar a.standart, +.metrouicss .toolbar button.standart + min-width 90px + min-height 32px + +.metrouicss .toolbar a:active, +.metrouicss .toolbar button:active, +.metrouicss .toolbar a.default:active, +.metrouicss .toolbar button.default:active + top 1px + left 1px + +.metrouicss .toolbar a:disabled, +.metrouicss .toolbar button:disabled, +.metrouicss .toolbar a.disabled, +.metrouicss .toolbar button.disabled + background-color #eaeaea + color #bebebe + cursor not-allowed + +.metrouicss .toolbar a.default, +.metrouicss .toolbar button.default + background-color #008287 + color #fff + +.metrouicss .toolbar a:focus, +.metrouicss .toolbar button:focus + outline 0 + border 1px #353535 dotted + +.metrouicss .toolbar a img, +.metrouicss .toolbar button img + width 16px + height 16px + top 8px + +.metrouicss .toolbar:before, +.metrouicss .toolbar:after + display table + content "" + +.metrouicss .toolbar-vertical a, +.metrouicss .toolbar-vertical button + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 9pt + font-smooth always + line-height 11pt + font-size 14px + display inline-block + padding 4px 12px + line-height 20px + vertical-align middle !important + min-width 90px + background-color #ccc + border 1px transparent solid + color #353535 + margin-right 10px + margin-bottom 10px + border-raduis 0 + cursor pointer + width auto + *zoom 1 + min-width 32px + min-height 32px + width 32px + height 32px + text-align center + position relative + padding 0 + margin-bottom 5px + +.metrouicss .toolbar-vertical a.mini, +.metrouicss .toolbar-vertical button.mini + min-height 20px + min-width 20px + height 14px + font-size .75em !important + padding-top 0px !important + min-width 22px + width 22px + min-height 20px + min-width 20px + height 14px + font-size .75em !important + padding-top 0px !important + +.metrouicss .toolbar-vertical a.big, +.metrouicss .toolbar-vertical button.big + min-height 48px + height 48px + font-size 1.2em + min-width 48px + width 48px + min-height 48px + height 48px + font-size 1.2em + +.metrouicss .toolbar-vertical a [class^="icon-"], +.metrouicss .toolbar-vertical button [class^="icon-"], +.metrouicss .toolbar-vertical a [class*=" icon-"], +.metrouicss .toolbar-vertical button [class*=" icon-"] + vertical-align -10% + font-size 1.2em + display inline-block + margin-right 5px + +.metrouicss .toolbar-vertical a [class^="icon-"].icon-large, +.metrouicss .toolbar-vertical button [class^="icon-"].icon-large, +.metrouicss .toolbar-vertical a [class*=" icon-"].icon-large, +.metrouicss .toolbar-vertical button [class*=" icon-"].icon-large + line-height .9em + +.metrouicss .toolbar-vertical a.big [class^="icon-"], +.metrouicss .toolbar-vertical button.big [class^="icon-"], +.metrouicss .toolbar-vertical a.big [class*=" icon-"], +.metrouicss .toolbar-vertical button.big [class*=" icon-"] + font-size 1.3333333333333333em + +.metrouicss .toolbar-vertical a [class^="icon-"].right, +.metrouicss .toolbar-vertical button [class^="icon-"].right, +.metrouicss .toolbar-vertical a [class*=" icon-"].right, +.metrouicss .toolbar-vertical button [class*=" icon-"].right + margin-left 5px + margin-right auto + +.metrouicss .toolbar-vertical a:before, +.metrouicss .toolbar-vertical button:before, +.metrouicss .toolbar-vertical a:after, +.metrouicss .toolbar-vertical button:after + display table + content "" + +.metrouicss .toolbar-vertical a:after, +.metrouicss .toolbar-vertical button:after + clear both + +.metrouicss .toolbar-vertical a.standart, +.metrouicss .toolbar-vertical button.standart + min-width 90px + min-height 32px + +.metrouicss .toolbar-vertical a:active, +.metrouicss .toolbar-vertical button:active, +.metrouicss .toolbar-vertical a.default:active, +.metrouicss .toolbar-vertical button.default:active + top 1px + left 1px + +.metrouicss .toolbar-vertical a:disabled, +.metrouicss .toolbar-vertical button:disabled, +.metrouicss .toolbar-vertical a.disabled, +.metrouicss .toolbar-vertical button.disabled + background-color #eaeaea + color #bebebe + cursor not-allowed + +.metrouicss .toolbar-vertical a.default, +.metrouicss .toolbar-vertical button.default + background-color #008287 + color #fff + +.metrouicss .toolbar-vertical a:focus, +.metrouicss .toolbar-vertical button:focus + outline 0 + border 1px #353535 dotted + +.metrouicss .toolbar-vertical a img, +.metrouicss .toolbar-vertical button img + width 16px + height 16px + top 8px + +.metrouicss .toolbar-vertical:before, +.metrouicss .toolbar-vertical:after + display table + content "" + +.metrouicss .image-button img, +.metrouicss .image-button:active img + position absolute + right 0 + margin-left 32px + padding 5px + height 100% + top 0px + margin-left 0px + box-sizing border-box + border 1px transparent solid + z-index 2 + +.metrouicss .button-set a, +.metrouicss .button-set button + margin-right 0 + text-align center + +.metrouicss .button-set a img, +.metrouicss .button-set button img + background-color transparent + +.metrouicss .pagination > ul li a [class^="icon-"], +.metrouicss .pagination > ul li a [class*=" icon-"] + vertical-align -10% + font-size 1.2em + display inline-block + margin-right 5px + +.metrouicss .pagination > ul li a [class^="icon-"].icon-large, +.metrouicss .pagination > ul li a [class*=" icon-"].icon-large + line-height .9em + +.metrouicss .pagination > ul li a.big [class^="icon-"], +.metrouicss .pagination > ul li a.big [class*=" icon-"] + font-size 1.3333333333333333em + +.metrouicss .pagination > ul li a [class^="icon-"].right, +.metrouicss .pagination > ul li a [class*=" icon-"].right + margin-left 5px + margin-right auto + +.metrouicss .pagination > ul li a:before, +.metrouicss .pagination > ul li a:after + display table + content "" + +.metrouicss .pagination > ul li a:active, +.metrouicss .pagination > ul li a.default:active + top 1px + left 1px + +.metrouicss .pagination > ul li a:disabled, +.metrouicss .pagination > ul li a.disabled + background-color #eaeaea + color #bebebe + cursor not-allowed + +.metrouicss .pagination > ul li.first a, +.metrouicss .pagination > ul li.prev a, +.metrouicss .pagination > ul li.next a, +.metrouicss .pagination > ul li.last a + font-size 20pt + +.metrouicss .pagination > ul li.first a:before, +.metrouicss .pagination > ul li.prev a:before, +.metrouicss .pagination > ul li.next a:before, +.metrouicss .pagination > ul li.last a:before + position absolute + left 50% + top 0 + margin-left -7px + content "\25C4" + font-size 1.5em + +.metrouicss .pagination > ul li.disabled a, +.metrouicss .pagination > ul li.spaces a + background-color #f2f2f2 + color #1e1e1e + cursor not-allowed + +.metrouicss .pagination > ul li.disabled a:active, +.metrouicss .pagination > ul li.spaces a:active + top 0 + left 0 + +.metrouicss table thead tr th, +.metrouicss table thead tr td + display table-cell + vertical-align bottom + padding-bottom 5px + padding-top 10px + padding-left 5px + border-bottom 1px #ddd solid + border-right 1px #ddd solid + border-left 1px transparent solid + border-top 1px transparent solid + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 11pt + letter-spacing 0.01em + line-height 13pt + font-smooth always + color rgba(0, 0, 0, 0.6) + text-align left + +.metrouicss table thead tr th.right, +.metrouicss table thead tr td.right + text-align right + padding-right 10px + +.metrouicss table thead tr th.last, +.metrouicss table thead tr td.last + border-right 1px transparent solid + +.metrouicss table thead tr th:last-child, +.metrouicss table thead tr td:last-child + border-right 1px transparent solid + +.metrouicss table tbody tr.info td, +.metrouicss table tbody tr.warning td, +.metrouicss table tbody tr.error td, +.metrouicss table tbody tr.success td + color #ffffff !important + +.metrouicss table.hovered thead tr th:hover, +.metrouicss table.hovered thead tr td:hover + border 1px #1c98cc solid + background rgba(28, 183, 236, 0.1) + +.metrouicss .oh, +.metrouicss .ot, +.metrouicss .tt + float left + margin 0 2% 2% 0 + width 48% + +.metrouicss [class*="span"]:before, +.metrouicss [class*="span"]:after + display table + content "" + +.metrouicss .grid .row:before, +.metrouicss .grid .row:after + display table + content "" + +.metrouicss .grid:before, +.metrouicss .grid:after + display table + content "" + +.metrouicss .grid > .row::before, +.metrouicss .grid > .row::after + content normal + +.metrouicss td[class*="span"], +.metrouicss th[class*="span"] + display table-cell !important + float none !important + padding 0 !important + +.metrouicss .hero-unit:before, +.metrouicss .hero-unit:after + display table + content "" + +.metrouicss .nav-bar .nav-bar-inner .element, +.metrouicss .nav-bar .nav-bar-inner a .element + position relative + margin 5px + line-height 20px + height 20px + float left + display inline-block + padding 0 + font-weight normal + font-size 10pt + color #fff + +.metrouicss .nav-bar .nav-bar-inner .element.brand, +.metrouicss .nav-bar .nav-bar-inner a .element.brand + font-size 1.15em + +.metrouicss .nav-bar .nav-bar-inner .element img, +.metrouicss .nav-bar .nav-bar-inner a .element img + height 100% + +.metrouicss .nav-bar .nav-bar-inner .element a, +.metrouicss .nav-bar .nav-bar-inner a .element a + line-height 20px + height 20px + font-size 10pt + +.metrouicss .nav-bar .nav-bar-inner .element [class^="icon-"]:before, +.metrouicss .nav-bar .nav-bar-inner a .element [class^="icon-"]:before, +.metrouicss .nav-bar .nav-bar-inner .element [class*=" icon-"]:before, +.metrouicss .nav-bar .nav-bar-inner a .element [class*=" icon-"]:before + display inline-block + margin 0 + padding 0 + display block + float left + margin 0 5px + +.metrouicss .nav-bar .nav-bar-inner > .divider, +.metrouicss .nav-bar .nav-bar-inner > ul.menu > li.divider + position relative + margin 5px + line-height 20px + height 20px + float left + display inline-block + padding 0 + font-weight normal + font-size 10pt + color #fff + width 1px + border-right 1px #e6e6e6 solid + +.metrouicss .nav-bar .nav-bar-inner > .divider.brand, +.metrouicss .nav-bar .nav-bar-inner > ul.menu > li.divider.brand + font-size 1.15em + +.metrouicss .nav-bar .nav-bar-inner > .divider img, +.metrouicss .nav-bar .nav-bar-inner > ul.menu > li.divider img + height 100% + +.metrouicss .nav-bar .nav-bar-inner > .divider a, +.metrouicss .nav-bar .nav-bar-inner > ul.menu > li.divider a + line-height 20px + height 20px + font-size 10pt + +.metrouicss .nav-bar .nav-bar-inner > .divider [class^="icon-"]:before, +.metrouicss .nav-bar .nav-bar-inner > ul.menu > li.divider [class^="icon-"]:before, +.metrouicss .nav-bar .nav-bar-inner > .divider [class*=" icon-"]:before, +.metrouicss .nav-bar .nav-bar-inner > ul.menu > li.divider [class*=" icon-"]:before + display inline-block + margin 0 + padding 0 + display block + float left + margin 0 5px + +.metrouicss .nav-bar .nav-bar-inner:before, +.metrouicss .nav-bar .nav-bar-inner:after + display table + content "" + +.metrouicss .nav-bar:before, +.metrouicss .nav-bar:after + display table + content "" + +.metrouicss .nav-bar.fixed-top, +.metrouicss .nav-bar.fixed-bottom + position fixed + z-index 10000 + left 0 + +.metrouicss .page-sidebar > ul > li a.lead, +.metrouicss .page-sidebar > ul > li.lead a, +.metrouicss .page-sidebar > ul > li.lead + font-weight bold + +.metrouicss .replies > div, +.metrouicss .replies > li, +.metrouicss .replies > span + position relative + margin 0 10px 10px 0 + display block + float none !important + width 310px + height 150px + font-family 'Segoe UI Semilight', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 300 + font-size 11pt + letter-spacing 0.02em + line-height 14pt + font-smooth always + height auto + min-height 70px + padding 10px + +.metrouicss .replies > div .avatar, +.metrouicss .replies > li .avatar, +.metrouicss .replies > span .avatar + width 50px + height 50px + overflow hidden + display table-cell + vertical-align middle !important + background #6e6e6e + box-shadow-bottom inset 0px 0px 3px #fff + +.metrouicss .replies > div .avatar img, +.metrouicss .replies > li .avatar img, +.metrouicss .replies > span .avatar img + width 100% + height 100% + display inline-block !important + vertical-align middle !important + +.metrouicss .replies > div .reply, +.metrouicss .replies > li .reply, +.metrouicss .replies > span .reply + margin-left 60px + margin-top -50px + +.metrouicss .replies > div .reply .date, +.metrouicss .replies > li .reply .date, +.metrouicss .replies > span .reply .date + float right + font-size 55% + color #ffffff + +.metrouicss .replies > div .reply .author, +.metrouicss .replies > li .reply .author, +.metrouicss .replies > span .reply .author + color #ffffff + +.metrouicss .replies > div .reply .text, +.metrouicss .replies > li .reply .text, +.metrouicss .replies > span .reply .text + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 9pt + font-smooth always + line-height 11pt + color #000000 + color #ffffff + line-height 16px + +.metrouicss .replies > div .reply .text:hover, +.metrouicss .replies > li .reply .text:hover, +.metrouicss .replies > span .reply .text:hover + color rgba(0, 0, 0, 0.8) + color #ffffff + +.metrouicss .replies > div .reply .text:active, +.metrouicss .replies > li .reply .text:active, +.metrouicss .replies > span .reply .text:active + color rgba(0, 0, 0, 0.4) + +.metrouicss .replies > div .sticker, +.metrouicss .replies > li .sticker, +.metrouicss .replies > span .sticker + width 0 + height 0 + border-top 10px solid #ffffff + position absolute + display block + z-index 1000 + +.metrouicss .replies > div .sticker.sticker-color-blue, +.metrouicss .replies > li .sticker.sticker-color-blue, +.metrouicss .replies > span .sticker.sticker-color-blue + border-color #2d89ef !important + +.metrouicss .replies > div .sticker.sticker-color-blueLight, +.metrouicss .replies > li .sticker.sticker-color-blueLight, +.metrouicss .replies > span .sticker.sticker-color-blueLight + border-color #eff4ff !important + +.metrouicss .replies > div .sticker.sticker-color-blueDark, +.metrouicss .replies > li .sticker.sticker-color-blueDark, +.metrouicss .replies > span .sticker.sticker-color-blueDark + border-color #2b5797 !important + +.metrouicss .replies > div .sticker.sticker-color-green, +.metrouicss .replies > li .sticker.sticker-color-green, +.metrouicss .replies > span .sticker.sticker-color-green + border-color #00a300 !important + +.metrouicss .replies > div .sticker.sticker-color-greenLight, +.metrouicss .replies > li .sticker.sticker-color-greenLight, +.metrouicss .replies > span .sticker.sticker-color-greenLight + border-color #99b433 !important + +.metrouicss .replies > div .sticker.sticker-color-greenDark, +.metrouicss .replies > li .sticker.sticker-color-greenDark, +.metrouicss .replies > span .sticker.sticker-color-greenDark + border-color #1e7145 !important + +.metrouicss .replies > div .sticker.sticker-color-red, +.metrouicss .replies > li .sticker.sticker-color-red, +.metrouicss .replies > span .sticker.sticker-color-red + border-color #b91d47 !important + +.metrouicss .replies > div .sticker.sticker-color-yellow, +.metrouicss .replies > li .sticker.sticker-color-yellow, +.metrouicss .replies > span .sticker.sticker-color-yellow + border-color #ffc40d !important + +.metrouicss .replies > div .sticker.sticker-color-orange, +.metrouicss .replies > li .sticker.sticker-color-orange, +.metrouicss .replies > span .sticker.sticker-color-orange + border-color #e3a21a !important + +.metrouicss .replies > div .sticker.sticker-color-orangeDark, +.metrouicss .replies > li .sticker.sticker-color-orangeDark, +.metrouicss .replies > span .sticker.sticker-color-orangeDark + border-color #da532c !important + +.metrouicss .replies > div .sticker.sticker-color-pink, +.metrouicss .replies > li .sticker.sticker-color-pink, +.metrouicss .replies > span .sticker.sticker-color-pink + border-color #9f00a7 !important + +.metrouicss .replies > div .sticker.sticker-color-pinkDark, +.metrouicss .replies > li .sticker.sticker-color-pinkDark, +.metrouicss .replies > span .sticker.sticker-color-pinkDark + border-color #7e3878 !important + +.metrouicss .replies > div .sticker.sticker-color-purple, +.metrouicss .replies > li .sticker.sticker-color-purple, +.metrouicss .replies > span .sticker.sticker-color-purple + border-color #603cba !important + +.metrouicss .replies > div .sticker.sticker-color-darken, +.metrouicss .replies > li .sticker.sticker-color-darken, +.metrouicss .replies > span .sticker.sticker-color-darken + border-color #1d1d1d !important + +.metrouicss .replies > div .sticker.sticker-color-white, +.metrouicss .replies > li .sticker.sticker-color-white, +.metrouicss .replies > span .sticker.sticker-color-white + border-color #ffffff !important + +.metrouicss .replies > div .sticker.sticker-color-lighten, +.metrouicss .replies > li .sticker.sticker-color-lighten, +.metrouicss .replies > span .sticker.sticker-color-lighten + border-color #d5e7ec !important + +.metrouicss .replies > div .sticker.sticker-color-grayDark, +.metrouicss .replies > li .sticker.sticker-color-grayDark, +.metrouicss .replies > span .sticker.sticker-color-grayDark + border-color #525252 !important + +.metrouicss .replies > div .sticker.sticker-color-magenta, +.metrouicss .replies > li .sticker.sticker-color-magenta, +.metrouicss .replies > span .sticker.sticker-color-magenta + border-color #ff0097 !important + +.metrouicss .replies > div .sticker.sticker-color-teal, +.metrouicss .replies > li .sticker.sticker-color-teal, +.metrouicss .replies > span .sticker.sticker-color-teal + border-color #00aba9 !important + +.metrouicss .replies > div .sticker.sticker-color-redLight, +.metrouicss .replies > li .sticker.sticker-color-redLight, +.metrouicss .replies > span .sticker.sticker-color-redLight + border-color #ee1111 !important + +.metrouicss .replies > div .sticker.sticker-left, +.metrouicss .replies > li .sticker.sticker-left, +.metrouicss .replies > span .sticker.sticker-left + border-left 20px solid transparent !important + left -20px + +.metrouicss .replies > div .sticker.sticker-right, +.metrouicss .replies > li .sticker.sticker-right, +.metrouicss .replies > span .sticker.sticker-right + border-right 20px solid transparent !important + right -20px + +.metrouicss .notices > div, +.metrouicss .notices > li, +.metrouicss .notices > span, +.metrouicss .notices > a + width 100% + height 90px + display block + overflow hidden + position relative + margin-bottom 10px + +.metrouicss .notices > div .notice-header, +.metrouicss .notices > li .notice-header, +.metrouicss .notices > span .notice-header, +.metrouicss .notices > a .notice-header, +.metrouicss .notices > div .header, +.metrouicss .notices > li .header, +.metrouicss .notices > span .header, +.metrouicss .notices > a .header + position relative + background transparent + font-family 'Segoe UI Light', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 200 + font-size 20pt + letter-spacing 0.01em + line-height 22pt + font-smooth always + font-size 12pt + margin-top 5px + margin-left 10px + +.metrouicss .notices > div .notice-text, +.metrouicss .notices > li .notice-text, +.metrouicss .notices > span .notice-text, +.metrouicss .notices > a .notice-text, +.metrouicss .notices > div .text, +.metrouicss .notices > li .text, +.metrouicss .notices > span .text, +.metrouicss .notices > a .text + position relative + margin-right 50px + margin-left 10px + color #fff + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 300 + font-size 8pt + font-smooth always + line-height 10pt + margin-top -5px + line-height 16px + +.metrouicss .notices > div .notice-icon, +.metrouicss .notices > li .notice-icon, +.metrouicss .notices > span .notice-icon, +.metrouicss .notices > a .notice-icon, +.metrouicss .notices > div .icon, +.metrouicss .notices > li .icon, +.metrouicss .notices > span .icon, +.metrouicss .notices > a .icon + position absolute + right 10px + bottom 5px + +.metrouicss .notices > div .notice-icon img, +.metrouicss .notices > li .notice-icon img, +.metrouicss .notices > span .notice-icon img, +.metrouicss .notices > a .notice-icon img, +.metrouicss .notices > div .icon img, +.metrouicss .notices > li .icon img, +.metrouicss .notices > span .icon img, +.metrouicss .notices > a .icon img + width 32px + height 32px + +.metrouicss .notices > div .notice-image, +.metrouicss .notices > li .notice-image, +.metrouicss .notices > span .notice-image, +.metrouicss .notices > a .notice-image, +.metrouicss .notices > div .image, +.metrouicss .notices > li .image, +.metrouicss .notices > span .image, +.metrouicss .notices > a .image + max-height 48px + width 48px + height 48px + margin 20px 20px 20px 20px + float left + +.metrouicss .notices > div .notice-image img, +.metrouicss .notices > li .notice-image img, +.metrouicss .notices > span .notice-image img, +.metrouicss .notices > a .notice-image img, +.metrouicss .notices > div .image img, +.metrouicss .notices > li .image img, +.metrouicss .notices > span .image img, +.metrouicss .notices > a .image img + width 48px + height 48px + +.metrouicss .notices > div .close, +.metrouicss .notices > li .close, +.metrouicss .notices > span .close, +.metrouicss .notices > a .close + z-index 2 + position absolute + top 5px + right 10px + cursor pointer + font-weight bold + text-decoration none + color #fff !important + +.metrouicss .notices > div .close::before, +.metrouicss .notices > li .close::before, +.metrouicss .notices > span .close::before, +.metrouicss .notices > a .close::before + content "\00d7" + color #fff !important + +.metrouicss .notices > div .image-large, +.metrouicss .notices > li .image-large, +.metrouicss .notices > span .image-large, +.metrouicss .notices > a .image-large + width 88px + height 88px + margin 1px 10px 1px 1px + overflow hidden + float left + +.metrouicss .notices > div .image-large img, +.metrouicss .notices > li .image-large img, +.metrouicss .notices > span .image-large img, +.metrouicss .notices > a .image-large img + width 88px + height 88px + +.metrouicss .tile .tile-content h1, +.metrouicss .tile .tile-content h2, +.metrouicss .tile .tile-content h3, +.metrouicss .tile .tile-content h4, +.metrouicss .tile .tile-content h5, +.metrouicss .tile .tile-content h6 + font-size 14pt + +.metrouicss .tile .tile-content h1, +.metrouicss .tile .tile-content h2, +.metrouicss .tile .tile-content h3, +.metrouicss .tile .tile-content h4, +.metrouicss .tile .tile-content h5, +.metrouicss .tile .tile-content h6, +.metrouicss .tile .tile-content p + padding 0 + margin 0 + line-height 24px + +.metrouicss .tile .tile-content h1:hover, +.metrouicss .tile .tile-content h2:hover, +.metrouicss .tile .tile-content h3:hover, +.metrouicss .tile .tile-content h4:hover, +.metrouicss .tile .tile-content h5:hover, +.metrouicss .tile .tile-content h6:hover, +.metrouicss .tile .tile-content p:hover + color #ffffff + +.metrouicss .tile.image > .tile-content, +.metrouicss .tile.image-slider > .tile-content + padding 0 + +.metrouicss .tile.image > .tile-content > img, +.metrouicss .tile.image-slider > .tile-content > img + width 100% + height auto + min-height 100% + max-width 100% + +.metrouicss .tile .brand, +.metrouicss .tile .tile-status + position absolute + bottom 0 + left 0 + right 0 + min-height 30px + background-color transparent + *zoom 1 + +.metrouicss .tile .brand:before, +.metrouicss .tile .tile-status:before, +.metrouicss .tile .brand:after, +.metrouicss .tile .tile-status:after + display table + content "" + +.metrouicss .tile .brand:after, +.metrouicss .tile .tile-status:after + clear both + +.metrouicss .tile .brand > .badge, +.metrouicss .tile .tile-status > .badge + position absolute + bottom 0 + right 0 + right 5px + margin-bottom 0 + color #ffffff + width 34px + height 28px + text-align center + font-family 'Segoe UI Semibold', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 600 + font-size 11pt + letter-spacing 0.01em + line-height 13pt + font-smooth always + padding-top 3px + +.metrouicss .tile .brand > .badge.activity, +.metrouicss .tile .tile-status > .badge.activity + background #2d89ef url(data:image/png + +.metrouicss .tile .brand > .badge.alert, +.metrouicss .tile .tile-status > .badge.alert + background #2d89ef url(data:image/png + +.metrouicss .tile .brand > .badge.available, +.metrouicss .tile .tile-status > .badge.available + background #2d89ef url(data:image/png + +.metrouicss .tile .brand > .badge.unavailable, +.metrouicss .tile .tile-status > .badge.unavailable + background #2d89ef url(data:image/png + +.metrouicss .tile .brand > .badge.away, +.metrouicss .tile .tile-status > .badge.away + background #2d89ef url(data:image/png + +.metrouicss .tile .brand > .badge.busy, +.metrouicss .tile .tile-status > .badge.busy + background #2d89ef url(data:image/png + +.metrouicss .tile .brand > .badge.newMessage, +.metrouicss .tile .tile-status > .badge.newMessage + background #2d89ef url(data:image/png + +.metrouicss .tile .brand > .badge.paused, +.metrouicss .tile .tile-status > .badge.paused + background #2d89ef url(data:image/png + +.metrouicss .tile .brand > .badge.playing, +.metrouicss .tile .tile-status > .badge.playing + background #2d89ef url(data:image/png + +.metrouicss .tile .brand > .badge.error, +.metrouicss .tile .tile-status > .badge.error + background #2d89ef url(data:image/png + +.metrouicss .tile .brand > .badge.attention, +.metrouicss .tile .tile-status > .badge.attention + background #2d89ef url(data:image/png + +.metrouicss .tile .brand > .name, +.metrouicss .tile .tile-status > .name + position absolute + bottom 0 + left 0 + margin-bottom 5px + margin-left 15px + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 9pt + font-smooth always + line-height 11pt + color #ffffff + +.metrouicss .tile .brand > .name:hover, +.metrouicss .tile .tile-status > .name:hover + color #ffffff + +.metrouicss .tile .brand > .name > [class*=icon-], +.metrouicss .tile .tile-status > .name > [class*=icon-] + font-size 24px + +.metrouicss .tile .brand > .icon, +.metrouicss .tile .tile-status > .icon + margin 5px 15px + width 32px + height 32px + +.metrouicss .tile .brand > .icon > [class*=icon-], +.metrouicss .tile .tile-status > .icon > [class*=icon-] + font-size 32px + +.metrouicss .tile .brand > .icon > img, +.metrouicss .tile .tile-status > .icon > img + width 100% + height 100% + +.metrouicss .tile .brand > img ~ .text, +.metrouicss .tile .tile-status > img ~ .text + position absolute + left 60px + width auto + +.metrouicss .tile .brand > .text, +.metrouicss .tile .tile-status > .text + position relative + left 8px + top 5px + right 50px + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 9pt + font-smooth always + line-height 11pt + color #000000 + color #ffffff + line-height 14px + width 60% + padding 0 + margin 0 + +.metrouicss .tile .brand > .text:hover, +.metrouicss .tile .tile-status > .text:hover + color rgba(0, 0, 0, 0.8) + color #ffffff + +.metrouicss .tile .brand > .text:active, +.metrouicss .tile .tile-status > .text:active + color rgba(0, 0, 0, 0.4) + +.metrouicss .input-control > input[type=text], +.metrouicss .input-control > input[type=email], +.metrouicss .input-control > input[type=url], +.metrouicss .input-control > input[type=phone], +.metrouicss .input-control > input[type=password], +.metrouicss .input-control > input[type=number], +.metrouicss .input-control > input[type=time], +.metrouicss .input-control > select, +.metrouicss .input-control > textarea + border 1px #bababa solid + width 100% + padding 4px 6px 6px 5px + background-color #fff + outline 0 + margin-right 32px + min-height 32px + position relative + +.metrouicss .input-control > input[type=text].with-helper, +.metrouicss .input-control > input[type=email].with-helper, +.metrouicss .input-control > input[type=url].with-helper, +.metrouicss .input-control > input[type=phone].with-helper, +.metrouicss .input-control > input[type=password].with-helper, +.metrouicss .input-control > input[type=number].with-helper, +.metrouicss .input-control > input[type=time].with-helper, +.metrouicss .input-control > select.with-helper, +.metrouicss .input-control > textarea.with-helper + padding 4px 32px 6px 5px + +.metrouicss .input-control > input[type=text]:disabled, +.metrouicss .input-control > input[type=email]:disabled, +.metrouicss .input-control > input[type=url]:disabled, +.metrouicss .input-control > input[type=phone]:disabled, +.metrouicss .input-control > input[type=password]:disabled, +.metrouicss .input-control > input[type=number]:disabled, +.metrouicss .input-control > input[type=time]:disabled, +.metrouicss .input-control > select:disabled, +.metrouicss .input-control > textarea:disabled + background-color #eaeaea + +.metrouicss .input-control > input[type=text]:focus, +.metrouicss .input-control > input[type=email]:focus, +.metrouicss .input-control > input[type=url]:focus, +.metrouicss .input-control > input[type=phone]:focus, +.metrouicss .input-control > input[type=password]:focus, +.metrouicss .input-control > input[type=number]:focus, +.metrouicss .input-control > input[type=time]:focus, +.metrouicss .input-control > select:focus, +.metrouicss .input-control > textarea:focus + border-color #000 + +.metrouicss .input-control > input[type=text]::-ms-clear, +.metrouicss .input-control > input[type=email]::-ms-clear, +.metrouicss .input-control > input[type=url]::-ms-clear, +.metrouicss .input-control > input[type=phone]::-ms-clear, +.metrouicss .input-control > input[type=number]::-ms-clear, +.metrouicss .input-control > input[type=time]::-ms-clear + display none + +.metrouicss .input-control.text input[type=text]:not(:focus) ~ [class^="btn-"], +.metrouicss .input-control.password input[type=text]:not(:focus) ~ [class^="btn-"], +.metrouicss .input-control.text input[type=password]:not(:focus) ~ [class^="btn-"], +.metrouicss .input-control.password input[type=password]:not(:focus) ~ [class^="btn-"], +.metrouicss .input-control.text input[type=email]:not(:focus) ~ [class^="btn-"], +.metrouicss .input-control.password input[type=email]:not(:focus) ~ [class^="btn-"], +.metrouicss .input-control.text input[type=phone]:not(:focus) ~ [class^="btn-"], +.metrouicss .input-control.password input[type=phone]:not(:focus) ~ [class^="btn-"], +.metrouicss .input-control.text input[type=number]:not(:focus) ~ [class^="btn-"], +.metrouicss .input-control.password input[type=number]:not(:focus) ~ [class^="btn-"], +.metrouicss .input-control.text input[type=time]:not(:focus) ~ [class^="btn-"], +.metrouicss .input-control.password input[type=time]:not(:focus) ~ [class^="btn-"], +.metrouicss .input-control.text input[type=url]:not(:focus) ~ [class^="btn-"], +.metrouicss .input-control.password input[type=url]:not(:focus) ~ [class^="btn-"], +.metrouicss .input-control.text input[type=text]:not(:focus) ~ .helper, +.metrouicss .input-control.password input[type=text]:not(:focus) ~ .helper, +.metrouicss .input-control.text input[type=password]:not(:focus) ~ .helper, +.metrouicss .input-control.password input[type=password]:not(:focus) ~ .helper, +.metrouicss .input-control.text input[type=email]:not(:focus) ~ .helper, +.metrouicss .input-control.password input[type=email]:not(:focus) ~ .helper, +.metrouicss .input-control.text input[type=phone]:not(:focus) ~ .helper, +.metrouicss .input-control.password input[type=phone]:not(:focus) ~ .helper, +.metrouicss .input-control.text input[type=number]:not(:focus) ~ .helper, +.metrouicss .input-control.password input[type=number]:not(:focus) ~ .helper, +.metrouicss .input-control.text input[type=time]:not(:focus) ~ .helper, +.metrouicss .input-control.password input[type=time]:not(:focus) ~ .helper, +.metrouicss .input-control.text input[type=url]:not(:focus) ~ .helper, +.metrouicss .input-control.password input[type=url]:not(:focus) ~ .helper + display none + +.metrouicss .input-control.text input[type=text]:focus ~ [class^="btn-"], +.metrouicss .input-control.password input[type=text]:focus ~ [class^="btn-"], +.metrouicss .input-control.text input[type=password]:focus ~ [class^="btn-"], +.metrouicss .input-control.password input[type=password]:focus ~ [class^="btn-"], +.metrouicss .input-control.text input[type=email]:focus ~ [class^="btn-"], +.metrouicss .input-control.password input[type=email]:focus ~ [class^="btn-"], +.metrouicss .input-control.text input[type=phone]:focus ~ [class^="btn-"], +.metrouicss .input-control.password input[type=phone]:focus ~ [class^="btn-"], +.metrouicss .input-control.text input[type=number]:focus ~ [class^="btn-"], +.metrouicss .input-control.password input[type=number]:focus ~ [class^="btn-"], +.metrouicss .input-control.text input[type=time]:focus ~ [class^="btn-"], +.metrouicss .input-control.password input[type=time]:focus ~ [class^="btn-"], +.metrouicss .input-control.text input[type=url]:focus ~ [class^="btn-"], +.metrouicss .input-control.password input[type=url]:focus ~ [class^="btn-"], +.metrouicss .input-control.text input[type=text]:focus ~ .helper, +.metrouicss .input-control.password input[type=text]:focus ~ .helper, +.metrouicss .input-control.text input[type=password]:focus ~ .helper, +.metrouicss .input-control.password input[type=password]:focus ~ .helper, +.metrouicss .input-control.text input[type=email]:focus ~ .helper, +.metrouicss .input-control.password input[type=email]:focus ~ .helper, +.metrouicss .input-control.text input[type=phone]:focus ~ .helper, +.metrouicss .input-control.password input[type=phone]:focus ~ .helper, +.metrouicss .input-control.text input[type=number]:focus ~ .helper, +.metrouicss .input-control.password input[type=number]:focus ~ .helper, +.metrouicss .input-control.text input[type=time]:focus ~ .helper, +.metrouicss .input-control.password input[type=time]:focus ~ .helper, +.metrouicss .input-control.text input[type=url]:focus ~ .helper, +.metrouicss .input-control.password input[type=url]:focus ~ .helper + display block + +.metrouicss .input-control.text input[type=text]:not(:focus) ~ [class^="btn-"]:active, +.metrouicss .input-control.password input[type=text]:not(:focus) ~ [class^="btn-"]:active, +.metrouicss .input-control.text input[type=password]:not(:focus) ~ [class^="btn-"]:active, +.metrouicss .input-control.password input[type=password]:not(:focus) ~ [class^="btn-"]:active, +.metrouicss .input-control.text input[type=email]:not(:focus) ~ [class^="btn-"]:active, +.metrouicss .input-control.password input[type=email]:not(:focus) ~ [class^="btn-"]:active, +.metrouicss .input-control.text input[type=phone]:not(:focus) ~ [class^="btn-"]:active, +.metrouicss .input-control.password input[type=phone]:not(:focus) ~ [class^="btn-"]:active, +.metrouicss .input-control.text input[type=number]:not(:focus) ~ [class^="btn-"]:active, +.metrouicss .input-control.password input[type=number]:not(:focus) ~ [class^="btn-"]:active, +.metrouicss .input-control.text input[type=time]:not(:focus) ~ [class^="btn-"]:active, +.metrouicss .input-control.password input[type=time]:not(:focus) ~ [class^="btn-"]:active, +.metrouicss .input-control.text input[type=url]:not(:focus) ~ [class^="btn-"]:active, +.metrouicss .input-control.password input[type=url]:not(:focus) ~ [class^="btn-"]:active, +.metrouicss .input-control.text input[type=text]:not(:focus) ~ .helper:active, +.metrouicss .input-control.password input[type=text]:not(:focus) ~ .helper:active, +.metrouicss .input-control.text input[type=password]:not(:focus) ~ .helper:active, +.metrouicss .input-control.password input[type=password]:not(:focus) ~ .helper:active, +.metrouicss .input-control.text input[type=email]:not(:focus) ~ .helper:active, +.metrouicss .input-control.password input[type=email]:not(:focus) ~ .helper:active, +.metrouicss .input-control.text input[type=phone]:not(:focus) ~ .helper:active, +.metrouicss .input-control.password input[type=phone]:not(:focus) ~ .helper:active, +.metrouicss .input-control.text input[type=number]:not(:focus) ~ .helper:active, +.metrouicss .input-control.password input[type=number]:not(:focus) ~ .helper:active, +.metrouicss .input-control.text input[type=time]:not(:focus) ~ .helper:active, +.metrouicss .input-control.password input[type=time]:not(:focus) ~ .helper:active, +.metrouicss .input-control.text input[type=url]:not(:focus) ~ .helper:active, +.metrouicss .input-control.password input[type=url]:not(:focus) ~ .helper:active + display block + +.metrouicss .input-control input[type=text] ~ .btn-search, +.metrouicss .input-control input[type=text] ~ .btn-date + display block !important + +.metrouicss .input-control.text .helper, +.metrouicss .input-control.password .helper, +.metrouicss .input-control.text [class^="btn-"], +.metrouicss .input-control.password [class^="btn-"] + font-family "iconFont" !important + background #fff + top 2px + width 26px !important + height 27px !important + min-width 26px !important + min-height 27px !important + cursor pointer + color #000 + position absolute + left 100% + margin-left -28px + display block + border 1px #fff solid + +.metrouicss .input-control.text .helper:before, +.metrouicss .input-control.password .helper:before, +.metrouicss .input-control.text [class^="btn-"]:before, +.metrouicss .input-control.password [class^="btn-"]:before + font-size 10pt !important + position absolute + color #000 !important + font-family "iconFont" !important + left 6px + top 4px + +.metrouicss .input-control.text .helper:hover, +.metrouicss .input-control.password .helper:hover, +.metrouicss .input-control.text [class^="btn-"]:hover, +.metrouicss .input-control.password [class^="btn-"]:hover + background #d9d9d9 + +.metrouicss .input-control.text .helper:active, +.metrouicss .input-control.password .helper:active, +.metrouicss .input-control.text [class^="btn-"]:active, +.metrouicss .input-control.password [class^="btn-"]:active + background-color #000 + +.metrouicss .input-control.text .helper:active:before, +.metrouicss .input-control.password .helper:active:before, +.metrouicss .input-control.text [class^="btn-"]:active:before, +.metrouicss .input-control.password [class^="btn-"]:active:before + color #fff + +.metrouicss .input-control.password .helper, +.metrouicss .input-control.password .btn-reveal + background #ffffff url(data:image/png + +.metrouicss .input-control.password .helper:hover, +.metrouicss .input-control.password .btn-reveal:hover + background #ffffff url(data:image/png + +.metrouicss .input-control.text .helper:before, +.metrouicss .input-control.text .btn-clear:before + content "\e089" + +.metrouicss input[type=button], +.metrouicss input[type=reset], +.metrouicss input[type=submit] + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 9pt + font-smooth always + line-height 11pt + font-size 14px + display inline-block + padding 4px 12px + line-height 20px + text-align center + vertical-align middle !important + min-width 90px + min-height 32px + height 32px + background-color #ccc + border 1px transparent solid + color #353535 + margin-right 10px + margin-bottom 10px + border-raduis 0 + cursor pointer + width auto + *zoom 1 + border-radius 0 + +.metrouicss input[type=button] [class^="icon-"], +.metrouicss input[type=reset] [class^="icon-"], +.metrouicss input[type=submit] [class^="icon-"], +.metrouicss input[type=button] [class*=" icon-"], +.metrouicss input[type=reset] [class*=" icon-"], +.metrouicss input[type=submit] [class*=" icon-"] + vertical-align -10% + font-size 1.2em + display inline-block + margin-right 5px + +.metrouicss input[type=button] [class^="icon-"].icon-large, +.metrouicss input[type=reset] [class^="icon-"].icon-large, +.metrouicss input[type=submit] [class^="icon-"].icon-large, +.metrouicss input[type=button] [class*=" icon-"].icon-large, +.metrouicss input[type=reset] [class*=" icon-"].icon-large, +.metrouicss input[type=submit] [class*=" icon-"].icon-large + line-height .9em + +.metrouicss input[type=button].big [class^="icon-"], +.metrouicss input[type=reset].big [class^="icon-"], +.metrouicss input[type=submit].big [class^="icon-"], +.metrouicss input[type=button].big [class*=" icon-"], +.metrouicss input[type=reset].big [class*=" icon-"], +.metrouicss input[type=submit].big [class*=" icon-"] + font-size 1.3333333333333333em + +.metrouicss input[type=button] [class^="icon-"].right, +.metrouicss input[type=reset] [class^="icon-"].right, +.metrouicss input[type=submit] [class^="icon-"].right, +.metrouicss input[type=button] [class*=" icon-"].right, +.metrouicss input[type=reset] [class*=" icon-"].right, +.metrouicss input[type=submit] [class*=" icon-"].right + margin-left 5px + margin-right auto + +.metrouicss input[type=button]:before, +.metrouicss input[type=reset]:before, +.metrouicss input[type=submit]:before, +.metrouicss input[type=button]:after, +.metrouicss input[type=reset]:after, +.metrouicss input[type=submit]:after + display table + content "" + +.metrouicss input[type=button]:after, +.metrouicss input[type=reset]:after, +.metrouicss input[type=submit]:after + clear both + +.metrouicss input[type=button].standart, +.metrouicss input[type=reset].standart, +.metrouicss input[type=submit].standart + min-width 90px + min-height 32px + +.metrouicss input[type=button]:active, +.metrouicss input[type=reset]:active, +.metrouicss input[type=submit]:active, +.metrouicss input[type=button].default:active, +.metrouicss input[type=reset].default:active, +.metrouicss input[type=submit].default:active + top 1px + left 1px + +.metrouicss input[type=button]:disabled, +.metrouicss input[type=reset]:disabled, +.metrouicss input[type=submit]:disabled, +.metrouicss input[type=button].disabled, +.metrouicss input[type=reset].disabled, +.metrouicss input[type=submit].disabled + background-color #eaeaea + color #bebebe + cursor not-allowed + +.metrouicss input[type=button].default, +.metrouicss input[type=reset].default, +.metrouicss input[type=submit].default + background-color #008287 + color #fff + +.metrouicss input[type=button]:focus, +.metrouicss input[type=reset]:focus, +.metrouicss input[type=submit]:focus + outline 0 + border 1px #353535 dotted + +.metrouicss input[type=button].mini, +.metrouicss input[type=reset].mini, +.metrouicss input[type=submit].mini + min-height 20px + min-width 20px + height 14px + font-size .75em !important + padding-top 0px !important + +.metrouicss input[type=button].big, +.metrouicss input[type=reset].big, +.metrouicss input[type=submit].big + min-height 48px + height 48px + font-size 1.2em + +.metrouicss .image-collection:before, +.metrouicss .image-collection:after + display table + content "" + +.metrouicss .image-collection > div, +.metrouicss .image-collection > li + width 220px + height 121px + overflow hidden + margin-right 20px + margin-bottom 20px + position relative + box-shadow inset 0px 0px 1px #FFFFCC + float left + background #cccccc url(data:image/png + display table-cell + vertical-align middle !important + text-align center + +.metrouicss .image-collection > div > img, +.metrouicss .image-collection > li > img + width 100% + height auto + min-height 100% + max-width 100% + +.metrouicss .image-collection > div > .overlay, +.metrouicss .image-collection > li > .overlay + position absolute + width 100% + height 55px + overflow hidden + background-color #1e1e1e + color #fff + font-size 8pt + text-align left + line-height 12px + padding 5px 10px + opacity .8 + bottom -55px + +.metrouicss .image-collection > div:hover .overlay, +.metrouicss .image-collection > li:hover .overlay + -webkit-transform translate(0, -55px) + -ms-transform translate(0, -55px) + -o-transform translate(0, -55px) + -moz-transform translate(0, -55px) + transform translate(0, -55px) + -webkit-transition all 0.3s ease + -moz-transition all 0.3s ease + -o-transition all 0.3s ease + -ms-transition all 0.3s ease + transition all 0.3s easet + +.metrouicss code, +.metrouicss pre + padding 0 3px 2px + font-family 'Segoe UI Semilight', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 300 + font-size 11pt + letter-spacing 0.02em + line-height 14pt + font-smooth always + font-size 10pt + color #525252 + +.metrouicss .page-control:before, +.metrouicss .page-control:after + display table + content "" + +.metrouicss .page-control > ul:before, +.metrouicss .page-control > ul:after + display table + content "" + +.metrouicss .page-control > ul li.active span, +.metrouicss .page-control > ul li.active a + color #2d89ef + +.metrouicss .page-control > ul li span, +.metrouicss .page-control > ul li a + text-decoration none + display block + float left + padding 5px 10px + color #1e1e1e + font-family 'Segoe UI', 'Open Sans', Verdana, Arial, Helvetica, sans-serif + font-weight 400 + font-size 11pt + letter-spacing 0.01em + line-height 13pt + font-smooth always + cursor pointer + outline 0 + +.metrouicss .page-control .menu-pull, +.metrouicss .page-control .menu-pull-bar + display none + +.metrouicss .accordion:before, +.metrouicss .accordion:after + display table + content "" + +.metrouicss .static-rating:before, +.metrouicss .static-rating:after + display table + content "" + +.metrouicss .rating:before, +.metrouicss .rating:after + display table + content "" + +.metrouicss .progress-bar:before, +.metrouicss .progress-bar:after + display table + content "" + +.metrouicss .listview li .data .static-rating.small, +.metrouicss .listview li .data .progress-bar + margin-bottom 3px + +.metrouicss .listview li:before, +.metrouicss .listview li:after + display table + content "" + +.metrouicss .listview.image li .data .static-rating.small, +.metrouicss .listview.image li .data .progress-bar + margin-bottom 10px + +.metrouicss .listview:before, +.metrouicss .listview:after + display table + content "" + +.metrouicss .slider:active .complete, +.metrouicss .slider:active + .marker:active .complete + background-color #25bbc4 + +.metrouicss .dialog .header button [class^="icon-"], +.metrouicss .dialog .header button [class*=" icon-"] + vertical-align -10% + font-size 1.2em + display inline-block + margin-right 5px + font-size 11px + +.metrouicss .dialog .header button [class^="icon-"].icon-large, +.metrouicss .dialog .header button [class*=" icon-"].icon-large + line-height .9em + +.metrouicss .dialog .header button.big [class^="icon-"], +.metrouicss .dialog .header button.big [class*=" icon-"] + font-size 1.3333333333333333em + +.metrouicss .dialog .header button [class^="icon-"].right, +.metrouicss .dialog .header button [class*=" icon-"].right + margin-left 5px + margin-right auto + +.metrouicss .dialog .header button:before, +.metrouicss .dialog .header button:after + display table + content "" + +.metrouicss .dialog .header button:active, +.metrouicss .dialog .header button.default:active + top 1px + left 1px + +.metrouicss .dialog .header button:disabled, +.metrouicss .dialog .header button.disabled + background-color #eaeaea + color #bebebe + cursor not-allowed + +.metrouicss .calendar td, +.metrouicss .calendar th + padding 4px + width 14.285% !important + font-size 10pt + border 1px #ccc solid !important + text-align center + diff --git a/vendor/styles/sapling/_account.less b/vendor/styles/sapling/_account.less deleted file mode 100644 index 4b2c398..0000000 --- a/vendor/styles/sapling/_account.less +++ /dev/null @@ -1,7 +0,0 @@ -// The nav icons break into seperate lines at widths between 768px and 980px -// To prevent this hide the icons at those widths -@media (min-width: 768px) and (max-width: 980px) { - #account-nav [class^="icon-"] { - display: none; - } -} diff --git a/vendor/styles/sapling/_angular.less b/vendor/styles/sapling/_angular.less deleted file mode 100644 index a2f4bdc..0000000 --- a/vendor/styles/sapling/_angular.less +++ /dev/null @@ -1,18 +0,0 @@ -input.ng-dirty.ng-valid { - /*.formFieldState(@successText, @successText, @successBackground);*/ - border-color: @successText; -} - -input.ng-dirty.ng-invalid { - /*.formFieldState(@errorText, @errorText, @errorBackground);*/ - border-color: @errorText; -} - -input.ng-pristine { - -} - -input.ng-dirty { - -} - diff --git a/vendor/styles/sapling/_auth.less b/vendor/styles/sapling/_auth.less deleted file mode 100644 index fc5ea57..0000000 --- a/vendor/styles/sapling/_auth.less +++ /dev/null @@ -1,47 +0,0 @@ -// Hover state -//.btn:hover { -// text-decoration: none; -// background-position: 0; -// border-color: rgba(14, 130, 180, 0.4); -// .box-shadow(0 0 5px rgba(14, 130, 180, 0.55)); -// -// // transition is only when going to hover, otherwise the background -// // behind the gradient (there for IE<=9 fallback) gets mismatched -// .transition(box-shadow .1s linear); -//} - -//.btn:hover { -// background-position: 0; -// border-color: rgba(14, 130, 180, 0.4); -// .box-shadow(0 0 5px rgba(14, 130, 180, 0.55)); -//} - -//.btn.active, .btn:active { -// @shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); -// .box-shadow(@shadow); -//} - -.provider-btn { - display: inline-block; - list-style: none; - padding: 5px; -} -.provider-btn .btn img { - width: 90px; - height: 30px; -} - -.password-form { - padding-top: 20px; - border-left: 1px solid #e5e5e5; -} - -.password-form .form-actions { - background-color: transparent; - border: none; -} - -.aeauth-form h4 { - text-align: center; -} - diff --git a/vendor/styles/sapling/_breadcrumbs.less b/vendor/styles/sapling/_breadcrumbs.less deleted file mode 100644 index 8854591..0000000 --- a/vendor/styles/sapling/_breadcrumbs.less +++ /dev/null @@ -1,22 +0,0 @@ -// BREADCRUMBS -// ----------- - -.breadcrumb { - padding: 7px 14px; - margin: 0 0 @baseLineHeight; - #gradient > .vertical(#f5f5f5, @white); - /*border: 1px solid #ddd;*/ - .border-radius(3px); - .box-shadow(inset 0 1px 0 @white); - li { - display: inline-block; - text-shadow: 0 1px 0 @white; - } - .divider { - padding: 0 5px; - color: @grayLight; - } - .active a { - color: @grayDark; - } -} diff --git a/vendor/styles/sapling/_font-awesome.less b/vendor/styles/sapling/_font-awesome.less deleted file mode 100644 index 15ac671..0000000 --- a/vendor/styles/sapling/_font-awesome.less +++ /dev/null @@ -1,329 +0,0 @@ -/* Font Awesome - the iconic font designed for use with Twitter Bootstrap - ------------------------------------------------------- - The full suite of pictographic icons, examples, and documentation - can be found at: http://fortawesome.github.com/Font-Awesome/ - - License - ------------------------------------------------------- - The Font Awesome webfont, CSS, and LESS files are licensed under CC BY 3.0: - http://creativecommons.org/licenses/by/3.0/ A mention of - 'Font Awesome - http://fortawesome.github.com/Font-Awesome' in human-readable - source code is considered acceptable attribution (most common on the web). - If human readable source code is not available to the end user, a mention in - an 'About' or 'Credits' screen is considered acceptable (most common in desktop - or mobile software). - - Contact - ------------------------------------------------------- - Email: dave@davegandy.com - Twitter: http://twitter.com/fortaweso_me - Work: Lead Product Designer @ http://kyruus.com - - */ - -@fontAwesomePath: '../font'; - -@font-face { - font-family: 'FontAwesome'; - src: url('@{fontAwesomePath}/fontawesome-webfont.eot'); - src: url('@{fontAwesomePath}/fontawesome-webfont.eot?#iefix') format('embedded-opentype'), - url('@{fontAwesomePath}/fontawesome-webfont.woff') format('woff'), - url('@{fontAwesomePath}/fontawesome-webfont.ttf') format('truetype'), - url('@{fontAwesomePath}/fontawesome-webfont.svg#FontAwesome') format('svg'); - font-weight: normal; - font-style: normal; -} - -/* Font Awesome styles - ------------------------------------------------------- */ -[class^="icon-"]:before, -[class*=" icon-"]:before { - font-family: FontAwesome; - font-weight: normal; - font-style: normal; - display: inline-block; - text-decoration: inherit; -} - -a [class^="icon-"], -a [class*=" icon-"] { - display: inline-block; - text-decoration: inherit; -} - -/* makes the font 33% larger relative to the icon container */ -.icon-large:before { - vertical-align: middle; - font-size: 4/3em; -} - -.btn, .nav-tabs { - [class^="icon-"], - [class*=" icon-"] { - /* keeps button heights with and without icons the same */ - line-height: .9em; - } -} - -li { - [class^="icon-"], - [class*=" icon-"] { - display: inline-block; - width: 1.25em; - text-align: center; - } - .icon-large:before, - .icon-large:before { - /* 1.5 increased font size for icon-large * 1.25 width */ - width: 1.5*1.25em; - } -} - -ul.icons { - list-style-type: none; - margin-left: 2em; - text-indent: -.8em; - - li { - [class^="icon-"], - [class*=" icon-"] { - width: .8em; - } - .icon-large:before, - .icon-large:before { - /* 1.5 increased font size for icon-large * 1.25 width */ - vertical-align: initial; -// width: 1.5*1.25em; - } - } -} - -/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen - readers do not read off random characters that represent icons */ -.icon-glass:before { content: "\f000"; } -.icon-music:before { content: "\f001"; } -.icon-search:before { content: "\f002"; } -.icon-envelope:before { content: "\f003"; } -.icon-heart:before { content: "\f004"; } -.icon-star:before { content: "\f005"; } -.icon-star-empty:before { content: "\f006"; } -.icon-user:before { content: "\f007"; } -.icon-film:before { content: "\f008"; } -.icon-th-large:before { content: "\f009"; } -.icon-th:before { content: "\f00a"; } -.icon-th-list:before { content: "\f00b"; } -.icon-ok:before { content: "\f00c"; } -.icon-remove:before { content: "\f00d"; } -.icon-zoom-in:before { content: "\f00e"; } - -.icon-zoom-out:before { content: "\f010"; } -.icon-off:before { content: "\f011"; } -.icon-signal:before { content: "\f012"; } -.icon-cog:before { content: "\f013"; } -.icon-trash:before { content: "\f014"; } -.icon-home:before { content: "\f015"; } -.icon-file:before { content: "\f016"; } -.icon-time:before { content: "\f017"; } -.icon-road:before { content: "\f018"; } -.icon-download-alt:before { content: "\f019"; } -.icon-download:before { content: "\f01a"; } -.icon-upload:before { content: "\f01b"; } -.icon-inbox:before { content: "\f01c"; } -.icon-play-circle:before { content: "\f01d"; } -.icon-repeat:before { content: "\f01e"; } - -/* \f020 is not a valid unicode character. all shifted one down */ -.icon-refresh:before { content: "\f021"; } -.icon-list-alt:before { content: "\f022"; } -.icon-lock:before { content: "\f023"; } -.icon-flag:before { content: "\f024"; } -.icon-headphones:before { content: "\f025"; } -.icon-volume-off:before { content: "\f026"; } -.icon-volume-down:before { content: "\f027"; } -.icon-volume-up:before { content: "\f028"; } -.icon-qrcode:before { content: "\f029"; } -.icon-barcode:before { content: "\f02a"; } -.icon-tag:before { content: "\f02b"; } -.icon-tags:before { content: "\f02c"; } -.icon-book:before { content: "\f02d"; } -.icon-bookmark:before { content: "\f02e"; } -.icon-print:before { content: "\f02f"; } - -.icon-camera:before { content: "\f030"; } -.icon-font:before { content: "\f031"; } -.icon-bold:before { content: "\f032"; } -.icon-italic:before { content: "\f033"; } -.icon-text-height:before { content: "\f034"; } -.icon-text-width:before { content: "\f035"; } -.icon-align-left:before { content: "\f036"; } -.icon-align-center:before { content: "\f037"; } -.icon-align-right:before { content: "\f038"; } -.icon-align-justify:before { content: "\f039"; } -.icon-list:before { content: "\f03a"; } -.icon-indent-left:before { content: "\f03b"; } -.icon-indent-right:before { content: "\f03c"; } -.icon-facetime-video:before { content: "\f03d"; } -.icon-picture:before { content: "\f03e"; } - -.icon-pencil:before { content: "\f040"; } -.icon-map-marker:before { content: "\f041"; } -.icon-adjust:before { content: "\f042"; } -.icon-tint:before { content: "\f043"; } -.icon-edit:before { content: "\f044"; } -.icon-share:before { content: "\f045"; } -.icon-check:before { content: "\f046"; } -.icon-move:before { content: "\f047"; } -.icon-step-backward:before { content: "\f048"; } -.icon-fast-backward:before { content: "\f049"; } -.icon-backward:before { content: "\f04a"; } -.icon-play:before { content: "\f04b"; } -.icon-pause:before { content: "\f04c"; } -.icon-stop:before { content: "\f04d"; } -.icon-forward:before { content: "\f04e"; } - -.icon-fast-forward:before { content: "\f050"; } -.icon-step-forward:before { content: "\f051"; } -.icon-eject:before { content: "\f052"; } -.icon-chevron-left:before { content: "\f053"; } -.icon-chevron-right:before { content: "\f054"; } -.icon-plus-sign:before { content: "\f055"; } -.icon-minus-sign:before { content: "\f056"; } -.icon-remove-sign:before { content: "\f057"; } -.icon-ok-sign:before { content: "\f058"; } -.icon-question-sign:before { content: "\f059"; } -.icon-info-sign:before { content: "\f05a"; } -.icon-screenshot:before { content: "\f05b"; } -.icon-remove-circle:before { content: "\f05c"; } -.icon-ok-circle:before { content: "\f05d"; } -.icon-ban-circle:before { content: "\f05e"; } - -.icon-arrow-left:before { content: "\f060"; } -.icon-arrow-right:before { content: "\f061"; } -.icon-arrow-up:before { content: "\f062"; } -.icon-arrow-down:before { content: "\f063"; } -.icon-share-alt:before { content: "\f064"; } -.icon-resize-full:before { content: "\f065"; } -.icon-resize-small:before { content: "\f066"; } -.icon-plus:before { content: "\f067"; } -.icon-minus:before { content: "\f068"; } -.icon-asterisk:before { content: "\f069"; } -.icon-exclamation-sign:before { content: "\f06a"; } -.icon-gift:before { content: "\f06b"; } -.icon-leaf:before { content: "\f06c"; } -.icon-fire:before { content: "\f06d"; } -.icon-eye-open:before { content: "\f06e"; } - -.icon-eye-close:before { content: "\f070"; } -.icon-warning-sign:before { content: "\f071"; } -.icon-plane:before { content: "\f072"; } -.icon-calendar:before { content: "\f073"; } -.icon-random:before { content: "\f074"; } -.icon-comment:before { content: "\f075"; } -.icon-magnet:before { content: "\f076"; } -.icon-chevron-up:before { content: "\f077"; } -.icon-chevron-down:before { content: "\f078"; } -.icon-retweet:before { content: "\f079"; } -.icon-shopping-cart:before { content: "\f07a"; } -.icon-folder-close:before { content: "\f07b"; } -.icon-folder-open:before { content: "\f07c"; } -.icon-resize-vertical:before { content: "\f07d"; } -.icon-resize-horizontal:before { content: "\f07e"; } - -.icon-bar-chart:before { content: "\f080"; } -.icon-twitter-sign:before { content: "\f081"; } -.icon-facebook-sign:before { content: "\f082"; } -.icon-camera-retro:before { content: "\f083"; } -.icon-key:before { content: "\f084"; } -.icon-cogs:before { content: "\f085"; } -.icon-comments:before { content: "\f086"; } -.icon-thumbs-up:before { content: "\f087"; } -.icon-thumbs-down:before { content: "\f088"; } -.icon-star-half:before { content: "\f089"; } -.icon-heart-empty:before { content: "\f08a"; } -.icon-signout:before { content: "\f08b"; } -.icon-linkedin-sign:before { content: "\f08c"; } -.icon-pushpin:before { content: "\f08d"; } -.icon-external-link:before { content: "\f08e"; } - -.icon-signin:before { content: "\f090"; } -.icon-trophy:before { content: "\f091"; } -.icon-github-sign:before { content: "\f092"; } -.icon-upload-alt:before { content: "\f093"; } -.icon-lemon:before { content: "\f094"; } -.icon-phone:before { content: "\f095"; } -.icon-check-empty:before { content: "\f096"; } -.icon-bookmark-empty:before { content: "\f097"; } -.icon-phone-sign:before { content: "\f098"; } -.icon-twitter:before { content: "\f099"; } -.icon-facebook:before { content: "\f09a"; } -.icon-github:before { content: "\f09b"; } -.icon-unlock:before { content: "\f09c"; } -.icon-credit-card:before { content: "\f09d"; } -.icon-rss:before { content: "\f09e"; } - -.icon-hdd:before { content: "\f0a0"; } -.icon-bullhorn:before { content: "\f0a1"; } -.icon-bell:before { content: "\f0a2"; } -.icon-certificate:before { content: "\f0a3"; } -.icon-hand-right:before { content: "\f0a4"; } -.icon-hand-left:before { content: "\f0a5"; } -.icon-hand-up:before { content: "\f0a6"; } -.icon-hand-down:before { content: "\f0a7"; } -.icon-circle-arrow-left:before { content: "\f0a8"; } -.icon-circle-arrow-right:before { content: "\f0a9"; } -.icon-circle-arrow-up:before { content: "\f0aa"; } -.icon-circle-arrow-down:before { content: "\f0ab"; } -.icon-globe:before { content: "\f0ac"; } -.icon-wrench:before { content: "\f0ad"; } -.icon-tasks:before { content: "\f0ae"; } - -.icon-filter:before { content: "\f0b0"; } -.icon-briefcase:before { content: "\f0b1"; } -.icon-fullscreen:before { content: "\f0b2"; } - -.icon-group:before { content: "\f0c0"; } -.icon-link:before { content: "\f0c1"; } -.icon-cloud:before { content: "\f0c2"; } -.icon-beaker:before { content: "\f0c3"; } -.icon-cut:before { content: "\f0c4"; } -.icon-copy:before { content: "\f0c5"; } -.icon-paper-clip:before { content: "\f0c6"; } -.icon-save:before { content: "\f0c7"; } -.icon-sign-blank:before { content: "\f0c8"; } -.icon-reorder:before { content: "\f0c9"; } -.icon-list-ul:before { content: "\f0ca"; } -.icon-list-ol:before { content: "\f0cb"; } -.icon-strikethrough:before { content: "\f0cc"; } -.icon-underline:before { content: "\f0cd"; } -.icon-table:before { content: "\f0ce"; } - -.icon-magic:before { content: "\f0d0"; } -.icon-truck:before { content: "\f0d1"; } -.icon-pinterest:before { content: "\f0d2"; } -.icon-pinterest-sign:before { content: "\f0d3"; } -.icon-google-plus-sign:before { content: "\f0d4"; } -.icon-google-plus:before { content: "\f0d5"; } -.icon-money:before { content: "\f0d6"; } -.icon-caret-down:before { content: "\f0d7"; } -.icon-caret-up:before { content: "\f0d8"; } -.icon-caret-left:before { content: "\f0d9"; } -.icon-caret-right:before { content: "\f0da"; } -.icon-columns:before { content: "\f0db"; } -.icon-sort:before { content: "\f0dc"; } -.icon-sort-down:before { content: "\f0dd"; } -.icon-sort-up:before { content: "\f0de"; } - -.icon-envelope-alt:before { content: "\f0e0"; } -.icon-linkedin:before { content: "\f0e1"; } -.icon-undo:before { content: "\f0e2"; } -.icon-legal:before { content: "\f0e3"; } -.icon-dashboard:before { content: "\f0e4"; } -.icon-comment-alt:before { content: "\f0e5"; } -.icon-comments-alt:before { content: "\f0e6"; } -.icon-bolt:before { content: "\f0e7"; } -.icon-sitemap:before { content: "\f0e8"; } -.icon-umbrella:before { content: "\f0e9"; } -.icon-paste:before { content: "\f0ea"; } - -.icon-user-md:before { content: "\f200"; } diff --git a/vendor/styles/sapling/_sticky-footer.less b/vendor/styles/sapling/_sticky-footer.less deleted file mode 100644 index 03fb337..0000000 --- a/vendor/styles/sapling/_sticky-footer.less +++ /dev/null @@ -1,23 +0,0 @@ - -// Sticky Footer - -@footerHeight: 88px; - -html, body { - height: 100%; -} - -.wrapper { - min-height: 100%; - height: auto !important; - height: 100%; - margin: 0 auto -@footerHeight; -} - -.push { - height: @footerHeight; -} - -.wrapper > .container { - padding-top: 24px; -} diff --git a/vendor/styles/themes/default/_overrides.less b/vendor/styles/themes/default/_overrides.less deleted file mode 100644 index 528b0e7..0000000 --- a/vendor/styles/themes/default/_overrides.less +++ /dev/null @@ -1,9 +0,0 @@ - -// Footer -.footer { - background-color: @grayDark; - padding: 30px 0; - text-shadow: none; - border-top: 1px solid #e5e5e5; - .box-shadow(inset 0 5px 15px rgba(0, 0, 0, .025)); -} diff --git a/vendor/styles/themes/default/_variables.less b/vendor/styles/themes/default/_variables.less deleted file mode 100644 index d8825fb..0000000 --- a/vendor/styles/themes/default/_variables.less +++ /dev/null @@ -1,205 +0,0 @@ -// Variables.less -// Variables to customize the look and feel of Bootstrap -// ----------------------------------------------------- - - - -// GLOBAL VALUES -// -------------------------------------------------- - - -// Grays -// ------------------------- -@black: #000; -@grayDarker: #222; -@grayDark: #333; -@gray: #555; -@grayLight: #999; -@grayLighter: #eee; -@white: #fff; - - -// Accent colors -// ------------------------- -@blue: #049cdb; -@blueDark: #0064cd; -@green: #46a546; -@red: #9d261d; -@yellow: #ffc40d; -@orange: #f89406; -@pink: #c3325f; -@purple: #7a43b6; - - -// Scaffolding -// ------------------------- -@bodyBackground: @white; -@textColor: @grayDark; - - -// Links -// ------------------------- -@linkColor: #08c; -@linkColorHover: darken(@linkColor, 15%); - - -// Typography -// ------------------------- -@sansFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif; -@serifFontFamily: Georgia, "Times New Roman", Times, serif; -@monoFontFamily: Menlo, Monaco, Consolas, "Courier New", monospace; - -@baseFontSize: 13px; -@baseFontFamily: @sansFontFamily; -@baseLineHeight: 18px; -@altFontFamily: @serifFontFamily; - -@headingsFontFamily: inherit; // empty to use BS default, @baseFontFamily -@headingsFontWeight: bold; // instead of browser default, bold -@headingsColor: inherit; // empty to use BS default, @textColor - - -// Tables -// ------------------------- -@tableBackground: transparent; // overall background-color -@tableBackgroundAccent: #f9f9f9; // for striping -@tableBackgroundHover: #f5f5f5; // for hover -@tableBorder: #ddd; // table and cell border - - -// Buttons -// ------------------------- -@btnBackground: @white; -@btnBackgroundHighlight: darken(@white, 10%); -@btnBorder: #ccc; - -@btnPrimaryBackground: @linkColor; -@btnPrimaryBackgroundHighlight: spin(@btnPrimaryBackground, 15%); - -@btnInfoBackground: #5bc0de; -@btnInfoBackgroundHighlight: #2f96b4; - -@btnSuccessBackground: #62c462; -@btnSuccessBackgroundHighlight: #51a351; - -@btnWarningBackground: lighten(@orange, 15%); -@btnWarningBackgroundHighlight: @orange; - -@btnDangerBackground: #ee5f5b; -@btnDangerBackgroundHighlight: #bd362f; - -@btnInverseBackground: @gray; -@btnInverseBackgroundHighlight: @grayDarker; - - -// Forms -// ------------------------- -@inputBackground: @white; -@inputBorder: #ccc; -@inputBorderRadius: 3px; -@inputDisabledBackground: @grayLighter; -@formActionsBackground: #f5f5f5; - -// Dropdowns -// ------------------------- -@dropdownBackground: @white; -@dropdownBorder: rgba(0,0,0,.2); -@dropdownLinkColor: @grayDark; -@dropdownLinkColorHover: @white; -@dropdownLinkBackgroundHover: @linkColor; - - - - -// COMPONENT VARIABLES -// -------------------------------------------------- - -// Z-index master list -// ------------------------- -// Used for a bird's eye view of components dependent on the z-axis -// Try to avoid customizing these :) -@zindexDropdown: 1000; -@zindexPopover: 1010; -@zindexTooltip: 1020; -@zindexFixedNavbar: 1030; -@zindexModalBackdrop: 1040; -@zindexModal: 1050; - - -// Sprite icons path -// ------------------------- -@iconSpritePath: "../img/glyphicons-halflings.png"; -@iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; - - -// Input placeholder text color -// ------------------------- -@placeholderText: @grayLight; - - -// Hr border color -// ------------------------- -@hrBorder: @grayLighter; - - -// Navbar -// ------------------------- -@navbarHeight: 40px; -@navbarBackground: @grayDarker; -@navbarBackgroundHighlight: @grayDark; - -@navbarText: @grayLight; -@navbarLinkColor: @grayLight; -@navbarLinkColorHover: @white; -@navbarLinkColorActive: @navbarLinkColorHover; -@navbarLinkBackgroundHover: transparent; -@navbarLinkBackgroundActive: @navbarBackground; - -@navbarSearchBackground: lighten(@navbarBackground, 25%); -@navbarSearchBackgroundFocus: @white; -@navbarSearchBorder: darken(@navbarSearchBackground, 30%); -@navbarSearchPlaceholderColor: #ccc; -@navbarBrandColor: @navbarLinkColor; - - -// Hero unit -// ------------------------- -@heroUnitBackground: @grayLighter; -@heroUnitHeadingColor: inherit; -@heroUnitLeadColor: inherit; - - -// Form states and alerts -// ------------------------- -@warningText: #c09853; -@warningBackground: #fcf8e3; -@warningBorder: darken(spin(@warningBackground, -10), 3%); - -@errorText: #b94a48; -@errorBackground: #f2dede; -@errorBorder: darken(spin(@errorBackground, -10), 3%); - -@successText: #468847; -@successBackground: #dff0d8; -@successBorder: darken(spin(@successBackground, -10), 5%); - -@infoText: #3a87ad; -@infoBackground: #d9edf7; -@infoBorder: darken(spin(@infoBackground, -10), 7%); - - - -// GRID -// -------------------------------------------------- - -// Default 940px grid -// ------------------------- -@gridColumns: 12; -@gridColumnWidth: 60px; -@gridGutterWidth: 20px; -@gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); - -// Fluid grid -// ------------------------- -@fluidGridColumnWidth: 6.382978723%; -@fluidGridGutterWidth: 2.127659574%; diff --git a/vendor/styles/themes/sapling/_overrides.less b/vendor/styles/themes/sapling/_overrides.less deleted file mode 100644 index de6b217..0000000 --- a/vendor/styles/themes/sapling/_overrides.less +++ /dev/null @@ -1,59 +0,0 @@ -// Overrides - -h1, h2, h3, h4, h5, h6 { - font-weight: normal; - /*font-family: 'Crete Round', "Helvetica Neue", Helvetica, Arial, sans-serif;*/ - padding-bottom: .3em; - color: #1F444B; -} -.nav .brand { - padding: 0; -} - -.clickable { - cursor: pointer; -} - -// Forms -.form-actions { - background-color: transparent; - border: none; -} - -// Navbar -.navbar-inner { - padding-top: 6px; - border-bottom: 1px solid #e5e5e5; - .box-shadow(inset 0 -2px 5px rgba(0, 0, 0, .025)); -} - -.navbar .nav > li > a { - text-shadow: none; -} - -.navbar .brand a:hover { - text-decoration: none; -} - -.nav-list .active > a, .nav-list .active > a:hover { - @shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); - .box-shadow(@shadow); - text-shadow: 0 1px 0 rgba(0, 0, 0, .2); -} -.nav-list > li > a { - line-height: 24px; - padding: 3px 10px; -} -// Sections -section header { - padding-bottom: 12px; -} - -// Footer -.footer { - background-color: @tan; - padding: 30px 0; - text-shadow: none; - border-top: 1px solid #e5e5e5; - .box-shadow(inset 0 5px 15px rgba(0, 0, 0, .025)); -} diff --git a/vendor/styles/themes/sapling/_variables.less b/vendor/styles/themes/sapling/_variables.less deleted file mode 100644 index 471246e..0000000 --- a/vendor/styles/themes/sapling/_variables.less +++ /dev/null @@ -1,206 +0,0 @@ -// Variables.less -// Variables to customize the look and feel of Bootstrap -// ----------------------------------------------------- - - - -// GLOBAL VALUES -// -------------------------------------------------- - - -// Grays -// ------------------------- -@black: #000; -@grayDarker: #222; -@grayDark: #333; -@gray: #555; -@grayLight: #999; -@grayLighter: #eee; -@white: #fff; - - -// Accent colors -// ------------------------- -@blue: #049cdb; -@blueDark: #1F444B; -@green: #46a546; -@red: #9d261d; -@yellow: #ffc40d; -@orange: #f89406; -@pink: #c3325f; -@purple: #7a43b6; -@tan: #EDECE6; - - -// Scaffolding -// ------------------------- -@bodyBackground: @white; -@textColor: @blueDark; - - -// Links -// ------------------------- -@linkColor: #6E8F4A; -@linkColorHover: #F26A1E; - - -// Typography -// ------------------------- -@sansFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif; -@serifFontFamily: Georgia, "Times New Roman", Times, serif; -@monoFontFamily: Menlo, Monaco, Consolas, "Courier New", monospace; - -@baseFontSize: 13px; -@baseFontFamily: @sansFontFamily; -@baseLineHeight: 18px; -@altFontFamily: @serifFontFamily; - -@headingsFontFamily: inherit; // empty to use BS default, @baseFontFamily -@headingsFontWeight: bold; // instead of browser default, bold -@headingsColor: inherit; // empty to use BS default, @textColor - - -// Tables -// ------------------------- -@tableBackground: transparent; // overall background-color -@tableBackgroundAccent: #f9f9f9; // for striping -@tableBackgroundHover: #f5f5f5; // for hover -@tableBorder: #ddd; // table and cell border - - -// Buttons -// ------------------------- -@btnBackground: @white; -@btnBackgroundHighlight: darken(@white, 10%); -@btnBorder: #ccc; - -@btnPrimaryBackground: @linkColor; -@btnPrimaryBackgroundHighlight: spin(@btnPrimaryBackground, 15%); - -@btnInfoBackground: #5bc0de; -@btnInfoBackgroundHighlight: #2f96b4; - -@btnSuccessBackground: #62c462; -@btnSuccessBackgroundHighlight: #51a351; - -@btnWarningBackground: lighten(@orange, 15%); -@btnWarningBackgroundHighlight: @orange; - -@btnDangerBackground: #ee5f5b; -@btnDangerBackgroundHighlight: #bd362f; - -@btnInverseBackground: @gray; -@btnInverseBackgroundHighlight: @grayDarker; - - -// Forms -// ------------------------- -@inputBackground: @white; -@inputBorder: #ccc; -@inputBorderRadius: 3px; -@inputDisabledBackground: @grayLighter; -@formActionsBackground: #f5f5f5; - -// Dropdowns -// ------------------------- -@dropdownBackground: @white; -@dropdownBorder: rgba(0,0,0,.2); -@dropdownLinkColor: @grayDark; -@dropdownLinkColorHover: @white; -@dropdownLinkBackgroundHover: @linkColor; - - - - -// COMPONENT VARIABLES -// -------------------------------------------------- - -// Z-index master list -// ------------------------- -// Used for a bird's eye view of components dependent on the z-axis -// Try to avoid customizing these :) -@zindexDropdown: 1000; -@zindexPopover: 1010; -@zindexTooltip: 1020; -@zindexFixedNavbar: 1030; -@zindexModalBackdrop: 1040; -@zindexModal: 1050; - - -// Sprite icons path -// ------------------------- -@iconSpritePath: "../img/glyphicons-halflings.png"; -@iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; - - -// Input placeholder text color -// ------------------------- -@placeholderText: @grayLight; - - -// Hr border color -// ------------------------- -@hrBorder: @grayLighter; - - -// Navbar -// ------------------------- -@navbarHeight: 70px; -@navbarBackground: @tan; -@navbarBackgroundHighlight: @tan; - -@navbarText: @blueDark; -@navbarLinkColor: @blueDark; -@navbarLinkColorHover: @linkColorHover; -@navbarLinkColorActive: @navbarLinkColorHover; -@navbarLinkBackgroundHover: transparent; -@navbarLinkBackgroundActive: @navbarBackground; - -@navbarSearchBackground: lighten(@navbarBackground, 25%); -@navbarSearchBackgroundFocus: @white; -@navbarSearchBorder: darken(@navbarSearchBackground, 30%); -@navbarSearchPlaceholderColor: #ccc; -@navbarBrandColor: @navbarLinkColor; - - -// Hero unit -// ------------------------- -@heroUnitBackground: @grayLighter; -@heroUnitHeadingColor: inherit; -@heroUnitLeadColor: inherit; - - -// Form states and alerts -// ------------------------- -@warningText: #c09853; -@warningBackground: #fcf8e3; -@warningBorder: darken(spin(@warningBackground, -10), 3%); - -@errorText: #b94a48; -@errorBackground: #f2dede; -@errorBorder: darken(spin(@errorBackground, -10), 3%); - -@successText: #468847; -@successBackground: #dff0d8; -@successBorder: darken(spin(@successBackground, -10), 5%); - -@infoText: #3a87ad; -@infoBackground: #d9edf7; -@infoBorder: darken(spin(@infoBackground, -10), 7%); - - - -// GRID -// -------------------------------------------------- - -// Default 940px grid -// ------------------------- -@gridColumns: 12; -@gridColumnWidth: 60px; -@gridGutterWidth: 20px; -@gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); - -// Fluid grid -// ------------------------- -@fluidGridColumnWidth: 6.382978723%; -@fluidGridGutterWidth: 2.127659574%; diff --git a/vendor/styles/themes/smokey/_overrides.less b/vendor/styles/themes/smokey/_overrides.less deleted file mode 100644 index c35b0c7..0000000 --- a/vendor/styles/themes/smokey/_overrides.less +++ /dev/null @@ -1,59 +0,0 @@ -// Overrides - -h1, h2, h3, h4, h5, h6 { - font-weight: normal; - /*font-family: 'Crete Round', "Helvetica Neue", Helvetica, Arial, sans-serif;*/ - padding-bottom: .3em; - color: #1F444B; -} -.nav .brand { - padding: 0; -} - -.clickable { - cursor: pointer; -} - -// Forms -.form-actions { - background-color: transparent; - border: none; -} - -// Navbar -.navbar-inner { - padding-top: 6px; - border-bottom: 1px solid #e5e5e5; - .box-shadow(inset 0 -2px 5px rgba(0, 0, 0, .025)); -} - -.navbar .nav > li > a { - text-shadow: none; -} - -.navbar .brand a:hover { - text-decoration: none; -} - -.nav-list .active > a, .nav-list .active > a:hover { - @shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); - .box-shadow(@shadow); - text-shadow: 0 1px 0 rgba(0, 0, 0, .2); -} -.nav-list > li > a { - line-height: 24px; - padding: 3px 10px; -} -// Sections -section header { - padding-bottom: 12px; -} - -// Footer -.footer { - background-color: @smoke; - padding: 30px 0; - text-shadow: none; - border-top: 1px solid #e5e5e5; - .box-shadow(inset 0 5px 15px rgba(0, 0, 0, .025)); -} diff --git a/vendor/styles/themes/smokey/_variables.less b/vendor/styles/themes/smokey/_variables.less deleted file mode 100644 index 3f6a1b2..0000000 --- a/vendor/styles/themes/smokey/_variables.less +++ /dev/null @@ -1,212 +0,0 @@ -// Variables.less -// Variables to customize the look and feel of Bootstrap -// ----------------------------------------------------- - - - -// GLOBAL VALUES -// -------------------------------------------------- - - -// Grays -// ------------------------- -@black: #000; -@grayDarker: #222; -@grayDark: #333; -@gray: #555; -@grayLight: #999; -@grayLighter: #eee; -@white: #fff; - - -// Accent colors -// ------------------------- -@blue: #049cdb; -@blueDark: #9FB3BB; -@green: #46a546; -@red: #9d261d; -@yellow: #ffc40d; -@orange: #f26a1e; -@pink: #c3325f; -@purple: #7a43b6; - - -// Custom Colors -// ------------------------- -@smoke: #f5f5f5; -@brownDark: #3C2415; -@blueLight: #D4EEF9; -@greenLight: #76A53A; - - -// Scaffolding -// ------------------------- -@bodyBackground: @white; -@textColor: @grayDark; - - -// Links -// ------------------------- -@linkColor: #2299BB; -@linkColorHover: #F26A1E; - -// Typography -// ------------------------- -@sansFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif; -@serifFontFamily: Georgia, "Times New Roman", Times, serif; -@monoFontFamily: Menlo, Monaco, Consolas, "Courier New", monospace; - -@baseFontSize: 13px; -@baseFontFamily: @sansFontFamily; -@baseLineHeight: 18px; -@altFontFamily: @serifFontFamily; - -@headingsFontFamily: inherit; // empty to use BS default, @baseFontFamily -@headingsFontWeight: bold; // instead of browser default, bold -@headingsColor: inherit; // empty to use BS default, @textColor - - -// Tables -// ------------------------- -@tableBackground: transparent; // overall background-color -@tableBackgroundAccent: #f9f9f9; // for striping -@tableBackgroundHover: #f5f5f5; // for hover -@tableBorder: #ddd; // table and cell border - - -// Buttons -// ------------------------- -@btnBackground: @white; -@btnBackgroundHighlight: darken(@white, 10%); -@btnBorder: #ccc; - -@btnPrimaryBackground: @linkColor; -@btnPrimaryBackgroundHighlight: spin(@btnPrimaryBackground, 15%); - -@btnInfoBackground: #5bc0de; -@btnInfoBackgroundHighlight: #2f96b4; - -@btnSuccessBackground: #62c462; -@btnSuccessBackgroundHighlight: #51a351; - -@btnWarningBackground: lighten(@orange, 15%); -@btnWarningBackgroundHighlight: @orange; - -@btnDangerBackground: #ee5f5b; -@btnDangerBackgroundHighlight: #bd362f; - -@btnInverseBackground: @gray; -@btnInverseBackgroundHighlight: @grayDarker; - - -// Forms -// ------------------------- -@inputBackground: @white; -@inputBorder: #ccc; -@inputBorderRadius: 3px; -@inputDisabledBackground: @grayLighter; -@formActionsBackground: #f5f5f5; - -// Dropdowns -// ------------------------- -@dropdownBackground: @white; -@dropdownBorder: rgba(0,0,0,.2); -@dropdownLinkColor: @grayDark; -@dropdownLinkColorHover: @white; -@dropdownLinkBackgroundHover: @linkColor; - - - - -// COMPONENT VARIABLES -// -------------------------------------------------- - -// Z-index master list -// ------------------------- -// Used for a bird's eye view of components dependent on the z-axis -// Try to avoid customizing these :) -@zindexDropdown: 1000; -@zindexPopover: 1010; -@zindexTooltip: 1020; -@zindexFixedNavbar: 1030; -@zindexModalBackdrop: 1040; -@zindexModal: 1050; - - -// Sprite icons path -// ------------------------- -@iconSpritePath: "../img/glyphicons-halflings.png"; -@iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; - - -// Input placeholder text color -// ------------------------- -@placeholderText: @grayLight; - - -// Hr border color -// ------------------------- -@hrBorder: @grayLighter; - - -// Navbar -// ------------------------- -@navbarHeight: 70px; -@navbarBackground: @smoke; -@navbarBackgroundHighlight: @smoke; - -@navbarText: @brownDark; -@navbarLinkColor: @brownDark; -@navbarLinkColorHover: @linkColorHover; -@navbarLinkColorActive: @navbarLinkColorHover; -@navbarLinkBackgroundHover: transparent; -@navbarLinkBackgroundActive: @navbarBackground; - -@navbarSearchBackground: lighten(@navbarBackground, 25%); -@navbarSearchBackgroundFocus: @white; -@navbarSearchBorder: darken(@navbarSearchBackground, 30%); -@navbarSearchPlaceholderColor: #ccc; -@navbarBrandColor: @navbarLinkColor; - - -// Hero unit -// ------------------------- -@heroUnitBackground: @grayLighter; -@heroUnitHeadingColor: inherit; -@heroUnitLeadColor: inherit; - - -// Form states and alerts -// ------------------------- -@warningText: #c09853; -@warningBackground: #fcf8e3; -@warningBorder: darken(spin(@warningBackground, -10), 3%); - -@errorText: #b94a48; -@errorBackground: #f2dede; -@errorBorder: darken(spin(@errorBackground, -10), 3%); - -@successText: #468847; -@successBackground: #dff0d8; -@successBorder: darken(spin(@successBackground, -10), 5%); - -@infoText: #3a87ad; -@infoBackground: #d9edf7; -@infoBorder: darken(spin(@infoBackground, -10), 7%); - - - -// GRID -// -------------------------------------------------- - -// Default 940px grid -// ------------------------- -@gridColumns: 12; -@gridColumnWidth: 60px; -@gridGutterWidth: 20px; -@gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); - -// Fluid grid -// ------------------------- -@fluidGridColumnWidth: 6.382978723%; -@fluidGridGutterWidth: 2.127659574%; From 48f1ff1b47ee090d7f47a97894b9bc952cfd4cc0 Mon Sep 17 00:00:00 2001 From: Shih-Wen Su Date: Thu, 16 May 2013 14:38:12 +0800 Subject: [PATCH 3/9] change from bootstrap less/sass to metro stylus --- app/assets/font/fontawesome-webfont.eot | Bin 38708 -> 0 bytes app/assets/font/fontawesome-webfont.svg | 255 ----------------------- app/assets/font/fontawesome-webfont.ttf | Bin 68476 -> 0 bytes app/assets/font/fontawesome-webfont.woff | Bin 41752 -> 0 bytes app/styles/_responsive.scss | 48 ----- app/styles/app.scss | 66 ------ app/styles/themes/custom/_overrides.less | 17 -- app/styles/themes/custom/_variables.less | 205 ------------------ 8 files changed, 591 deletions(-) delete mode 100755 app/assets/font/fontawesome-webfont.eot delete mode 100755 app/assets/font/fontawesome-webfont.svg delete mode 100755 app/assets/font/fontawesome-webfont.ttf delete mode 100755 app/assets/font/fontawesome-webfont.woff delete mode 100644 app/styles/_responsive.scss delete mode 100644 app/styles/app.scss delete mode 100644 app/styles/themes/custom/_overrides.less delete mode 100644 app/styles/themes/custom/_variables.less diff --git a/app/assets/font/fontawesome-webfont.eot b/app/assets/font/fontawesome-webfont.eot deleted file mode 100755 index 89070c1e63c2703b2334023922ecc1664f759b55..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38708 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/assets/font/fontawesome-webfont.ttf b/app/assets/font/fontawesome-webfont.ttf deleted file mode 100755 index c17e9f8d100d01a002029b5b93cc081062618bf3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68476 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 diff --git a/app/styles/_responsive.scss b/app/styles/_responsive.scss deleted file mode 100644 index 6d903e1..0000000 --- a/app/styles/_responsive.scss +++ /dev/null @@ -1,48 +0,0 @@ -/*! - * Bootstrap Responsive v2.3.0 - * - * Copyright 2012 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world @twitter by @mdo and @fat. - */ - - -// Responsive -// For phone and tablet devices -// ------------------------------------------------------------- - - -// REPEAT VARIABLES & MIXINS -// ------------------------- -// Required since we compile the responsive stuff separately - -@import "vendor/styles/bootstrap/variables"; // Modify this for custom colors, font-sizes, etc -@import "vendor/styles/bootstrap/mixins"; - - -// RESPONSIVE CLASSES -// ------------------ - -@import "vendor/styles/bootstrap/responsive-utilities"; - - -// MEDIA QUERIES -// ------------------ - -// Large desktops -@import "vendor/styles/bootstrap/responsive-1200px-min"; - -// Tablets to regular desktops -@import "vendor/styles/bootstrap/responsive-768px-979px"; - -// Phones to portrait tablets and narrow desktops -@import "vendor/styles/bootstrap/responsive-767px-max"; - - -// RESPONSIVE NAVBAR -// ------------------ - -// From 979px and below, show a button to toggle navbar contents -@import "vendor/styles/bootstrap/responsive-navbar"; diff --git a/app/styles/app.scss b/app/styles/app.scss deleted file mode 100644 index c99bc49..0000000 --- a/app/styles/app.scss +++ /dev/null @@ -1,66 +0,0 @@ -/*! - * Bootstrap v2.3.0 - * - * Copyright 2012 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world @twitter by @mdo and @fat. - */ - -// Core variables and mixins -@import "vendor/styles/bootstrap/variables"; // Modify this for custom colors, font-sizes, etc -@import "vendor/styles/bootstrap/mixins"; - -// CSS Reset -@import "vendor/styles/bootstrap/reset"; - -// Grid system and page structure -@import "vendor/styles/bootstrap/scaffolding"; -@import "vendor/styles/bootstrap/grid"; -@import "vendor/styles/bootstrap/layouts"; - -// Base CSS -@import "vendor/styles/bootstrap/type"; -@import "vendor/styles/bootstrap/code"; -@import "vendor/styles/bootstrap/forms"; -@import "vendor/styles/bootstrap/tables"; - -// Components: common -@import "vendor/styles/bootstrap/sprites"; -@import "vendor/styles/bootstrap/dropdowns"; -@import "vendor/styles/bootstrap/wells"; -@import "vendor/styles/bootstrap/component-animations"; -@import "vendor/styles/bootstrap/close"; - -// Components: Buttons & Alerts -@import "vendor/styles/bootstrap/buttons"; -@import "vendor/styles/bootstrap/button-groups"; -@import "vendor/styles/bootstrap/alerts"; // Note: alerts share common CSS with buttons and thus have styles in buttons - -// Components: Nav -@import "vendor/styles/bootstrap/navs"; -@import "vendor/styles/bootstrap/navbar"; -@import "vendor/styles/bootstrap/breadcrumbs"; -@import "vendor/styles/bootstrap/pagination"; -@import "vendor/styles/bootstrap/pager"; - -// Components: Popovers -@import "vendor/styles/bootstrap/modals"; -@import "vendor/styles/bootstrap/tooltip"; -@import "vendor/styles/bootstrap/popovers"; - -// Components: Misc -@import "vendor/styles/bootstrap/thumbnails"; -@import "vendor/styles/bootstrap/media"; -@import "vendor/styles/bootstrap/labels-badges"; -@import "vendor/styles/bootstrap/progress-bars"; -@import "vendor/styles/bootstrap/accordion"; -@import "vendor/styles/bootstrap/carousel"; -@import "vendor/styles/bootstrap/hero-unit"; - -// Utility classes -@import "vendor/styles/bootstrap/utilities"; // Has to be last to override when necessary - -// Enable Responsive -//@import "_responsive"; diff --git a/app/styles/themes/custom/_overrides.less b/app/styles/themes/custom/_overrides.less deleted file mode 100644 index 6ec2d05..0000000 --- a/app/styles/themes/custom/_overrides.less +++ /dev/null @@ -1,17 +0,0 @@ -/* -Place custom styles here. Thes styles are ment to be loaded after -bootstrap, so the may override it's behavior. -*/ - -body { - #gradient > .striped(@blue); -} - -// Footer -.footer { - background-color: #1a1a1a; - padding: 30px 0; - text-shadow: none; - .box-shadow(inset 0 5px 15px rgba(0, 0, 0, .025)); -} - diff --git a/app/styles/themes/custom/_variables.less b/app/styles/themes/custom/_variables.less deleted file mode 100644 index d8825fb..0000000 --- a/app/styles/themes/custom/_variables.less +++ /dev/null @@ -1,205 +0,0 @@ -// Variables.less -// Variables to customize the look and feel of Bootstrap -// ----------------------------------------------------- - - - -// GLOBAL VALUES -// -------------------------------------------------- - - -// Grays -// ------------------------- -@black: #000; -@grayDarker: #222; -@grayDark: #333; -@gray: #555; -@grayLight: #999; -@grayLighter: #eee; -@white: #fff; - - -// Accent colors -// ------------------------- -@blue: #049cdb; -@blueDark: #0064cd; -@green: #46a546; -@red: #9d261d; -@yellow: #ffc40d; -@orange: #f89406; -@pink: #c3325f; -@purple: #7a43b6; - - -// Scaffolding -// ------------------------- -@bodyBackground: @white; -@textColor: @grayDark; - - -// Links -// ------------------------- -@linkColor: #08c; -@linkColorHover: darken(@linkColor, 15%); - - -// Typography -// ------------------------- -@sansFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif; -@serifFontFamily: Georgia, "Times New Roman", Times, serif; -@monoFontFamily: Menlo, Monaco, Consolas, "Courier New", monospace; - -@baseFontSize: 13px; -@baseFontFamily: @sansFontFamily; -@baseLineHeight: 18px; -@altFontFamily: @serifFontFamily; - -@headingsFontFamily: inherit; // empty to use BS default, @baseFontFamily -@headingsFontWeight: bold; // instead of browser default, bold -@headingsColor: inherit; // empty to use BS default, @textColor - - -// Tables -// ------------------------- -@tableBackground: transparent; // overall background-color -@tableBackgroundAccent: #f9f9f9; // for striping -@tableBackgroundHover: #f5f5f5; // for hover -@tableBorder: #ddd; // table and cell border - - -// Buttons -// ------------------------- -@btnBackground: @white; -@btnBackgroundHighlight: darken(@white, 10%); -@btnBorder: #ccc; - -@btnPrimaryBackground: @linkColor; -@btnPrimaryBackgroundHighlight: spin(@btnPrimaryBackground, 15%); - -@btnInfoBackground: #5bc0de; -@btnInfoBackgroundHighlight: #2f96b4; - -@btnSuccessBackground: #62c462; -@btnSuccessBackgroundHighlight: #51a351; - -@btnWarningBackground: lighten(@orange, 15%); -@btnWarningBackgroundHighlight: @orange; - -@btnDangerBackground: #ee5f5b; -@btnDangerBackgroundHighlight: #bd362f; - -@btnInverseBackground: @gray; -@btnInverseBackgroundHighlight: @grayDarker; - - -// Forms -// ------------------------- -@inputBackground: @white; -@inputBorder: #ccc; -@inputBorderRadius: 3px; -@inputDisabledBackground: @grayLighter; -@formActionsBackground: #f5f5f5; - -// Dropdowns -// ------------------------- -@dropdownBackground: @white; -@dropdownBorder: rgba(0,0,0,.2); -@dropdownLinkColor: @grayDark; -@dropdownLinkColorHover: @white; -@dropdownLinkBackgroundHover: @linkColor; - - - - -// COMPONENT VARIABLES -// -------------------------------------------------- - -// Z-index master list -// ------------------------- -// Used for a bird's eye view of components dependent on the z-axis -// Try to avoid customizing these :) -@zindexDropdown: 1000; -@zindexPopover: 1010; -@zindexTooltip: 1020; -@zindexFixedNavbar: 1030; -@zindexModalBackdrop: 1040; -@zindexModal: 1050; - - -// Sprite icons path -// ------------------------- -@iconSpritePath: "../img/glyphicons-halflings.png"; -@iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; - - -// Input placeholder text color -// ------------------------- -@placeholderText: @grayLight; - - -// Hr border color -// ------------------------- -@hrBorder: @grayLighter; - - -// Navbar -// ------------------------- -@navbarHeight: 40px; -@navbarBackground: @grayDarker; -@navbarBackgroundHighlight: @grayDark; - -@navbarText: @grayLight; -@navbarLinkColor: @grayLight; -@navbarLinkColorHover: @white; -@navbarLinkColorActive: @navbarLinkColorHover; -@navbarLinkBackgroundHover: transparent; -@navbarLinkBackgroundActive: @navbarBackground; - -@navbarSearchBackground: lighten(@navbarBackground, 25%); -@navbarSearchBackgroundFocus: @white; -@navbarSearchBorder: darken(@navbarSearchBackground, 30%); -@navbarSearchPlaceholderColor: #ccc; -@navbarBrandColor: @navbarLinkColor; - - -// Hero unit -// ------------------------- -@heroUnitBackground: @grayLighter; -@heroUnitHeadingColor: inherit; -@heroUnitLeadColor: inherit; - - -// Form states and alerts -// ------------------------- -@warningText: #c09853; -@warningBackground: #fcf8e3; -@warningBorder: darken(spin(@warningBackground, -10), 3%); - -@errorText: #b94a48; -@errorBackground: #f2dede; -@errorBorder: darken(spin(@errorBackground, -10), 3%); - -@successText: #468847; -@successBackground: #dff0d8; -@successBorder: darken(spin(@successBackground, -10), 5%); - -@infoText: #3a87ad; -@infoBackground: #d9edf7; -@infoBorder: darken(spin(@infoBackground, -10), 7%); - - - -// GRID -// -------------------------------------------------- - -// Default 940px grid -// ------------------------- -@gridColumns: 12; -@gridColumnWidth: 60px; -@gridGutterWidth: 20px; -@gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); - -// Fluid grid -// ------------------------- -@fluidGridColumnWidth: 6.382978723%; -@fluidGridGutterWidth: 2.127659574%; From afa1be313c7c4d252b620cd8a99b284d732829b0 Mon Sep 17 00:00:00 2001 From: Shih-Wen Su Date: Thu, 16 May 2013 18:05:27 +0800 Subject: [PATCH 4/9] package add stylus bower and karma --- package.ls | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/package.ls b/package.ls index de2784f..8f09129 100755 --- a/package.ls +++ b/package.ls @@ -1,30 +1,36 @@ -#!/usr/bin/env lsc -cj -author: 'Chia-liang Kao' -name: 'angular-brunch-seed-livescript' -description: 'AngularJS + Brunch + LiveScript' +author: 'Shih-Wen Su' +name: 'angular-seed' +description: 'AngularJS Brunch LiveScript' version: '0.1.1' -homepage: 'https://github.com/clkao/angular-brunch-seed-livescript' +homepage: 'https://github.com/flyakite/angular-brunch-seed' repository: type: 'git' - url: 'https://github.com/clkao/angular-brunch-seed-livescript' + url: 'https://github.com/flyakite/angular-brunch-seed' engines: - node: '0.8.x' - npm: '1.1.x' + node: '~0.6.10 || 0.8 || 0.9' + npm '1.2.x' scripts: - prepublish: './node_modules/.bin/lsc -cj package.ls' - start: './node_modules/.bin/brunch watch --server' - test: 'testacular test/testacular.config.js' -dependencies: {} -devDependencies: - testacular: '>= 0.0.16' - LiveScript: '>= 1.1.1' + start: 'node_modules/.bin/brunch watch --server' + test: 'node_modules/.bin/karma start test/karma.conf.js' +dependencies: brunch: '1.5.x' + bower: '~0.9.2' + karma: '>= 0.8.4 < 0.9.0' + jade: '>= 0.28' + 'coffee-script': '>= 1.4' 'javascript-brunch': '1.5.x' - 'LiveScript-brunch': '1.5.x' + 'coffee-script-brunch': '1.5.x' + 'less-brunch': '1.5.x' + 'stylus-brunch': '1.5.x' + 'auto-reload-brunch': '1.5.x' 'css-brunch': '1.5.x' 'sass-brunch': '1.5.x' 'jade-brunch': '1.4.x' 'static-jade-brunch': '>= 1.4.0 <= 1.4.5 || >= 1.4.8 < 1.5' + 'jade-angularjs-brunch': '>= 0.0.5 <= 0.1', 'auto-reload-brunch': '1.5.x' - 'uglify-js-brunch': '1.3.x' + 'uglify-js-brunch': '1.5.x' 'clean-css-brunch': '1.5.x' + 'bower-stylesheet-brunch': 'git://github.com/angular-brunch/bower-stylesheet-brunch/#master', + 'bower-javascript-brunch': 'git://github.com/angular-brunch/bower-javascript-brunch/#master', + 'bower-asserts-brunch': 'git://github.com/angular-brunch/bower-assets-brunch/#master', From 2ec3482075fb5e9ba37365386b6804c373a4b669 Mon Sep 17 00:00:00 2001 From: Shih-Wen Su Date: Thu, 16 May 2013 18:51:56 +0800 Subject: [PATCH 5/9] re-org --- .gitignore | 2 + app/assets/test/angular-scenario.js | 26011 ++++++++++++++++ app/assets/test/runner.html | 10 + app/scripts/controllers.ls | 31 + app/scripts/directives.ls | 14 + app/scripts/filters.ls | 5 + app/scripts/services.ls | 6 + bower.json | 20 + vendor/angular-cookies/README.md | 4 + vendor/angular-cookies/angular-cookies.js | 184 + vendor/angular-cookies/angular-cookies.min.js | 7 + vendor/angular-cookies/bower.json | 17 + vendor/angular-mocks/README.md | 4 + vendor/angular-mocks/angular-mocks.js | 1768 ++ vendor/angular-mocks/bower.json | 17 + vendor/angular-resource/README.md | 4 + vendor/angular-resource/angular-resource.js | 457 + .../angular-resource/angular-resource.min.js | 10 + vendor/angular-resource/bower.json | 17 + vendor/angular-sanitize/README.md | 4 + vendor/angular-sanitize/angular-sanitize.js | 537 + .../angular-sanitize/angular-sanitize.min.js | 13 + vendor/angular-sanitize/bower.json | 17 + vendor/angular/angular.js | 14760 +++++++++ vendor/angular/angular.min.js | 162 + vendor/angular/bower.json | 14 + vendor/bootstrap-less-themes/README.md | 130 + vendor/bootstrap-less-themes/bower.json | 17 + .../themes/angular/forms.less | 18 + .../themes/default/overrides.less | 8 + .../themes/default/variables.less | 301 + .../themes/sapling/account.less | 7 + .../themes/sapling/overrides.less | 51 + .../themes/sapling/sticky-footer.less | 23 + .../themes/sapling/variables.less | 302 + vendor/bootstrap/.gitignore | 37 + vendor/bootstrap/.travis.yml | 3 + vendor/bootstrap/CHANGELOG.md | 360 + vendor/bootstrap/CONTRIBUTING.md | 75 + vendor/bootstrap/LICENSE | 176 + vendor/bootstrap/Makefile | 126 + vendor/bootstrap/README.md | 117 + vendor/bootstrap/component.json | 20 + vendor/bootstrap/composer.json | 9 + .../docs/assets/css/bootstrap-responsive.css | 1109 + .../bootstrap/docs/assets/css/bootstrap.css | 6158 ++++ vendor/bootstrap/docs/assets/css/docs.css | 1067 + .../ico/apple-touch-icon-114-precomposed.png | Bin 0 -> 11392 bytes .../ico/apple-touch-icon-144-precomposed.png | Bin 0 -> 16780 bytes .../ico/apple-touch-icon-57-precomposed.png | Bin 0 -> 4026 bytes .../ico/apple-touch-icon-72-precomposed.png | Bin 0 -> 5681 bytes vendor/bootstrap/docs/assets/ico/favicon.ico | Bin 0 -> 1150 bytes vendor/bootstrap/docs/assets/ico/favicon.png | Bin 0 -> 2711 bytes .../docs/assets/img/bootstrap-docs-readme.png | Bin 0 -> 30612 bytes .../assets/img/bootstrap-mdo-sfmoma-01.jpg | Bin 0 -> 125346 bytes .../assets/img/bootstrap-mdo-sfmoma-02.jpg | Bin 0 -> 81284 bytes .../assets/img/bootstrap-mdo-sfmoma-03.jpg | Bin 0 -> 49063 bytes .../assets/img/bs-docs-bootstrap-features.png | Bin 0 -> 11244 bytes .../assets/img/bs-docs-masthead-pattern.png | Bin 0 -> 6450 bytes .../img/bs-docs-responsive-illustrations.png | Bin 0 -> 10572 bytes .../assets/img/bs-docs-twitter-github.png | Bin 0 -> 30968 bytes .../assets/img/example-sites/8020select.png | Bin 0 -> 62853 bytes .../img/example-sites/adoptahydrant.png | Bin 0 -> 136480 bytes .../assets/img/example-sites/breakingnews.png | Bin 0 -> 72725 bytes .../docs/assets/img/example-sites/fleetio.png | Bin 0 -> 39837 bytes .../img/example-sites/gathercontent.png | Bin 0 -> 76560 bytes .../docs/assets/img/example-sites/jshint.png | Bin 0 -> 7258 bytes .../docs/assets/img/example-sites/kippt.png | Bin 0 -> 48259 bytes .../assets/img/example-sites/soundready.png | Bin 0 -> 50225 bytes .../examples/bootstrap-example-carousel.png | Bin 0 -> 339980 bytes .../img/examples/bootstrap-example-fluid.png | Bin 0 -> 209039 bytes .../bootstrap-example-justified-nav.png | Bin 0 -> 136021 bytes .../bootstrap-example-marketing-narrow.png | Bin 0 -> 117303 bytes .../examples/bootstrap-example-marketing.png | Bin 0 -> 134269 bytes .../img/examples/bootstrap-example-signin.png | Bin 0 -> 22037 bytes .../examples/bootstrap-example-starter.png | Bin 0 -> 36099 bytes .../bootstrap-example-sticky-footer.png | Bin 0 -> 30820 bytes .../img/examples/browser-icon-chrome.png | Bin 0 -> 55522 bytes .../img/examples/browser-icon-firefox.png | Bin 0 -> 175994 bytes .../img/examples/browser-icon-safari.png | Bin 0 -> 209527 bytes .../docs/assets/img/examples/slide-01.jpg | Bin 0 -> 83303 bytes .../docs/assets/img/examples/slide-02.jpg | Bin 0 -> 137070 bytes .../docs/assets/img/examples/slide-03.jpg | Bin 0 -> 137378 bytes .../assets/img/glyphicons-halflings-white.png | Bin 0 -> 8777 bytes .../docs/assets/img/glyphicons-halflings.png | Bin 0 -> 12799 bytes .../docs/assets/img/grid-baseline-20px.png | Bin 0 -> 84 bytes .../docs/assets/img/less-logo-large.png | Bin 0 -> 12824 bytes .../assets/img/responsive-illustrations.png | Bin 0 -> 1008 bytes vendor/bootstrap/docs/assets/js/README.md | 106 + .../bootstrap/docs/assets/js/application.js | 156 + .../docs/assets/js/bootstrap-affix.js | 117 + .../docs/assets/js/bootstrap-alert.js | 99 + .../docs/assets/js/bootstrap-button.js | 105 + .../docs/assets/js/bootstrap-carousel.js | 207 + .../docs/assets/js/bootstrap-collapse.js | 167 + .../docs/assets/js/bootstrap-dropdown.js | 165 + .../docs/assets/js/bootstrap-modal.js | 247 + .../docs/assets/js/bootstrap-popover.js | 114 + .../docs/assets/js/bootstrap-scrollspy.js | 162 + .../bootstrap/docs/assets/js/bootstrap-tab.js | 144 + .../docs/assets/js/bootstrap-tooltip.js | 361 + .../docs/assets/js/bootstrap-transition.js | 60 + .../docs/assets/js/bootstrap-typeahead.js | 335 + vendor/bootstrap/docs/assets/js/bootstrap.js | 2276 ++ .../bootstrap/docs/assets/js/bootstrap.min.js | 6 + .../js/google-code-prettify/prettify.css | 30 + .../js/google-code-prettify/prettify.js | 28 + .../bootstrap/docs/assets/js/holder/holder.js | 401 + vendor/bootstrap/docs/assets/js/html5shiv.js | 8 + vendor/bootstrap/docs/assets/js/jquery.js | 5 + vendor/bootstrap/docs/base-css.html | 2215 ++ vendor/bootstrap/docs/build/index.js | 44 + vendor/bootstrap/docs/build/package.json | 6 + vendor/bootstrap/docs/components.html | 2626 ++ vendor/bootstrap/docs/customize.html | 514 + vendor/bootstrap/docs/examples/carousel.html | 454 + vendor/bootstrap/docs/examples/fluid.html | 163 + vendor/bootstrap/docs/examples/hero.html | 126 + .../docs/examples/justified-nav.html | 174 + .../docs/examples/marketing-narrow.html | 137 + vendor/bootstrap/docs/examples/signin.html | 94 + .../docs/examples/starter-template.html | 79 + .../docs/examples/sticky-footer-navbar.html | 161 + .../docs/examples/sticky-footer.html | 125 + vendor/bootstrap/docs/extend.html | 282 + vendor/bootstrap/docs/getting-started.html | 377 + vendor/bootstrap/docs/index.html | 221 + vendor/bootstrap/docs/javascript.html | 1780 ++ vendor/bootstrap/docs/scaffolding.html | 602 + .../bootstrap/docs/templates/layout.mustache | 151 + .../docs/templates/pages/base-css.mustache | 2102 ++ .../docs/templates/pages/components.mustache | 2505 ++ .../docs/templates/pages/customize.mustache | 393 + .../docs/templates/pages/extend.mustache | 161 + .../templates/pages/getting-started.mustache | 256 + .../docs/templates/pages/index.mustache | 100 + .../docs/templates/pages/javascript.mustache | 1660 + .../docs/templates/pages/scaffolding.mustache | 485 + .../img/glyphicons-halflings-white.png | Bin 0 -> 8777 bytes vendor/bootstrap/img/glyphicons-halflings.png | Bin 0 -> 12799 bytes vendor/bootstrap/js/.jshintrc | 12 + vendor/bootstrap/js/bootstrap-affix.js | 117 + vendor/bootstrap/js/bootstrap-alert.js | 99 + vendor/bootstrap/js/bootstrap-button.js | 105 + vendor/bootstrap/js/bootstrap-carousel.js | 207 + vendor/bootstrap/js/bootstrap-collapse.js | 167 + vendor/bootstrap/js/bootstrap-dropdown.js | 165 + vendor/bootstrap/js/bootstrap-modal.js | 247 + vendor/bootstrap/js/bootstrap-popover.js | 114 + vendor/bootstrap/js/bootstrap-scrollspy.js | 162 + vendor/bootstrap/js/bootstrap-tab.js | 144 + vendor/bootstrap/js/bootstrap-tooltip.js | 361 + vendor/bootstrap/js/bootstrap-transition.js | 60 + vendor/bootstrap/js/bootstrap-typeahead.js | 335 + vendor/bootstrap/js/tests/index.html | 56 + vendor/bootstrap/js/tests/phantom.js | 63 + vendor/bootstrap/js/tests/server.js | 14 + .../js/tests/unit/bootstrap-affix.js | 25 + .../js/tests/unit/bootstrap-alert.js | 62 + .../js/tests/unit/bootstrap-button.js | 102 + .../js/tests/unit/bootstrap-carousel.js | 81 + .../js/tests/unit/bootstrap-collapse.js | 94 + .../js/tests/unit/bootstrap-dropdown.js | 151 + .../js/tests/unit/bootstrap-modal.js | 137 + .../js/tests/unit/bootstrap-phantom.js | 21 + .../js/tests/unit/bootstrap-popover.js | 113 + .../js/tests/unit/bootstrap-scrollspy.js | 37 + .../bootstrap/js/tests/unit/bootstrap-tab.js | 86 + .../js/tests/unit/bootstrap-tooltip.js | 294 + .../js/tests/unit/bootstrap-transition.js | 13 + .../js/tests/unit/bootstrap-typeahead.js | 236 + vendor/bootstrap/js/tests/vendor/jquery.js | 5 + vendor/bootstrap/js/tests/vendor/qunit.css | 232 + vendor/bootstrap/js/tests/vendor/qunit.js | 1510 + vendor/bootstrap/less/accordion.less | 34 + vendor/bootstrap/less/alerts.less | 79 + vendor/bootstrap/less/bootstrap.less | 63 + vendor/bootstrap/less/breadcrumbs.less | 24 + vendor/bootstrap/less/button-groups.less | 229 + vendor/bootstrap/less/buttons.less | 228 + vendor/bootstrap/less/carousel.less | 158 + vendor/bootstrap/less/close.less | 32 + vendor/bootstrap/less/code.less | 61 + .../bootstrap/less/component-animations.less | 22 + vendor/bootstrap/less/dropdowns.less | 237 + vendor/bootstrap/less/forms.less | 690 + vendor/bootstrap/less/grid.less | 21 + vendor/bootstrap/less/hero-unit.less | 25 + vendor/bootstrap/less/labels-badges.less | 84 + vendor/bootstrap/less/layouts.less | 16 + vendor/bootstrap/less/media.less | 55 + vendor/bootstrap/less/mixins.less | 702 + vendor/bootstrap/less/modals.less | 95 + vendor/bootstrap/less/navbar.less | 497 + vendor/bootstrap/less/navs.less | 409 + vendor/bootstrap/less/pager.less | 43 + vendor/bootstrap/less/pagination.less | 123 + vendor/bootstrap/less/popovers.less | 133 + vendor/bootstrap/less/progress-bars.less | 122 + vendor/bootstrap/less/reset.less | 216 + .../bootstrap/less/responsive-1200px-min.less | 28 + .../bootstrap/less/responsive-767px-max.less | 193 + .../less/responsive-768px-979px.less | 19 + vendor/bootstrap/less/responsive-navbar.less | 189 + .../bootstrap/less/responsive-utilities.less | 59 + vendor/bootstrap/less/responsive.less | 48 + vendor/bootstrap/less/scaffolding.less | 53 + vendor/bootstrap/less/sprites.less | 197 + vendor/bootstrap/less/tables.less | 244 + vendor/bootstrap/less/tests/buttons.html | 139 + vendor/bootstrap/less/tests/css-tests.css | 150 + vendor/bootstrap/less/tests/css-tests.html | 1399 + .../less/tests/forms-responsive.html | 71 + vendor/bootstrap/less/tests/forms.html | 179 + .../less/tests/navbar-fixed-top.html | 104 + .../less/tests/navbar-static-top.html | 107 + vendor/bootstrap/less/tests/navbar.html | 107 + vendor/bootstrap/less/thumbnails.less | 53 + vendor/bootstrap/less/tooltip.less | 70 + vendor/bootstrap/less/type.less | 247 + vendor/bootstrap/less/utilities.less | 30 + vendor/bootstrap/less/variables.less | 301 + vendor/bootstrap/less/wells.less | 29 + vendor/bootstrap/package.json | 26 + vendor/console-polyfill/.gitignore | 2 + vendor/console-polyfill/Makefile | 11 + vendor/console-polyfill/README.md | 30 + vendor/console-polyfill/component.json | 25 + vendor/console-polyfill/index.js | 15 + vendor/font-awesome/.gitignore | 29 + vendor/font-awesome/README.md | 22 + vendor/font-awesome/bower.json | 8 + .../font-awesome/css/font-awesome-ie7.min.css | 22 + vendor/font-awesome/css/font-awesome.css | 540 + vendor/font-awesome/css/font-awesome.min.css | 33 + .../docs/assets/css/font-awesome-ie7.min.css | 22 + .../docs/assets/css/font-awesome.css | 540 + .../docs/assets/css/font-awesome.min.css | 33 + .../font-awesome/docs/assets/css/prettify.css | 30 + vendor/font-awesome/docs/assets/css/site.css | 9 + .../docs/assets/font/FontAwesome.otf | Bin 0 -> 42288 bytes .../docs/assets/font/fontawesome-webfont.eot | Bin 0 -> 25395 bytes .../docs/assets/font/fontawesome-webfont.svg | 284 + .../docs/assets/font/fontawesome-webfont.ttf | Bin 0 -> 55096 bytes .../docs/assets/font/fontawesome-webfont.woff | Bin 0 -> 29380 bytes .../assets/font/museo_slab_300-webfont.eot | Bin 0 -> 51440 bytes .../assets/font/museo_slab_300-webfont.ttf | Bin 0 -> 51260 bytes .../assets/font/museo_slab_500-webfont.eot | Bin 0 -> 55516 bytes .../assets/font/museo_slab_500-webfont.ttf | Bin 0 -> 55336 bytes .../assets/font/proximanova-sbold-webfont.eot | Bin 0 -> 14174 bytes .../assets/font/proximanova-sbold-webfont.ttf | Bin 0 -> 32412 bytes .../docs/assets/font/proximanova-webfont.eot | Bin 0 -> 31323 bytes .../docs/assets/font/proximanova-webfont.ttf | Bin 0 -> 89732 bytes .../font-awesome/docs/assets/ico/favicon.ico | Bin 0 -> 1150 bytes .../docs/assets/img/contribution-sample.png | Bin 0 -> 2441 bytes .../docs/assets/img/fort_awesome.jpg | Bin 0 -> 114822 bytes .../assets/img/glyphicons-halflings-white.png | Bin 0 -> 8777 bytes .../docs/assets/img/glyphicons-halflings.png | Bin 0 -> 12799 bytes .../docs/assets/img/icon-flag.pdf | Bin 0 -> 184736 bytes .../docs/assets/js/backbone.min.js | 37 + .../docs/assets/js/bootstrap-222.min.js | 6 + .../docs/assets/js/index/index.js | 89 + .../docs/assets/js/jquery-1.7.1.min.js | 4 + .../docs/assets/js/prettify.min.js | 28 + .../docs/assets/js/underscore.min.js | 31 + .../docs/assets/less/font-awesome-ie7.less | 350 + .../docs/assets/less/font-awesome.less | 537 + .../docs/assets/less/font-site.less | 35 + .../font-awesome/docs/assets/less/mixins.less | 43 + .../font-awesome/docs/assets/less/site.less | 373 + .../docs/assets/less/twbs-222/accordion.less | 34 + .../docs/assets/less/twbs-222/alerts.less | 79 + .../docs/assets/less/twbs-222/bootstrap.less | 63 + .../assets/less/twbs-222/breadcrumbs.less | 24 + .../assets/less/twbs-222/button-groups.less | 227 + .../docs/assets/less/twbs-222/buttons.less | 230 + .../docs/assets/less/twbs-222/carousel.less | 131 + .../docs/assets/less/twbs-222/close.less | 31 + .../docs/assets/less/twbs-222/code.less | 61 + .../less/twbs-222/component-animations.less | 22 + .../docs/assets/less/twbs-222/dropdowns.less | 233 + .../docs/assets/less/twbs-222/forms.less | 687 + .../docs/assets/less/twbs-222/grid.less | 21 + .../docs/assets/less/twbs-222/hero-unit.less | 25 + .../assets/less/twbs-222/labels-badges.less | 82 + .../docs/assets/less/twbs-222/layouts.less | 16 + .../docs/assets/less/twbs-222/media.less | 55 + .../docs/assets/less/twbs-222/mixins.less | 686 + .../docs/assets/less/twbs-222/modals.less | 95 + .../docs/assets/less/twbs-222/navbar.less | 490 + .../docs/assets/less/twbs-222/navs.less | 391 + .../docs/assets/less/twbs-222/pager.less | 41 + .../docs/assets/less/twbs-222/pagination.less | 121 + .../docs/assets/less/twbs-222/popovers.less | 129 + .../assets/less/twbs-222/progress-bars.less | 122 + .../docs/assets/less/twbs-222/reset.less | 216 + .../less/twbs-222/responsive-1200px-min.less | 28 + .../less/twbs-222/responsive-767px-max.less | 193 + .../less/twbs-222/responsive-768px-979px.less | 19 + .../less/twbs-222/responsive-navbar.less | 185 + .../less/twbs-222/responsive-utilities.less | 43 + .../docs/assets/less/twbs-222/responsive.less | 57 + .../assets/less/twbs-222/scaffolding.less | 52 + .../docs/assets/less/twbs-222/sprites.less | 193 + .../docs/assets/less/twbs-222/tables.less | 237 + .../assets/less/twbs-222/tests/buttons.html | 139 + .../assets/less/twbs-222/tests/css-tests.css | 139 + .../assets/less/twbs-222/tests/css-tests.html | 1345 + .../less/twbs-222/tests/forms-responsive.html | 71 + .../assets/less/twbs-222/tests/forms.html | 179 + .../less/twbs-222/tests/navbar-fixed-top.html | 104 + .../twbs-222/tests/navbar-static-top.html | 107 + .../assets/less/twbs-222/tests/navbar.html | 107 + .../docs/assets/less/twbs-222/thumbnails.less | 52 + .../docs/assets/less/twbs-222/tooltip.less | 70 + .../docs/assets/less/twbs-222/type.less | 235 + .../docs/assets/less/twbs-222/utilities.less | 30 + .../docs/assets/less/twbs-222/variables.less | 301 + .../docs/assets/less/twbs-222/wells.less | 29 + .../docs/assets/less/variables.less | 303 + vendor/font-awesome/docs/design.html | 333 + vendor/font-awesome/docs/index.html | 1462 + vendor/font-awesome/docs/test.html | 584 + vendor/font-awesome/font/FontAwesome.otf | Bin 0 -> 48748 bytes .../font-awesome/font/fontawesome-webfont.eot | Bin 0 -> 25395 bytes .../font-awesome/font/fontawesome-webfont.svg | 284 + .../font-awesome/font/fontawesome-webfont.ttf | Bin 0 -> 55096 bytes .../font/fontawesome-webfont.woff | Bin 0 -> 29380 bytes .../font-awesome/less/font-awesome-ie7.less | 350 + vendor/font-awesome/less/font-awesome.less | 537 + vendor/font-awesome/sass/font-awesome.sass | 758 + vendor/font-awesome/sass/font-awesome.scss | 534 + vendor/jquery/.gitignore | 3 + vendor/jquery/README.md | 4 + vendor/jquery/component.json | 21 + vendor/jquery/composer.json | 30 + vendor/jquery/jquery.js | 9472 ++++++ vendor/jquery/jquery.min.js | 2 + vendor/jquery/package.json | 7 + vendor/metro | 1 + 340 files changed, 117668 insertions(+) create mode 100644 app/assets/test/angular-scenario.js create mode 100644 app/assets/test/runner.html create mode 100644 app/scripts/controllers.ls create mode 100644 app/scripts/directives.ls create mode 100644 app/scripts/filters.ls create mode 100644 app/scripts/services.ls create mode 100644 bower.json create mode 100644 vendor/angular-cookies/README.md create mode 100644 vendor/angular-cookies/angular-cookies.js create mode 100644 vendor/angular-cookies/angular-cookies.min.js create mode 100644 vendor/angular-cookies/bower.json create mode 100644 vendor/angular-mocks/README.md create mode 100644 vendor/angular-mocks/angular-mocks.js create mode 100644 vendor/angular-mocks/bower.json create mode 100644 vendor/angular-resource/README.md create mode 100644 vendor/angular-resource/angular-resource.js create mode 100644 vendor/angular-resource/angular-resource.min.js create mode 100644 vendor/angular-resource/bower.json create mode 100644 vendor/angular-sanitize/README.md create mode 100644 vendor/angular-sanitize/angular-sanitize.js create mode 100644 vendor/angular-sanitize/angular-sanitize.min.js create mode 100644 vendor/angular-sanitize/bower.json create mode 100644 vendor/angular/angular.js create mode 100644 vendor/angular/angular.min.js create mode 100644 vendor/angular/bower.json create mode 100644 vendor/bootstrap-less-themes/README.md create mode 100644 vendor/bootstrap-less-themes/bower.json create mode 100644 vendor/bootstrap-less-themes/themes/angular/forms.less create mode 100644 vendor/bootstrap-less-themes/themes/default/overrides.less create mode 100644 vendor/bootstrap-less-themes/themes/default/variables.less create mode 100644 vendor/bootstrap-less-themes/themes/sapling/account.less create mode 100644 vendor/bootstrap-less-themes/themes/sapling/overrides.less create mode 100644 vendor/bootstrap-less-themes/themes/sapling/sticky-footer.less create mode 100644 vendor/bootstrap-less-themes/themes/sapling/variables.less create mode 100644 vendor/bootstrap/.gitignore create mode 100644 vendor/bootstrap/.travis.yml create mode 100644 vendor/bootstrap/CHANGELOG.md create mode 100644 vendor/bootstrap/CONTRIBUTING.md create mode 100644 vendor/bootstrap/LICENSE create mode 100644 vendor/bootstrap/Makefile create mode 100644 vendor/bootstrap/README.md create mode 100644 vendor/bootstrap/component.json create mode 100644 vendor/bootstrap/composer.json create mode 100644 vendor/bootstrap/docs/assets/css/bootstrap-responsive.css create mode 100644 vendor/bootstrap/docs/assets/css/bootstrap.css create mode 100644 vendor/bootstrap/docs/assets/css/docs.css create mode 100644 vendor/bootstrap/docs/assets/ico/apple-touch-icon-114-precomposed.png create mode 100644 vendor/bootstrap/docs/assets/ico/apple-touch-icon-144-precomposed.png create mode 100644 vendor/bootstrap/docs/assets/ico/apple-touch-icon-57-precomposed.png create mode 100644 vendor/bootstrap/docs/assets/ico/apple-touch-icon-72-precomposed.png create mode 100644 vendor/bootstrap/docs/assets/ico/favicon.ico create mode 100644 vendor/bootstrap/docs/assets/ico/favicon.png create mode 100644 vendor/bootstrap/docs/assets/img/bootstrap-docs-readme.png create mode 100644 vendor/bootstrap/docs/assets/img/bootstrap-mdo-sfmoma-01.jpg create mode 100644 vendor/bootstrap/docs/assets/img/bootstrap-mdo-sfmoma-02.jpg create mode 100644 vendor/bootstrap/docs/assets/img/bootstrap-mdo-sfmoma-03.jpg create mode 100644 vendor/bootstrap/docs/assets/img/bs-docs-bootstrap-features.png create mode 100644 vendor/bootstrap/docs/assets/img/bs-docs-masthead-pattern.png create mode 100644 vendor/bootstrap/docs/assets/img/bs-docs-responsive-illustrations.png create mode 100644 vendor/bootstrap/docs/assets/img/bs-docs-twitter-github.png create mode 100644 vendor/bootstrap/docs/assets/img/example-sites/8020select.png create mode 100644 vendor/bootstrap/docs/assets/img/example-sites/adoptahydrant.png create mode 100644 vendor/bootstrap/docs/assets/img/example-sites/breakingnews.png create mode 100644 vendor/bootstrap/docs/assets/img/example-sites/fleetio.png create mode 100644 vendor/bootstrap/docs/assets/img/example-sites/gathercontent.png create mode 100644 vendor/bootstrap/docs/assets/img/example-sites/jshint.png create mode 100644 vendor/bootstrap/docs/assets/img/example-sites/kippt.png create mode 100644 vendor/bootstrap/docs/assets/img/example-sites/soundready.png create mode 100644 vendor/bootstrap/docs/assets/img/examples/bootstrap-example-carousel.png create mode 100644 vendor/bootstrap/docs/assets/img/examples/bootstrap-example-fluid.png create mode 100644 vendor/bootstrap/docs/assets/img/examples/bootstrap-example-justified-nav.png create mode 100644 vendor/bootstrap/docs/assets/img/examples/bootstrap-example-marketing-narrow.png create mode 100644 vendor/bootstrap/docs/assets/img/examples/bootstrap-example-marketing.png create mode 100644 vendor/bootstrap/docs/assets/img/examples/bootstrap-example-signin.png create mode 100644 vendor/bootstrap/docs/assets/img/examples/bootstrap-example-starter.png create mode 100644 vendor/bootstrap/docs/assets/img/examples/bootstrap-example-sticky-footer.png create mode 100644 vendor/bootstrap/docs/assets/img/examples/browser-icon-chrome.png create mode 100644 vendor/bootstrap/docs/assets/img/examples/browser-icon-firefox.png create mode 100644 vendor/bootstrap/docs/assets/img/examples/browser-icon-safari.png create mode 100644 vendor/bootstrap/docs/assets/img/examples/slide-01.jpg create mode 100644 vendor/bootstrap/docs/assets/img/examples/slide-02.jpg create mode 100644 vendor/bootstrap/docs/assets/img/examples/slide-03.jpg create mode 100644 vendor/bootstrap/docs/assets/img/glyphicons-halflings-white.png create mode 100644 vendor/bootstrap/docs/assets/img/glyphicons-halflings.png create mode 100644 vendor/bootstrap/docs/assets/img/grid-baseline-20px.png create mode 100644 vendor/bootstrap/docs/assets/img/less-logo-large.png create mode 100644 vendor/bootstrap/docs/assets/img/responsive-illustrations.png create mode 100644 vendor/bootstrap/docs/assets/js/README.md create mode 100644 vendor/bootstrap/docs/assets/js/application.js create mode 100644 vendor/bootstrap/docs/assets/js/bootstrap-affix.js create mode 100644 vendor/bootstrap/docs/assets/js/bootstrap-alert.js create mode 100644 vendor/bootstrap/docs/assets/js/bootstrap-button.js create mode 100644 vendor/bootstrap/docs/assets/js/bootstrap-carousel.js create mode 100644 vendor/bootstrap/docs/assets/js/bootstrap-collapse.js create mode 100644 vendor/bootstrap/docs/assets/js/bootstrap-dropdown.js create mode 100644 vendor/bootstrap/docs/assets/js/bootstrap-modal.js create mode 100644 vendor/bootstrap/docs/assets/js/bootstrap-popover.js create mode 100644 vendor/bootstrap/docs/assets/js/bootstrap-scrollspy.js create mode 100644 vendor/bootstrap/docs/assets/js/bootstrap-tab.js create mode 100644 vendor/bootstrap/docs/assets/js/bootstrap-tooltip.js create mode 100644 vendor/bootstrap/docs/assets/js/bootstrap-transition.js create mode 100644 vendor/bootstrap/docs/assets/js/bootstrap-typeahead.js create mode 100644 vendor/bootstrap/docs/assets/js/bootstrap.js create mode 100644 vendor/bootstrap/docs/assets/js/bootstrap.min.js create mode 100644 vendor/bootstrap/docs/assets/js/google-code-prettify/prettify.css create mode 100644 vendor/bootstrap/docs/assets/js/google-code-prettify/prettify.js create mode 100755 vendor/bootstrap/docs/assets/js/holder/holder.js create mode 100644 vendor/bootstrap/docs/assets/js/html5shiv.js create mode 100644 vendor/bootstrap/docs/assets/js/jquery.js create mode 100644 vendor/bootstrap/docs/base-css.html create mode 100644 vendor/bootstrap/docs/build/index.js create mode 100644 vendor/bootstrap/docs/build/package.json create mode 100644 vendor/bootstrap/docs/components.html create mode 100644 vendor/bootstrap/docs/customize.html create mode 100644 vendor/bootstrap/docs/examples/carousel.html create mode 100644 vendor/bootstrap/docs/examples/fluid.html create mode 100644 vendor/bootstrap/docs/examples/hero.html create mode 100644 vendor/bootstrap/docs/examples/justified-nav.html create mode 100644 vendor/bootstrap/docs/examples/marketing-narrow.html create mode 100644 vendor/bootstrap/docs/examples/signin.html create mode 100644 vendor/bootstrap/docs/examples/starter-template.html create mode 100644 vendor/bootstrap/docs/examples/sticky-footer-navbar.html create mode 100644 vendor/bootstrap/docs/examples/sticky-footer.html create mode 100644 vendor/bootstrap/docs/extend.html create mode 100644 vendor/bootstrap/docs/getting-started.html create mode 100644 vendor/bootstrap/docs/index.html create mode 100644 vendor/bootstrap/docs/javascript.html create mode 100644 vendor/bootstrap/docs/scaffolding.html create mode 100644 vendor/bootstrap/docs/templates/layout.mustache create mode 100644 vendor/bootstrap/docs/templates/pages/base-css.mustache create mode 100644 vendor/bootstrap/docs/templates/pages/components.mustache create mode 100644 vendor/bootstrap/docs/templates/pages/customize.mustache create mode 100644 vendor/bootstrap/docs/templates/pages/extend.mustache create mode 100644 vendor/bootstrap/docs/templates/pages/getting-started.mustache create mode 100644 vendor/bootstrap/docs/templates/pages/index.mustache create mode 100644 vendor/bootstrap/docs/templates/pages/javascript.mustache create mode 100644 vendor/bootstrap/docs/templates/pages/scaffolding.mustache create mode 100644 vendor/bootstrap/img/glyphicons-halflings-white.png create mode 100644 vendor/bootstrap/img/glyphicons-halflings.png create mode 100644 vendor/bootstrap/js/.jshintrc create mode 100644 vendor/bootstrap/js/bootstrap-affix.js create mode 100644 vendor/bootstrap/js/bootstrap-alert.js create mode 100644 vendor/bootstrap/js/bootstrap-button.js create mode 100644 vendor/bootstrap/js/bootstrap-carousel.js create mode 100644 vendor/bootstrap/js/bootstrap-collapse.js create mode 100644 vendor/bootstrap/js/bootstrap-dropdown.js create mode 100644 vendor/bootstrap/js/bootstrap-modal.js create mode 100644 vendor/bootstrap/js/bootstrap-popover.js create mode 100644 vendor/bootstrap/js/bootstrap-scrollspy.js create mode 100644 vendor/bootstrap/js/bootstrap-tab.js create mode 100644 vendor/bootstrap/js/bootstrap-tooltip.js create mode 100644 vendor/bootstrap/js/bootstrap-transition.js create mode 100644 vendor/bootstrap/js/bootstrap-typeahead.js create mode 100644 vendor/bootstrap/js/tests/index.html create mode 100644 vendor/bootstrap/js/tests/phantom.js create mode 100644 vendor/bootstrap/js/tests/server.js create mode 100644 vendor/bootstrap/js/tests/unit/bootstrap-affix.js create mode 100644 vendor/bootstrap/js/tests/unit/bootstrap-alert.js create mode 100644 vendor/bootstrap/js/tests/unit/bootstrap-button.js create mode 100644 vendor/bootstrap/js/tests/unit/bootstrap-carousel.js create mode 100644 vendor/bootstrap/js/tests/unit/bootstrap-collapse.js create mode 100644 vendor/bootstrap/js/tests/unit/bootstrap-dropdown.js create mode 100644 vendor/bootstrap/js/tests/unit/bootstrap-modal.js create mode 100644 vendor/bootstrap/js/tests/unit/bootstrap-phantom.js create mode 100644 vendor/bootstrap/js/tests/unit/bootstrap-popover.js create mode 100644 vendor/bootstrap/js/tests/unit/bootstrap-scrollspy.js create mode 100644 vendor/bootstrap/js/tests/unit/bootstrap-tab.js create mode 100644 vendor/bootstrap/js/tests/unit/bootstrap-tooltip.js create mode 100644 vendor/bootstrap/js/tests/unit/bootstrap-transition.js create mode 100644 vendor/bootstrap/js/tests/unit/bootstrap-typeahead.js create mode 100644 vendor/bootstrap/js/tests/vendor/jquery.js create mode 100644 vendor/bootstrap/js/tests/vendor/qunit.css create mode 100644 vendor/bootstrap/js/tests/vendor/qunit.js create mode 100644 vendor/bootstrap/less/accordion.less create mode 100644 vendor/bootstrap/less/alerts.less create mode 100644 vendor/bootstrap/less/bootstrap.less create mode 100644 vendor/bootstrap/less/breadcrumbs.less create mode 100644 vendor/bootstrap/less/button-groups.less create mode 100644 vendor/bootstrap/less/buttons.less create mode 100644 vendor/bootstrap/less/carousel.less create mode 100644 vendor/bootstrap/less/close.less create mode 100644 vendor/bootstrap/less/code.less create mode 100644 vendor/bootstrap/less/component-animations.less create mode 100644 vendor/bootstrap/less/dropdowns.less create mode 100644 vendor/bootstrap/less/forms.less create mode 100644 vendor/bootstrap/less/grid.less create mode 100644 vendor/bootstrap/less/hero-unit.less create mode 100644 vendor/bootstrap/less/labels-badges.less create mode 100644 vendor/bootstrap/less/layouts.less create mode 100644 vendor/bootstrap/less/media.less create mode 100644 vendor/bootstrap/less/mixins.less create mode 100644 vendor/bootstrap/less/modals.less create mode 100644 vendor/bootstrap/less/navbar.less create mode 100644 vendor/bootstrap/less/navs.less create mode 100644 vendor/bootstrap/less/pager.less create mode 100644 vendor/bootstrap/less/pagination.less create mode 100644 vendor/bootstrap/less/popovers.less create mode 100644 vendor/bootstrap/less/progress-bars.less create mode 100644 vendor/bootstrap/less/reset.less create mode 100644 vendor/bootstrap/less/responsive-1200px-min.less create mode 100644 vendor/bootstrap/less/responsive-767px-max.less create mode 100644 vendor/bootstrap/less/responsive-768px-979px.less create mode 100644 vendor/bootstrap/less/responsive-navbar.less create mode 100644 vendor/bootstrap/less/responsive-utilities.less create mode 100644 vendor/bootstrap/less/responsive.less create mode 100644 vendor/bootstrap/less/scaffolding.less create mode 100644 vendor/bootstrap/less/sprites.less create mode 100644 vendor/bootstrap/less/tables.less create mode 100644 vendor/bootstrap/less/tests/buttons.html create mode 100644 vendor/bootstrap/less/tests/css-tests.css create mode 100644 vendor/bootstrap/less/tests/css-tests.html create mode 100644 vendor/bootstrap/less/tests/forms-responsive.html create mode 100644 vendor/bootstrap/less/tests/forms.html create mode 100644 vendor/bootstrap/less/tests/navbar-fixed-top.html create mode 100644 vendor/bootstrap/less/tests/navbar-static-top.html create mode 100644 vendor/bootstrap/less/tests/navbar.html create mode 100644 vendor/bootstrap/less/thumbnails.less create mode 100644 vendor/bootstrap/less/tooltip.less create mode 100644 vendor/bootstrap/less/type.less create mode 100644 vendor/bootstrap/less/utilities.less create mode 100644 vendor/bootstrap/less/variables.less create mode 100644 vendor/bootstrap/less/wells.less create mode 100644 vendor/bootstrap/package.json create mode 100644 vendor/console-polyfill/.gitignore create mode 100644 vendor/console-polyfill/Makefile create mode 100644 vendor/console-polyfill/README.md create mode 100644 vendor/console-polyfill/component.json create mode 100644 vendor/console-polyfill/index.js create mode 100644 vendor/font-awesome/.gitignore create mode 100644 vendor/font-awesome/README.md create mode 100644 vendor/font-awesome/bower.json create mode 100644 vendor/font-awesome/css/font-awesome-ie7.min.css create mode 100644 vendor/font-awesome/css/font-awesome.css create mode 100644 vendor/font-awesome/css/font-awesome.min.css create mode 100644 vendor/font-awesome/docs/assets/css/font-awesome-ie7.min.css create mode 100644 vendor/font-awesome/docs/assets/css/font-awesome.css create mode 100644 vendor/font-awesome/docs/assets/css/font-awesome.min.css create mode 100755 vendor/font-awesome/docs/assets/css/prettify.css create mode 100644 vendor/font-awesome/docs/assets/css/site.css create mode 100644 vendor/font-awesome/docs/assets/font/FontAwesome.otf create mode 100755 vendor/font-awesome/docs/assets/font/fontawesome-webfont.eot create mode 100755 vendor/font-awesome/docs/assets/font/fontawesome-webfont.svg create mode 100755 vendor/font-awesome/docs/assets/font/fontawesome-webfont.ttf create mode 100755 vendor/font-awesome/docs/assets/font/fontawesome-webfont.woff create mode 100755 vendor/font-awesome/docs/assets/font/museo_slab_300-webfont.eot create mode 100755 vendor/font-awesome/docs/assets/font/museo_slab_300-webfont.ttf create mode 100755 vendor/font-awesome/docs/assets/font/museo_slab_500-webfont.eot create mode 100755 vendor/font-awesome/docs/assets/font/museo_slab_500-webfont.ttf create mode 100755 vendor/font-awesome/docs/assets/font/proximanova-sbold-webfont.eot create mode 100755 vendor/font-awesome/docs/assets/font/proximanova-sbold-webfont.ttf create mode 100755 vendor/font-awesome/docs/assets/font/proximanova-webfont.eot create mode 100755 vendor/font-awesome/docs/assets/font/proximanova-webfont.ttf create mode 100644 vendor/font-awesome/docs/assets/ico/favicon.ico create mode 100644 vendor/font-awesome/docs/assets/img/contribution-sample.png create mode 100644 vendor/font-awesome/docs/assets/img/fort_awesome.jpg create mode 100644 vendor/font-awesome/docs/assets/img/glyphicons-halflings-white.png create mode 100644 vendor/font-awesome/docs/assets/img/glyphicons-halflings.png create mode 100644 vendor/font-awesome/docs/assets/img/icon-flag.pdf create mode 100644 vendor/font-awesome/docs/assets/js/backbone.min.js create mode 100644 vendor/font-awesome/docs/assets/js/bootstrap-222.min.js create mode 100644 vendor/font-awesome/docs/assets/js/index/index.js create mode 100644 vendor/font-awesome/docs/assets/js/jquery-1.7.1.min.js create mode 100644 vendor/font-awesome/docs/assets/js/prettify.min.js create mode 100644 vendor/font-awesome/docs/assets/js/underscore.min.js create mode 100644 vendor/font-awesome/docs/assets/less/font-awesome-ie7.less create mode 100644 vendor/font-awesome/docs/assets/less/font-awesome.less create mode 100644 vendor/font-awesome/docs/assets/less/font-site.less create mode 100644 vendor/font-awesome/docs/assets/less/mixins.less create mode 100644 vendor/font-awesome/docs/assets/less/site.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/accordion.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/alerts.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/bootstrap.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/breadcrumbs.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/button-groups.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/buttons.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/carousel.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/close.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/code.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/component-animations.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/dropdowns.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/forms.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/grid.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/hero-unit.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/labels-badges.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/layouts.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/media.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/mixins.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/modals.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/navbar.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/navs.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/pager.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/pagination.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/popovers.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/progress-bars.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/reset.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/responsive-1200px-min.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/responsive-767px-max.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/responsive-768px-979px.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/responsive-navbar.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/responsive-utilities.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/responsive.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/scaffolding.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/sprites.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/tables.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/tests/buttons.html create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/tests/css-tests.css create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/tests/css-tests.html create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/tests/forms-responsive.html create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/tests/forms.html create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/tests/navbar-fixed-top.html create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/tests/navbar-static-top.html create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/tests/navbar.html create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/thumbnails.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/tooltip.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/type.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/utilities.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/variables.less create mode 100755 vendor/font-awesome/docs/assets/less/twbs-222/wells.less create mode 100755 vendor/font-awesome/docs/assets/less/variables.less create mode 100644 vendor/font-awesome/docs/design.html create mode 100644 vendor/font-awesome/docs/index.html create mode 100644 vendor/font-awesome/docs/test.html create mode 100644 vendor/font-awesome/font/FontAwesome.otf create mode 100755 vendor/font-awesome/font/fontawesome-webfont.eot create mode 100755 vendor/font-awesome/font/fontawesome-webfont.svg create mode 100755 vendor/font-awesome/font/fontawesome-webfont.ttf create mode 100755 vendor/font-awesome/font/fontawesome-webfont.woff create mode 100644 vendor/font-awesome/less/font-awesome-ie7.less create mode 100644 vendor/font-awesome/less/font-awesome.less create mode 100644 vendor/font-awesome/sass/font-awesome.sass create mode 100644 vendor/font-awesome/sass/font-awesome.scss create mode 100644 vendor/jquery/.gitignore create mode 100644 vendor/jquery/README.md create mode 100644 vendor/jquery/component.json create mode 100644 vendor/jquery/composer.json create mode 100644 vendor/jquery/jquery.js create mode 100644 vendor/jquery/jquery.min.js create mode 100644 vendor/jquery/package.json create mode 160000 vendor/metro diff --git a/.gitignore b/.gitignore index 847473f..11e5310 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ node_modules/* npm-debug.log *.swp + +test/test-results.xml diff --git a/app/assets/test/angular-scenario.js b/app/assets/test/angular-scenario.js new file mode 100644 index 0000000..7a22f37 --- /dev/null +++ b/app/assets/test/angular-scenario.js @@ -0,0 +1,26011 @@ +/*! + * jQuery JavaScript Library v1.7.2 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Wed Mar 21 12:46:34 2012 -0700 + */ +(function( window, undefined ) { +'use strict'; + +// Use the correct document accordingly with window argument (sandbox) +var document = window.document, + navigator = window.navigator, + location = window.location; +var jQuery = (function() { + +// Define a local copy of jQuery +var jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // A central reference to the root jQuery(document) + rootjQuery, + + // A simple way to check for HTML strings or ID strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Check if a string has a non-whitespace character in it + rnotwhite = /\S/, + + // Used for trimming whitespace + trimLeft = /^\s+/, + trimRight = /\s+$/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, + rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + + // Useragent RegExp + rwebkit = /(webkit)[ \/]([\w.]+)/, + ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, + rmsie = /(msie) ([\w.]+)/, + rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, + + // Matches dashed string for camelizing + rdashAlpha = /-([a-z]|[0-9])/ig, + rmsPrefix = /^-ms-/, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // Keep a UserAgent string for use with jQuery.browser + userAgent = navigator.userAgent, + + // For matching the engine and version of the browser + browserMatch, + + // The deferred used on DOM ready + readyList, + + // The ready event handler + DOMContentLoaded, + + // Save a reference to some core methods + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty, + push = Array.prototype.push, + slice = Array.prototype.slice, + trim = String.prototype.trim, + indexOf = Array.prototype.indexOf, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), or $(undefined) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // The body element only exists once, optimize finding it + if ( selector === "body" && !context && document.body ) { + this.context = document; + this[0] = document.body; + this.selector = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + // Are we dealing with HTML string or an ID? + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = quickExpr.exec( selector ); + } + + // Verify a match, and that no context was specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = ( context ? context.ownerDocument || context : document ); + + // If a single string is passed in and it's a single tag + // just do a createElement and skip the rest + ret = rsingleTag.exec( selector ); + + if ( ret ) { + if ( jQuery.isPlainObject( context ) ) { + selector = [ document.createElement( ret[1] ) ]; + jQuery.fn.attr.call( selector, context, true ); + + } else { + selector = [ doc.createElement( ret[1] ) ]; + } + + } else { + ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); + selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; + } + + return jQuery.merge( this, selector ); + + // HANDLE: $("#id") + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The current version of jQuery being used + jquery: "1.7.2", + + // The default length of a jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return slice.call( this, 0 ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + // Build a new jQuery matched element set + var ret = this.constructor(); + + if ( jQuery.isArray( elems ) ) { + push.apply( ret, elems ); + + } else { + jQuery.merge( ret, elems ); + } + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) { + ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; + } else if ( name ) { + ret.selector = this.selector + "." + name + "(" + selector + ")"; + } + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Attach the listeners + jQuery.bindReady(); + + // Add the callback + readyList.add( fn ); + + return this; + }, + + eq: function( i ) { + i = +i; + return i === -1 ? + this.slice( i ) : + this.slice( i, i + 1 ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ), + "slice", slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + // Either a released hold or an DOMready/load event and not yet ready + if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready, 1 ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.fireWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger( "ready" ).off( "ready" ); + } + } + }, + + bindReady: function() { + if ( readyList ) { + return; + } + + readyList = jQuery.Callbacks( "once memory" ); + + // Catch cases where $(document).ready() is called after the + // browser event has already occurred. + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + return setTimeout( jQuery.ready, 1 ); + } + + // Mozilla, Opera and webkit nightlies currently support this event + if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", jQuery.ready, false ); + + // If IE event model is used + } else if ( document.attachEvent ) { + // ensure firing before onload, + // maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", DOMContentLoaded ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var toplevel = false; + + try { + toplevel = window.frameElement == null; + } catch(e) {} + + if ( document.documentElement.doScroll && toplevel ) { + doScrollCheck(); + } + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ toString.call(obj) ] || "object"; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + for ( var name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + parseJSON: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + + } + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + var xml, tmp; + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && rnotwhite.test( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); + }, + + // args is for internal usage only + each: function( object, callback, args ) { + var name, i = 0, + length = object.length, + isObj = length === undefined || jQuery.isFunction( object ); + + if ( args ) { + if ( isObj ) { + for ( name in object ) { + if ( callback.apply( object[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( object[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in object ) { + if ( callback.call( object[ name ], name, object[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { + break; + } + } + } + } + + return object; + }, + + // Use native String.trim function wherever possible + trim: trim ? + function( text ) { + return text == null ? + "" : + trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); + }, + + // results is for internal usage only + makeArray: function( array, results ) { + var ret = results || []; + + if ( array != null ) { + // The window, strings (and functions) also have 'length' + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + var type = jQuery.type( array ); + + if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { + push.call( ret, array ); + } else { + jQuery.merge( ret, array ); + } + } + + return ret; + }, + + inArray: function( elem, array, i ) { + var len; + + if ( array ) { + if ( indexOf ) { + return indexOf.call( array, elem, i ); + } + + len = array.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in array && array[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var i = first.length, + j = 0; + + if ( typeof second.length === "number" ) { + for ( var l = second.length; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var ret = [], retVal; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( var i = 0, length = elems.length; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, key, ret = [], + i = 0, + length = elems.length, + // jquery objects are treated as arrays + isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( key in elems ) { + value = callback( elems[ key ], key, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return ret.concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + if ( typeof context === "string" ) { + var tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + var args = slice.call( arguments, 2 ), + proxy = function() { + return fn.apply( context, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; + + return proxy; + }, + + // Mutifunctional method to get and set values to a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, pass ) { + var exec, + bulk = key == null, + i = 0, + length = elems.length; + + // Sets many values + if ( key && typeof key === "object" ) { + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); + } + chainable = 1; + + // Sets one value + } else if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = pass === undefined && jQuery.isFunction( value ); + + if ( bulk ) { + // Bulk operations only iterate when executing function values + if ( exec ) { + exec = fn; + fn = function( elem, key, value ) { + return exec.call( jQuery( elem ), value ); + }; + + // Otherwise they run against the entire set + } else { + fn.call( elems, value ); + fn = null; + } + } + + if ( fn ) { + for (; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + } + + chainable = 1; + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + }, + + // Use of jQuery.browser is frowned upon. + // More details: http://docs.jquery.com/Utilities/jQuery.browser + uaMatch: function( ua ) { + ua = ua.toLowerCase(); + + var match = rwebkit.exec( ua ) || + ropera.exec( ua ) || + rmsie.exec( ua ) || + ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || + []; + + return { browser: match[1] || "", version: match[2] || "0" }; + }, + + sub: function() { + function jQuerySub( selector, context ) { + return new jQuerySub.fn.init( selector, context ); + } + jQuery.extend( true, jQuerySub, this ); + jQuerySub.superclass = this; + jQuerySub.fn = jQuerySub.prototype = this(); + jQuerySub.fn.constructor = jQuerySub; + jQuerySub.sub = this.sub; + jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { + context = jQuerySub( context ); + } + + return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); + }; + jQuerySub.fn.init.prototype = jQuerySub.fn; + var rootjQuerySub = jQuerySub(document); + return jQuerySub; + }, + + browser: {} +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +browserMatch = jQuery.uaMatch( userAgent ); +if ( browserMatch.browser ) { + jQuery.browser[ browserMatch.browser ] = true; + jQuery.browser.version = browserMatch.version; +} + +// Deprecated, use jQuery.browser.webkit instead +if ( jQuery.browser.webkit ) { + jQuery.browser.safari = true; +} + +// IE doesn't match non-breaking spaces with \s +if ( rnotwhite.test( "\xA0" ) ) { + trimLeft = /^[\s\xA0]+/; + trimRight = /[\s\xA0]+$/; +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); + +// Cleanup functions for the document ready method +if ( document.addEventListener ) { + DOMContentLoaded = function() { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + }; + +} else if ( document.attachEvent ) { + DOMContentLoaded = function() { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( document.readyState === "complete" ) { + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }; +} + +// The DOM ready check for Internet Explorer +function doScrollCheck() { + if ( jQuery.isReady ) { + return; + } + + try { + // If IE is used, use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + document.documentElement.doScroll("left"); + } catch(e) { + setTimeout( doScrollCheck, 1 ); + return; + } + + // and execute any waiting functions + jQuery.ready(); +} + +return jQuery; + +})(); + + +// String to Object flags format cache +var flagsCache = {}; + +// Convert String-formatted flags into Object-formatted ones and store in cache +function createFlags( flags ) { + var object = flagsCache[ flags ] = {}, + i, length; + flags = flags.split( /\s+/ ); + for ( i = 0, length = flags.length; i < length; i++ ) { + object[ flags[i] ] = true; + } + return object; +} + +/* + * Create a callback list using the following parameters: + * + * flags: an optional list of space-separated flags that will change how + * the callback list behaves + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible flags: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( flags ) { + + // Convert flags from String-formatted to Object-formatted + // (we check in cache first) + flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; + + var // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = [], + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Add one or several callbacks to the list + add = function( args ) { + var i, + length, + elem, + type, + actual; + for ( i = 0, length = args.length; i < length; i++ ) { + elem = args[ i ]; + type = jQuery.type( elem ); + if ( type === "array" ) { + // Inspect recursively + add( elem ); + } else if ( type === "function" ) { + // Add if not in unique mode and callback is not in + if ( !flags.unique || !self.has( elem ) ) { + list.push( elem ); + } + } + } + }, + // Fire callbacks + fire = function( context, args ) { + args = args || []; + memory = !flags.memory || [ context, args ]; + fired = true; + firing = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { + memory = true; // Mark as halted + break; + } + } + firing = false; + if ( list ) { + if ( !flags.once ) { + if ( stack && stack.length ) { + memory = stack.shift(); + self.fireWith( memory[ 0 ], memory[ 1 ] ); + } + } else if ( memory === true ) { + self.disable(); + } else { + list = []; + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + var length = list.length; + add( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away, unless previous + // firing was halted (stopOnFalse) + } else if ( memory && memory !== true ) { + firingStart = length; + fire( memory[ 0 ], memory[ 1 ] ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + var args = arguments, + argIndex = 0, + argLength = args.length; + for ( ; argIndex < argLength ; argIndex++ ) { + for ( var i = 0; i < list.length; i++ ) { + if ( args[ argIndex ] === list[ i ] ) { + // Handle firingIndex and firingLength + if ( firing ) { + if ( i <= firingLength ) { + firingLength--; + if ( i <= firingIndex ) { + firingIndex--; + } + } + } + // Remove the element + list.splice( i--, 1 ); + // If we have some unicity property then + // we only need to do this once + if ( flags.unique ) { + break; + } + } + } + } + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + if ( list ) { + var i = 0, + length = list.length; + for ( ; i < length; i++ ) { + if ( fn === list[ i ] ) { + return true; + } + } + } + return false; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory || memory === true ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( stack ) { + if ( firing ) { + if ( !flags.once ) { + stack.push( [ context, args ] ); + } + } else if ( !( flags.once && memory ) ) { + fire( context, args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + + + +var // Static reference to slice + sliceDeferred = [].slice; + +jQuery.extend({ + + Deferred: function( func ) { + var doneList = jQuery.Callbacks( "once memory" ), + failList = jQuery.Callbacks( "once memory" ), + progressList = jQuery.Callbacks( "memory" ), + state = "pending", + lists = { + resolve: doneList, + reject: failList, + notify: progressList + }, + promise = { + done: doneList.add, + fail: failList.add, + progress: progressList.add, + + state: function() { + return state; + }, + + // Deprecated + isResolved: doneList.fired, + isRejected: failList.fired, + + then: function( doneCallbacks, failCallbacks, progressCallbacks ) { + deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); + return this; + }, + always: function() { + deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); + return this; + }, + pipe: function( fnDone, fnFail, fnProgress ) { + return jQuery.Deferred(function( newDefer ) { + jQuery.each( { + done: [ fnDone, "resolve" ], + fail: [ fnFail, "reject" ], + progress: [ fnProgress, "notify" ] + }, function( handler, data ) { + var fn = data[ 0 ], + action = data[ 1 ], + returned; + if ( jQuery.isFunction( fn ) ) { + deferred[ handler ](function() { + returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + }); + } else { + deferred[ handler ]( newDefer[ action ] ); + } + }); + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + if ( obj == null ) { + obj = promise; + } else { + for ( var key in promise ) { + obj[ key ] = promise[ key ]; + } + } + return obj; + } + }, + deferred = promise.promise({}), + key; + + for ( key in lists ) { + deferred[ key ] = lists[ key ].fire; + deferred[ key + "With" ] = lists[ key ].fireWith; + } + + // Handle state + deferred.done( function() { + state = "resolved"; + }, failList.disable, progressList.lock ).fail( function() { + state = "rejected"; + }, doneList.disable, progressList.lock ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( firstParam ) { + var args = sliceDeferred.call( arguments, 0 ), + i = 0, + length = args.length, + pValues = new Array( length ), + count = length, + pCount = length, + deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? + firstParam : + jQuery.Deferred(), + promise = deferred.promise(); + function resolveFunc( i ) { + return function( value ) { + args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + if ( !( --count ) ) { + deferred.resolveWith( deferred, args ); + } + }; + } + function progressFunc( i ) { + return function( value ) { + pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + deferred.notifyWith( promise, pValues ); + }; + } + if ( length > 1 ) { + for ( ; i < length; i++ ) { + if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { + args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); + } else { + --count; + } + } + if ( !count ) { + deferred.resolveWith( deferred, args ); + } + } else if ( deferred !== firstParam ) { + deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); + } + return promise; + } +}); + + + + +jQuery.support = (function() { + + var support, + all, + a, + select, + opt, + input, + fragment, + tds, + events, + eventName, + i, + isSupported, + div = document.createElement( "div" ), + documentElement = document.documentElement; + + // Preliminary tests + div.setAttribute("className", "t"); + div.innerHTML = "
    a"; + + all = div.getElementsByTagName( "*" ); + a = div.getElementsByTagName( "a" )[ 0 ]; + + // Can't get basic test support + if ( !all || !all.length || !a ) { + return {}; + } + + // First batch of supports tests + select = document.createElement( "select" ); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName( "input" )[ 0 ]; + + support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: ( div.firstChild.nodeType === 3 ), + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: ( a.getAttribute("href") === "/a" ), + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.55/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: ( input.value === "on" ), + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // Tests for enctype support on a form(#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true, + pixelMargin: true + }; + + // jQuery.boxModel DEPRECATED in 1.3, use jQuery.support.boxModel instead + jQuery.boxModel = support.boxModel = (document.compatMode === "CSS1Compat"); + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent( "onclick", function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent( "onclick" ); + } + + // Check if a radio maintains its value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute("type", "radio"); + support.radioValue = input.value === "t"; + + input.setAttribute("checked", "checked"); + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for ( i in { + submit: 1, + change: 1, + focusin: 1 + }) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + fragment.removeChild( div ); + + // Null elements to avoid leaks in IE + fragment = select = opt = div = input = null; + + // Run tests that need a body at doc ready + jQuery(function() { + var container, outer, inner, table, td, offsetSupport, + marginDiv, conMarginTop, style, html, positionTopLeftWidthHeight, + paddingMarginBorderVisibility, paddingMarginBorder, + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + conMarginTop = 1; + paddingMarginBorder = "padding:0;margin:0;border:"; + positionTopLeftWidthHeight = "position:absolute;top:0;left:0;width:1px;height:1px;"; + paddingMarginBorderVisibility = paddingMarginBorder + "0;visibility:hidden;"; + style = "style='" + positionTopLeftWidthHeight + paddingMarginBorder + "5px solid #000;"; + html = "
    " + + "" + + "
    "; + + container = document.createElement("div"); + container.style.cssText = paddingMarginBorderVisibility + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + div.innerHTML = "
    t
    "; + tds = div.getElementsByTagName( "td" ); + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE <= 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + if ( window.getComputedStyle ) { + div.innerHTML = ""; + marginDiv = document.createElement( "div" ); + marginDiv.style.width = "0"; + marginDiv.style.marginRight = "0"; + div.style.width = "2px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; + } + + if ( typeof div.style.zoom !== "undefined" ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.innerHTML = ""; + div.style.width = div.style.padding = "1px"; + div.style.border = 0; + div.style.overflow = "hidden"; + div.style.display = "inline"; + div.style.zoom = 1; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = "block"; + div.style.overflow = "visible"; + div.innerHTML = "
    "; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + } + + div.style.cssText = positionTopLeftWidthHeight + paddingMarginBorderVisibility; + div.innerHTML = html; + + outer = div.firstChild; + inner = outer.firstChild; + td = outer.nextSibling.firstChild.firstChild; + + offsetSupport = { + doesNotAddBorder: ( inner.offsetTop !== 5 ), + doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) + }; + + inner.style.position = "fixed"; + inner.style.top = "20px"; + + // safari subtracts parent border width here which is 5px + offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); + inner.style.position = inner.style.top = ""; + + outer.style.overflow = "hidden"; + outer.style.position = "relative"; + + offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); + offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); + + if ( window.getComputedStyle ) { + div.style.marginTop = "1%"; + support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%"; + } + + if ( typeof container.style.zoom !== "undefined" ) { + container.style.zoom = 1; + } + + body.removeChild( container ); + marginDiv = div = container = null; + + jQuery.extend( support, offsetSupport ); + }); + + return support; +})(); + + + + +var rbrace = /^(?:\{.*\}|\[.*\])$/, + rmultiDash = /([A-Z])/g; + +jQuery.extend({ + cache: {}, + + // Please use with caution + uuid: 0, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var privateCache, thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey, + isEvents = name === "events"; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ internalKey ] = id = ++jQuery.uuid; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + privateCache = thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Users should not attempt to inspect the internal events object using jQuery.data, + // it is undocumented and subject to change. But does anyone listen? No. + if ( isEvents && !thisCache[ name ] ) { + return privateCache.events; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + // Reference to internal data cache key + internalKey = jQuery.expando, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + + // See jQuery.data for more information + id = isNode ? elem[ internalKey ] : internalKey; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split( " " ); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject(cache[ id ]) ) { + return; + } + } + + // Browsers that fail expando deletion also refuse to delete expandos on + // the window, but it will allow it on all other JS objects; other browsers + // don't care + // Ensure that `cache` is not a window object #10080 + if ( jQuery.support.deleteExpando || !cache.setInterval ) { + delete cache[ id ]; + } else { + cache[ id ] = null; + } + + // We destroyed the cache and need to eliminate the expando on the node to avoid + // false lookups in the cache for entries that no longer exist + if ( isNode ) { + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( jQuery.support.deleteExpando ) { + delete elem[ internalKey ]; + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + } else { + elem[ internalKey ] = null; + } + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + if ( elem.nodeName ) { + var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; + + if ( match ) { + return !(match === true || elem.getAttribute("classid") !== match); + } + } + + return true; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var parts, part, attr, name, l, + elem = this[0], + i = 0, + data = null; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attr = elem.attributes; + for ( l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + parts = key.split( ".", 2 ); + parts[1] = parts[1] ? "." + parts[1] : ""; + part = parts[1] + "!"; + + return jQuery.access( this, function( value ) { + + if ( value === undefined ) { + data = this.triggerHandler( "getData" + part, [ parts[0] ] ); + + // Try to fetch any internally stored data first + if ( data === undefined && elem ) { + data = jQuery.data( elem, key ); + data = dataAttr( elem, key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + } + + parts[1] = value; + this.each(function() { + var self = jQuery( this ); + + self.triggerHandler( "setData" + part, parts ); + jQuery.data( this, key, value ); + self.triggerHandler( "changeData" + part, parts ); + }); + }, null, value, arguments.length > 1, null, false ); + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + jQuery.isNumeric( data ) ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + for ( var name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + + + + +function handleQueueMarkDefer( elem, type, src ) { + var deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + defer = jQuery._data( elem, deferDataKey ); + if ( defer && + ( src === "queue" || !jQuery._data(elem, queueDataKey) ) && + ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) { + // Give room for hard-coded callbacks to fire first + // and eventually mark/queue something else on the element + setTimeout( function() { + if ( !jQuery._data( elem, queueDataKey ) && + !jQuery._data( elem, markDataKey ) ) { + jQuery.removeData( elem, deferDataKey, true ); + defer.fire(); + } + }, 0 ); + } +} + +jQuery.extend({ + + _mark: function( elem, type ) { + if ( elem ) { + type = ( type || "fx" ) + "mark"; + jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); + } + }, + + _unmark: function( force, elem, type ) { + if ( force !== true ) { + type = elem; + elem = force; + force = false; + } + if ( elem ) { + type = type || "fx"; + var key = type + "mark", + count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 ); + if ( count ) { + jQuery._data( elem, key, count ); + } else { + jQuery.removeData( elem, key, true ); + handleQueueMarkDefer( elem, type, "mark" ); + } + } + }, + + queue: function( elem, type, data ) { + var q; + if ( elem ) { + type = ( type || "fx" ) + "queue"; + q = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !q || jQuery.isArray(data) ) { + q = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + q.push( data ); + } + } + return q || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + fn = queue.shift(), + hooks = {}; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + } + + if ( fn ) { + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + jQuery._data( elem, type + ".run", hooks ); + fn.call( elem, function() { + jQuery.dequeue( elem, type ); + }, hooks ); + } + + if ( !queue.length ) { + jQuery.removeData( elem, type + "queue " + type + ".run", true ); + handleQueueMarkDefer( elem, type, "queue" ); + } + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, object ) { + if ( typeof type !== "string" ) { + object = type; + type = undefined; + } + type = type || "fx"; + var defer = jQuery.Deferred(), + elements = this, + i = elements.length, + count = 1, + deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + tmp; + function resolve() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + } + while( i-- ) { + if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || + ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || + jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && + jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) { + count++; + tmp.add( resolve ); + } + } + resolve(); + return defer.promise( object ); + } +}); + + + + +var rclass = /[\n\t\r]/g, + rspace = /\s+/, + rreturn = /\r/g, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea)?$/i, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute, + nodeHook, boolHook, fixSpecified; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classNames, i, l, elem, + setClass, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call(this, j, this.className) ); + }); + } + + if ( value && typeof value === "string" ) { + classNames = value.split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className && classNames.length === 1 ) { + elem.className = value; + + } else { + setClass = " " + elem.className + " "; + + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classNames, i, l, elem, className, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call(this, j, this.className) ); + }); + } + + if ( (value && typeof value === "string") || value === undefined ) { + classNames = ( value || "" ).split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 && elem.className ) { + if ( value ) { + className = (" " + elem.className + " ").replace( rclass, " " ); + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + className = className.replace(" " + classNames[ c ] + " ", " "); + } + elem.className = jQuery.trim( className ); + + } else { + elem.className = ""; + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.split( rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space seperated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var self = jQuery(this), val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, i, max, option, + index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type === "select-one"; + + // Nothing was selected + if ( index < 0 ) { + return null; + } + + // Loop through all the selected options + i = one ? index : 0; + max = one ? index + 1 : options.length; + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Don't return options that are disabled or in a disabled optgroup + if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && + (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + // Fixes Bug #2551 -- select.val() broken in IE after form.reset() + if ( one && !values.length && options.length ) { + return jQuery( options[ index ] ).val(); + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attrFn: { + val: true, + css: true, + html: true, + text: true, + data: true, + width: true, + height: true, + offset: true + }, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && name in jQuery.attrFn ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, "" + value ); + return value; + } + + } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + ret = elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return ret === null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var propName, attrNames, name, l, isBool, + i = 0; + + if ( value && elem.nodeType === 1 ) { + attrNames = value.toLowerCase().split( rspace ); + l = attrNames.length; + + for ( ; i < l; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = jQuery.propFix[ name ] || name; + isBool = rboolean.test( name ); + + // See #9699 for explanation of this approach (setting first, then removal) + // Do not do this for boolean attributes (see #10870) + if ( !isBool ) { + jQuery.attr( elem, name, "" ); + } + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( isBool && propName in elem ) { + elem[ propName ] = false; + } + } + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return ( elem[ name ] = value ); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) +jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex; + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true, + coords: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? + ret.nodeValue : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.nodeValue = value + "" ); + } + }; + + // Apply the nodeHook to tabindex + jQuery.attrHooks.tabindex.set = nodeHook.set; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// Some attributes require a special call on IE +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = "" + value ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }); +}); + + + + +var rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, + rhoverHack = /(?:^|\s)hover(\.\S+)?\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, + quickParse = function( selector ) { + var quick = rquickIs.exec( selector ); + if ( quick ) { + // 0 1 2 3 + // [ _, tag, id, class ] + quick[1] = ( quick[1] || "" ).toLowerCase(); + quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); + } + return quick; + }, + quickIs = function( elem, m ) { + var attrs = elem.attributes || {}; + return ( + (!m[1] || elem.nodeName.toLowerCase() === m[1]) && + (!m[2] || (attrs.id || {}).value === m[2]) && + (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) + ); + }, + hoverHack = function( events ) { + return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, quick, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + if ( !eventHandle ) { + elemData.handle = eventHandle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + quick: selector && quickParse( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), + t, tns, type, origType, namespaces, origCount, + j, events, special, handle, eventType, handleObj; + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + handle = elemData.handle; + if ( handle ) { + handle.elem = null; + } + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery.removeData( elem, [ "events", "handle" ], true ); + } + }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, + + trigger: function( event, data, elem, onlyHandlers ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var type = event.type || event, + namespaces = [], + cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "!" ) >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; + } + + if ( type.indexOf( "." ) >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + + if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { + // No jQuery handlers for this event type, and it can't have inline handlers + return; + } + + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + new jQuery.Event( type, event ) : + // Just the event type (string) + new jQuery.Event( type ); + + event.type = type; + event.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data != null ? jQuery.makeArray( data ) : []; + data.unshift( event ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + old = null; + for ( ; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old && old === elem.ownerDocument ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event || window.event ); + + var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = [].slice.call( arguments, 0 ), + run_all = !event.exclusive && !event.namespace, + special = jQuery.event.special[ event.type ] || {}, + handlerQueue = [], + i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers that should run if there are delegated events + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !(event.button && event.type === "click") ) { + + // Pregenerate a single jQuery object for reuse with .is() + jqcur = jQuery(this); + jqcur.context = this.ownerDocument || this; + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + + // Don't process events on disabled elements (#6911, #8165) + if ( cur.disabled !== true ) { + selMatch = {}; + matches = []; + jqcur[0] = cur; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = ( + handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel ) + ); + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) + if ( event.metaKey === undefined ) { + event.metaKey = event.ctrlKey; + } + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + ready: { + // Make sure the ready event is setup + setup: jQuery.bindReady + }, + + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +jQuery.event.handle = jQuery.event.dispatch; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + if ( elem.detachEvent ) { + elem.detachEvent( "on" + type, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector, + ret; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !form._submit_attached ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + form._submit_attached = true; + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + jQuery.event.simulate( "change", this, event, true ); + } + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + elem._change_attached = true; + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { // && selector != null + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + var handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( var type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + if ( this[0] ) { + return jQuery.event.trigger( type, data, this[0], true ); + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + guid = fn.guid || jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; + + // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; + while ( i < args.length ) { + args[ i++ ].guid = guid; + } + + return this.click( toggler ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( jQuery.attrFn ) { + jQuery.attrFn[ name ] = true; + } + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); + + + +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){ + +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, + expando = "sizcache" + (Math.random() + '').replace('.', ''), + done = 0, + toString = Object.prototype.toString, + hasDuplicate = false, + baseHasDuplicate = true, + rBackslash = /\\/g, + rReturn = /\r\n/g, + rNonWord = /\W/; + +// Here we check if the JavaScript engine is using some sort of +// optimization where it does not always call our comparision +// function. If that is the case, discard the hasDuplicate value. +// Thus far that includes Google Chrome. +[0, 0].sort(function() { + baseHasDuplicate = false; + return 0; +}); + +var Sizzle = function( selector, context, results, seed ) { + results = results || []; + context = context || document; + + var origContext = context; + + if ( context.nodeType !== 1 && context.nodeType !== 9 ) { + return []; + } + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + var m, set, checkSet, extra, ret, cur, pop, i, + prune = true, + contextXML = Sizzle.isXML( context ), + parts = [], + soFar = selector; + + // Reset the position of the chunker regexp (start from head) + do { + chunker.exec( "" ); + m = chunker.exec( soFar ); + + if ( m ) { + soFar = m[3]; + + parts.push( m[1] ); + + if ( m[2] ) { + extra = m[3]; + break; + } + } + } while ( m ); + + if ( parts.length > 1 && origPOS.exec( selector ) ) { + + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { + set = posProcess( parts[0] + parts[1], context, seed ); + + } else { + set = Expr.relative[ parts[0] ] ? + [ context ] : + Sizzle( parts.shift(), context ); + + while ( parts.length ) { + selector = parts.shift(); + + if ( Expr.relative[ selector ] ) { + selector += parts.shift(); + } + + set = posProcess( selector, set, seed ); + } + } + + } else { + // Take a shortcut and set the context if the root selector is an ID + // (but not if it'll be faster if the inner selector is an ID) + if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { + + ret = Sizzle.find( parts.shift(), context, contextXML ); + context = ret.expr ? + Sizzle.filter( ret.expr, ret.set )[0] : + ret.set[0]; + } + + if ( context ) { + ret = seed ? + { expr: parts.pop(), set: makeArray(seed) } : + Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); + + set = ret.expr ? + Sizzle.filter( ret.expr, ret.set ) : + ret.set; + + if ( parts.length > 0 ) { + checkSet = makeArray( set ); + + } else { + prune = false; + } + + while ( parts.length ) { + cur = parts.pop(); + pop = cur; + + if ( !Expr.relative[ cur ] ) { + cur = ""; + } else { + pop = parts.pop(); + } + + if ( pop == null ) { + pop = context; + } + + Expr.relative[ cur ]( checkSet, pop, contextXML ); + } + + } else { + checkSet = parts = []; + } + } + + if ( !checkSet ) { + checkSet = set; + } + + if ( !checkSet ) { + Sizzle.error( cur || selector ); + } + + if ( toString.call(checkSet) === "[object Array]" ) { + if ( !prune ) { + results.push.apply( results, checkSet ); + + } else if ( context && context.nodeType === 1 ) { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { + results.push( set[i] ); + } + } + + } else { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && checkSet[i].nodeType === 1 ) { + results.push( set[i] ); + } + } + } + + } else { + makeArray( checkSet, results ); + } + + if ( extra ) { + Sizzle( extra, origContext, results, seed ); + Sizzle.uniqueSort( results ); + } + + return results; +}; + +Sizzle.uniqueSort = function( results ) { + if ( sortOrder ) { + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( var i = 1; i < results.length; i++ ) { + if ( results[i] === results[ i - 1 ] ) { + results.splice( i--, 1 ); + } + } + } + } + + return results; +}; + +Sizzle.matches = function( expr, set ) { + return Sizzle( expr, null, null, set ); +}; + +Sizzle.matchesSelector = function( node, expr ) { + return Sizzle( expr, null, null, [node] ).length > 0; +}; + +Sizzle.find = function( expr, context, isXML ) { + var set, i, len, match, type, left; + + if ( !expr ) { + return []; + } + + for ( i = 0, len = Expr.order.length; i < len; i++ ) { + type = Expr.order[i]; + + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { + left = match[1]; + match.splice( 1, 1 ); + + if ( left.substr( left.length - 1 ) !== "\\" ) { + match[1] = (match[1] || "").replace( rBackslash, "" ); + set = Expr.find[ type ]( match, context, isXML ); + + if ( set != null ) { + expr = expr.replace( Expr.match[ type ], "" ); + break; + } + } + } + } + + if ( !set ) { + set = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( "*" ) : + []; + } + + return { set: set, expr: expr }; +}; + +Sizzle.filter = function( expr, set, inplace, not ) { + var match, anyFound, + type, found, item, filter, left, + i, pass, + old = expr, + result = [], + curLoop = set, + isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); + + while ( expr && set.length ) { + for ( type in Expr.filter ) { + if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { + filter = Expr.filter[ type ]; + left = match[1]; + + anyFound = false; + + match.splice(1,1); + + if ( left.substr( left.length - 1 ) === "\\" ) { + continue; + } + + if ( curLoop === result ) { + result = []; + } + + if ( Expr.preFilter[ type ] ) { + match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); + + if ( !match ) { + anyFound = found = true; + + } else if ( match === true ) { + continue; + } + } + + if ( match ) { + for ( i = 0; (item = curLoop[i]) != null; i++ ) { + if ( item ) { + found = filter( item, match, i, curLoop ); + pass = not ^ found; + + if ( inplace && found != null ) { + if ( pass ) { + anyFound = true; + + } else { + curLoop[i] = false; + } + + } else if ( pass ) { + result.push( item ); + anyFound = true; + } + } + } + } + + if ( found !== undefined ) { + if ( !inplace ) { + curLoop = result; + } + + expr = expr.replace( Expr.match[ type ], "" ); + + if ( !anyFound ) { + return []; + } + + break; + } + } + } + + // Improper expression + if ( expr === old ) { + if ( anyFound == null ) { + Sizzle.error( expr ); + + } else { + break; + } + } + + old = expr; + } + + return curLoop; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Utility function for retreiving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +var getText = Sizzle.getText = function( elem ) { + var i, node, + nodeType = elem.nodeType, + ret = ""; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent || innerText for elements + if ( typeof elem.textContent === 'string' ) { + return elem.textContent; + } else if ( typeof elem.innerText === 'string' ) { + // Replace IE's carriage returns + return elem.innerText.replace( rReturn, '' ); + } else { + // Traverse it's children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + } else { + + // If no nodeType, this is expected to be an array + for ( i = 0; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + if ( node.nodeType !== 8 ) { + ret += getText( node ); + } + } + } + return ret; +}; + +var Expr = Sizzle.selectors = { + order: [ "ID", "NAME", "TAG" ], + + match: { + ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, + TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, + CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, + PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ + }, + + leftMatch: {}, + + attrMap: { + "class": "className", + "for": "htmlFor" + }, + + attrHandle: { + href: function( elem ) { + return elem.getAttribute( "href" ); + }, + type: function( elem ) { + return elem.getAttribute( "type" ); + } + }, + + relative: { + "+": function(checkSet, part){ + var isPartStr = typeof part === "string", + isTag = isPartStr && !rNonWord.test( part ), + isPartStrNotTag = isPartStr && !isTag; + + if ( isTag ) { + part = part.toLowerCase(); + } + + for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { + if ( (elem = checkSet[i]) ) { + while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} + + checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? + elem || false : + elem === part; + } + } + + if ( isPartStrNotTag ) { + Sizzle.filter( part, checkSet, true ); + } + }, + + ">": function( checkSet, part ) { + var elem, + isPartStr = typeof part === "string", + i = 0, + l = checkSet.length; + + if ( isPartStr && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + var parent = elem.parentNode; + checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; + } + } + + } else { + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + checkSet[i] = isPartStr ? + elem.parentNode : + elem.parentNode === part; + } + } + + if ( isPartStr ) { + Sizzle.filter( part, checkSet, true ); + } + } + }, + + "": function(checkSet, part, isXML){ + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); + }, + + "~": function( checkSet, part, isXML ) { + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); + } + }, + + find: { + ID: function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }, + + NAME: function( match, context ) { + if ( typeof context.getElementsByName !== "undefined" ) { + var ret = [], + results = context.getElementsByName( match[1] ); + + for ( var i = 0, l = results.length; i < l; i++ ) { + if ( results[i].getAttribute("name") === match[1] ) { + ret.push( results[i] ); + } + } + + return ret.length === 0 ? null : ret; + } + }, + + TAG: function( match, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( match[1] ); + } + } + }, + preFilter: { + CLASS: function( match, curLoop, inplace, result, not, isXML ) { + match = " " + match[1].replace( rBackslash, "" ) + " "; + + if ( isXML ) { + return match; + } + + for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { + if ( elem ) { + if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { + if ( !inplace ) { + result.push( elem ); + } + + } else if ( inplace ) { + curLoop[i] = false; + } + } + } + + return false; + }, + + ID: function( match ) { + return match[1].replace( rBackslash, "" ); + }, + + TAG: function( match, curLoop ) { + return match[1].replace( rBackslash, "" ).toLowerCase(); + }, + + CHILD: function( match ) { + if ( match[1] === "nth" ) { + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + match[2] = match[2].replace(/^\+|\s*/g, ''); + + // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' + var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( + match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); + + // calculate the numbers (first)n+(last) including if they are negative + match[2] = (test[1] + (test[2] || 1)) - 0; + match[3] = test[3] - 0; + } + else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + // TODO: Move to normal caching system + match[0] = done++; + + return match; + }, + + ATTR: function( match, curLoop, inplace, result, not, isXML ) { + var name = match[1] = match[1].replace( rBackslash, "" ); + + if ( !isXML && Expr.attrMap[name] ) { + match[1] = Expr.attrMap[name]; + } + + // Handle if an un-quoted value was used + match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); + + if ( match[2] === "~=" ) { + match[4] = " " + match[4] + " "; + } + + return match; + }, + + PSEUDO: function( match, curLoop, inplace, result, not ) { + if ( match[1] === "not" ) { + // If we're dealing with a complex expression, or a simple one + if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { + match[3] = Sizzle(match[3], null, null, curLoop); + + } else { + var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); + + if ( !inplace ) { + result.push.apply( result, ret ); + } + + return false; + } + + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { + return true; + } + + return match; + }, + + POS: function( match ) { + match.unshift( true ); + + return match; + } + }, + + filters: { + enabled: function( elem ) { + return elem.disabled === false && elem.type !== "hidden"; + }, + + disabled: function( elem ) { + return elem.disabled === true; + }, + + checked: function( elem ) { + return elem.checked === true; + }, + + selected: function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + parent: function( elem ) { + return !!elem.firstChild; + }, + + empty: function( elem ) { + return !elem.firstChild; + }, + + has: function( elem, i, match ) { + return !!Sizzle( match[3], elem ).length; + }, + + header: function( elem ) { + return (/h\d/i).test( elem.nodeName ); + }, + + text: function( elem ) { + var attr = elem.getAttribute( "type" ), type = elem.type; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); + }, + + radio: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; + }, + + checkbox: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; + }, + + file: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; + }, + + password: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; + }, + + submit: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "submit" === elem.type; + }, + + image: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; + }, + + reset: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "reset" === elem.type; + }, + + button: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && "button" === elem.type || name === "button"; + }, + + input: function( elem ) { + return (/input|select|textarea|button/i).test( elem.nodeName ); + }, + + focus: function( elem ) { + return elem === elem.ownerDocument.activeElement; + } + }, + setFilters: { + first: function( elem, i ) { + return i === 0; + }, + + last: function( elem, i, match, array ) { + return i === array.length - 1; + }, + + even: function( elem, i ) { + return i % 2 === 0; + }, + + odd: function( elem, i ) { + return i % 2 === 1; + }, + + lt: function( elem, i, match ) { + return i < match[3] - 0; + }, + + gt: function( elem, i, match ) { + return i > match[3] - 0; + }, + + nth: function( elem, i, match ) { + return match[3] - 0 === i; + }, + + eq: function( elem, i, match ) { + return match[3] - 0 === i; + } + }, + filter: { + PSEUDO: function( elem, match, i, array ) { + var name = match[1], + filter = Expr.filters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + + } else if ( name === "contains" ) { + return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; + + } else if ( name === "not" ) { + var not = match[3]; + + for ( var j = 0, l = not.length; j < l; j++ ) { + if ( not[j] === elem ) { + return false; + } + } + + return true; + + } else { + Sizzle.error( name ); + } + }, + + CHILD: function( elem, match ) { + var first, last, + doneName, parent, cache, + count, diff, + type = match[1], + node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + /* falls through */ + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + + case "nth": + first = match[2]; + last = match[3]; + + if ( first === 1 && last === 0 ) { + return true; + } + + doneName = match[0]; + parent = elem.parentNode; + + if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { + count = 0; + + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + node.nodeIndex = ++count; + } + } + + parent[ expando ] = doneName; + } + + diff = elem.nodeIndex - last; + + if ( first === 0 ) { + return diff === 0; + + } else { + return ( diff % first === 0 && diff / first >= 0 ); + } + } + }, + + ID: function( elem, match ) { + return elem.nodeType === 1 && elem.getAttribute("id") === match; + }, + + TAG: function( elem, match ) { + return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match; + }, + + CLASS: function( elem, match ) { + return (" " + (elem.className || elem.getAttribute("class")) + " ") + .indexOf( match ) > -1; + }, + + ATTR: function( elem, match ) { + var name = match[1], + result = Sizzle.attr ? + Sizzle.attr( elem, name ) : + Expr.attrHandle[ name ] ? + Expr.attrHandle[ name ]( elem ) : + elem[ name ] != null ? + elem[ name ] : + elem.getAttribute( name ), + value = result + "", + type = match[2], + check = match[4]; + + return result == null ? + type === "!=" : + !type && Sizzle.attr ? + result != null : + type === "=" ? + value === check : + type === "*=" ? + value.indexOf(check) >= 0 : + type === "~=" ? + (" " + value + " ").indexOf(check) >= 0 : + !check ? + value && result !== false : + type === "!=" ? + value !== check : + type === "^=" ? + value.indexOf(check) === 0 : + type === "$=" ? + value.substr(value.length - check.length) === check : + type === "|=" ? + value === check || value.substr(0, check.length + 1) === check + "-" : + false; + }, + + POS: function( elem, match, i, array ) { + var name = match[2], + filter = Expr.setFilters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } + } + } +}; + +var origPOS = Expr.match.POS, + fescape = function(all, num){ + return "\\" + (num - 0 + 1); + }; + +for ( var type in Expr.match ) { + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); + Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); +} +// Expose origPOS +// "global" as in regardless of relation to brackets/parens +Expr.match.globalPOS = origPOS; + +var makeArray = function( array, results ) { + array = Array.prototype.slice.call( array, 0 ); + + if ( results ) { + results.push.apply( results, array ); + return results; + } + + return array; +}; + +// Perform a simple check to determine if the browser is capable of +// converting a NodeList to an array using builtin methods. +// Also verifies that the returned array holds DOM nodes +// (which is not the case in the Blackberry browser) +try { + Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; + +// Provide a fallback method if it does not work +} catch( e ) { + makeArray = function( array, results ) { + var i = 0, + ret = results || []; + + if ( toString.call(array) === "[object Array]" ) { + Array.prototype.push.apply( ret, array ); + + } else { + if ( typeof array.length === "number" ) { + for ( var l = array.length; i < l; i++ ) { + ret.push( array[i] ); + } + + } else { + for ( ; array[i]; i++ ) { + ret.push( array[i] ); + } + } + } + + return ret; + }; +} + +var sortOrder, siblingCheck; + +if ( document.documentElement.compareDocumentPosition ) { + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { + return a.compareDocumentPosition ? -1 : 1; + } + + return a.compareDocumentPosition(b) & 4 ? -1 : 1; + }; + +} else { + sortOrder = function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // If the nodes are siblings (or identical) we can do a quick check + if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + + siblingCheck = function( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; + }; +} + +// Check to see if the browser returns elements by name when +// querying by getElementById (and provide a workaround) +(function(){ + // We're going to inject a fake input element with a specified name + var form = document.createElement("div"), + id = "script" + (new Date()).getTime(), + root = document.documentElement; + + form.innerHTML = ""; + + // Inject it into the root element, check its status, and remove it quickly + root.insertBefore( form, root.firstChild ); + + // The workaround has to do additional checks after a getElementById + // Which slows things down for other browsers (hence the branching) + if ( document.getElementById( id ) ) { + Expr.find.ID = function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + + return m ? + m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? + [m] : + undefined : + []; + } + }; + + Expr.filter.ID = function( elem, match ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + + return elem.nodeType === 1 && node && node.nodeValue === match; + }; + } + + root.removeChild( form ); + + // release memory in IE + root = form = null; +})(); + +(function(){ + // Check to see if the browser returns only elements + // when doing getElementsByTagName("*") + + // Create a fake element + var div = document.createElement("div"); + div.appendChild( document.createComment("") ); + + // Make sure no comments are found + if ( div.getElementsByTagName("*").length > 0 ) { + Expr.find.TAG = function( match, context ) { + var results = context.getElementsByTagName( match[1] ); + + // Filter out possible comments + if ( match[1] === "*" ) { + var tmp = []; + + for ( var i = 0; results[i]; i++ ) { + if ( results[i].nodeType === 1 ) { + tmp.push( results[i] ); + } + } + + results = tmp; + } + + return results; + }; + } + + // Check to see if an attribute returns normalized href attributes + div.innerHTML = ""; + + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && + div.firstChild.getAttribute("href") !== "#" ) { + + Expr.attrHandle.href = function( elem ) { + return elem.getAttribute( "href", 2 ); + }; + } + + // release memory in IE + div = null; +})(); + +if ( document.querySelectorAll ) { + (function(){ + var oldSizzle = Sizzle, + div = document.createElement("div"), + id = "__sizzle__"; + + div.innerHTML = "

    "; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function( query, context, extra, seed ) { + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && !Sizzle.isXML(context) ) { + // See if we find a selector to speed up + var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); + + if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { + // Speed-up: Sizzle("TAG") + if ( match[1] ) { + return makeArray( context.getElementsByTagName( query ), extra ); + + // Speed-up: Sizzle(".CLASS") + } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { + return makeArray( context.getElementsByClassName( match[2] ), extra ); + } + } + + if ( context.nodeType === 9 ) { + // Speed-up: Sizzle("body") + // The body element only exists once, optimize finding it + if ( query === "body" && context.body ) { + return makeArray( [ context.body ], extra ); + + // Speed-up: Sizzle("#ID") + } else if ( match && match[3] ) { + var elem = context.getElementById( match[3] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id === match[3] ) { + return makeArray( [ elem ], extra ); + } + + } else { + return makeArray( [], extra ); + } + } + + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(qsaError) {} + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + var oldContext = context, + old = context.getAttribute( "id" ), + nid = old || id, + hasParent = context.parentNode, + relativeHierarchySelector = /^\s*[+~]/.test( query ); + + if ( !old ) { + context.setAttribute( "id", nid ); + } else { + nid = nid.replace( /'/g, "\\$&" ); + } + if ( relativeHierarchySelector && hasParent ) { + context = context.parentNode; + } + + try { + if ( !relativeHierarchySelector || hasParent ) { + return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); + } + + } catch(pseudoError) { + } finally { + if ( !old ) { + oldContext.removeAttribute( "id" ); + } + } + } + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + // release memory in IE + div = null; + })(); +} + +(function(){ + var html = document.documentElement, + matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; + + if ( matches ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9 fails this) + var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), + pseudoWorks = false; + + try { + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( document.documentElement, "[test!='']:sizzle" ); + + } catch( pseudoError ) { + pseudoWorks = true; + } + + Sizzle.matchesSelector = function( node, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); + + if ( !Sizzle.isXML( node ) ) { + try { + if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { + var ret = matches.call( node, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || !disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9, so check for that + node.document && node.document.nodeType !== 11 ) { + return ret; + } + } + } catch(e) {} + } + + return Sizzle(expr, null, null, [node]).length > 0; + }; + } +})(); + +(function(){ + var div = document.createElement("div"); + + div.innerHTML = "
    "; + + // Opera can't find a second classname (in 9.6) + // Also, make sure that getElementsByClassName actually exists + if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { + return; + } + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) { + return; + } + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function( match, context, isXML ) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + // release memory in IE + div = null; +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( elem.nodeName.toLowerCase() === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +if ( document.documentElement.contains ) { + Sizzle.contains = function( a, b ) { + return a !== b && (a.contains ? a.contains(b) : true); + }; + +} else if ( document.documentElement.compareDocumentPosition ) { + Sizzle.contains = function( a, b ) { + return !!(a.compareDocumentPosition(b) & 16); + }; + +} else { + Sizzle.contains = function() { + return false; + }; +} + +Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; + + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +var posProcess = function( selector, context, seed ) { + var match, + tmpSet = [], + later = "", + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet, seed ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +Sizzle.selectors.attrMap = {}; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.filters; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})(); + + +var runtil = /Until$/, + rparentsprev = /^(?:parents|prevUntil|prevAll)/, + // Note: This RegExp should be improved, or likely pulled from Sizzle + rmultiselector = /,/, + isSimple = /^.[^:#\[\.,]*$/, + slice = Array.prototype.slice, + POS = jQuery.expr.match.globalPOS, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var self = this, + i, l; + + if ( typeof selector !== "string" ) { + return jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + var ret = this.pushStack( "", "find", selector ), + length, n, r; + + for ( i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var targets = jQuery( target ); + return this.filter(function() { + for ( var i = 0, l = targets.length; i < l; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && ( + typeof selector === "string" ? + // If this is a positional selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + POS.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var ret = [], i, l, cur = this[0]; + + // Array (deprecated as of jQuery 1.7) + if ( jQuery.isArray( selectors ) ) { + var level = 1; + + while ( cur && cur.ownerDocument && cur !== context ) { + for ( i = 0; i < selectors.length; i++ ) { + + if ( jQuery( cur ).is( selectors[ i ] ) ) { + ret.push({ selector: selectors[ i ], elem: cur, level: level }); + } + } + + cur = cur.parentNode; + level++; + } + + return ret; + } + + // String + var pos = POS.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( i = 0, l = this.length; i < l; i++ ) { + cur = this[i]; + + while ( cur ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + + } else { + cur = cur.parentNode; + if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { + break; + } + } + } + } + + ret = ret.length > 1 ? jQuery.unique( ret ) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + jQuery.unique( all ) ); + }, + + andSelf: function() { + return this.add( this.prevObject ); + } +}); + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return jQuery.nth( elem, 2, "nextSibling" ); + }, + prev: function( elem ) { + return jQuery.nth( elem, 2, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.makeArray( elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, slice.call( arguments ).join(",") ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + nth: function( cur, result, dir, elem ) { + result = result || 1; + var num = 0; + + for ( ; cur; cur = cur[dir] ) { + if ( cur.nodeType === 1 && ++num === result ) { + break; + } + } + + return cur; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem, i ) { + return ( elem === qualifier ) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem, i ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; + }); +} + + + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, + rtagName = /<([\w:]+)/, + rtbody = /]", "i"), + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /\/(java|ecma)script/i, + rcleanScript = /^\s*", "" ], + legend: [ 1, "
    ", "
    " ], + thead: [ 1, "", "
    " ], + tr: [ 2, "", "
    " ], + td: [ 3, "", "
    " ], + col: [ 2, "", "
    " ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE can't serialize and +
    +
    +
    +
    +
    + + + it('should auto compile', function() { + expect(element('div[compile]').text()).toBe('Hello Angular'); + input('html').enter('{{name}}!'); + expect(element('div[compile]').text()).toBe('Angular!'); + }); + + + + * + * + * @param {string|DOMElement} element Element or HTML string to compile into a template function. + * @param {function(angular.Scope[, cloneAttachFn]} transclude function available to directives. + * @param {number} maxPriority only apply directives lower then given priority (Only effects the + * root element(s), not their children) + * @returns {function(scope[, cloneAttachFn])} a link function which is used to bind template + * (a DOM element/tree) to a scope. Where: + * + * * `scope` - A {@link ng.$rootScope.Scope Scope} to bind to. + * * `cloneAttachFn` - If `cloneAttachFn` is provided, then the link function will clone the + * `template` and call the `cloneAttachFn` function allowing the caller to attach the + * cloned elements to the DOM document at the appropriate place. The `cloneAttachFn` is + * called as:
    `cloneAttachFn(clonedElement, scope)` where: + * + * * `clonedElement` - is a clone of the original `element` passed into the compiler. + * * `scope` - is the current scope with which the linking function is working with. + * + * Calling the linking function returns the element of the template. It is either the original element + * passed in, or the clone of the element if the `cloneAttachFn` is provided. + * + * After linking the view is not updated until after a call to $digest which typically is done by + * Angular automatically. + * + * If you need access to the bound view, there are two ways to do it: + * + * - If you are not asking the linking function to clone the template, create the DOM element(s) + * before you send them to the compiler and keep this reference around. + *
    + *     var element = $compile('

    {{total}}

    ')(scope); + *
    + * + * - if on the other hand, you need the element to be cloned, the view reference from the original + * example would not point to the clone, but rather to the original template that was cloned. In + * this case, you can access the clone via the cloneAttachFn: + *
    + *     var templateHTML = angular.element('

    {{total}}

    '), + * scope = ....; + * + * var clonedElement = $compile(templateHTML)(scope, function(clonedElement, scope) { + * //attach the clone to DOM document at the right place + * }); + * + * //now we have reference to the cloned DOM via `clone` + *
    + * + * + * For information on how the compiler works, see the + * {@link guide/compiler Angular HTML Compiler} section of the Developer Guide. + */ + + +/** + * @ngdoc service + * @name ng.$compileProvider + * @function + * + * @description + */ +$CompileProvider.$inject = ['$provide']; +function $CompileProvider($provide) { + var hasDirectives = {}, + Suffix = 'Directive', + COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/, + CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/, + MULTI_ROOT_TEMPLATE_ERROR = 'Template must have exactly one root element. was: '; + + + /** + * @ngdoc function + * @name ng.$compileProvider#directive + * @methodOf ng.$compileProvider + * @function + * + * @description + * Register a new directives with the compiler. + * + * @param {string} name Name of the directive in camel-case. (ie ngBind which will match as + * ng-bind). + * @param {function} directiveFactory An injectable directive factroy function. See {@link guide/directive} for more + * info. + * @returns {ng.$compileProvider} Self for chaining. + */ + this.directive = function registerDirective(name, directiveFactory) { + if (isString(name)) { + assertArg(directiveFactory, 'directive'); + if (!hasDirectives.hasOwnProperty(name)) { + hasDirectives[name] = []; + $provide.factory(name + Suffix, ['$injector', '$exceptionHandler', + function($injector, $exceptionHandler) { + var directives = []; + forEach(hasDirectives[name], function(directiveFactory) { + try { + var directive = $injector.invoke(directiveFactory); + if (isFunction(directive)) { + directive = { compile: valueFn(directive) }; + } else if (!directive.compile && directive.link) { + directive.compile = valueFn(directive.link); + } + directive.priority = directive.priority || 0; + directive.name = directive.name || name; + directive.require = directive.require || (directive.controller && directive.name); + directive.restrict = directive.restrict || 'A'; + directives.push(directive); + } catch (e) { + $exceptionHandler(e); + } + }); + return directives; + }]); + } + hasDirectives[name].push(directiveFactory); + } else { + forEach(name, reverseParams(registerDirective)); + } + return this; + }; + + + this.$get = [ + '$injector', '$interpolate', '$exceptionHandler', '$http', '$templateCache', '$parse', + '$controller', '$rootScope', + function($injector, $interpolate, $exceptionHandler, $http, $templateCache, $parse, + $controller, $rootScope) { + + var Attributes = function(element, attr) { + this.$$element = element; + this.$attr = attr || {}; + }; + + Attributes.prototype = { + $normalize: directiveNormalize, + + + /** + * Set a normalized attribute on the element in a way such that all directives + * can share the attribute. This function properly handles boolean attributes. + * @param {string} key Normalized key. (ie ngAttribute) + * @param {string|boolean} value The value to set. If `null` attribute will be deleted. + * @param {boolean=} writeAttr If false, does not write the value to DOM element attribute. + * Defaults to true. + * @param {string=} attrName Optional none normalized name. Defaults to key. + */ + $set: function(key, value, writeAttr, attrName) { + var booleanKey = getBooleanAttrName(this.$$element[0], key), + $$observers = this.$$observers; + + if (booleanKey) { + this.$$element.prop(key, value); + attrName = booleanKey; + } + + this[key] = value; + + // translate normalized key to actual key + if (attrName) { + this.$attr[key] = attrName; + } else { + attrName = this.$attr[key]; + if (!attrName) { + this.$attr[key] = attrName = snake_case(key, '-'); + } + } + + if (writeAttr !== false) { + if (value === null || value === undefined) { + this.$$element.removeAttr(attrName); + } else { + this.$$element.attr(attrName, value); + } + } + + // fire observers + $$observers && forEach($$observers[key], function(fn) { + try { + fn(value); + } catch (e) { + $exceptionHandler(e); + } + }); + }, + + + /** + * Observe an interpolated attribute. + * The observer will never be called, if given attribute is not interpolated. + * + * @param {string} key Normalized key. (ie ngAttribute) . + * @param {function(*)} fn Function that will be called whenever the attribute value changes. + * @returns {function(*)} the `fn` Function passed in. + */ + $observe: function(key, fn) { + var attrs = this, + $$observers = (attrs.$$observers || (attrs.$$observers = {})), + listeners = ($$observers[key] || ($$observers[key] = [])); + + listeners.push(fn); + $rootScope.$evalAsync(function() { + if (!listeners.$$inter) { + // no one registered attribute interpolation function, so lets call it manually + fn(attrs[key]); + } + }); + return fn; + } + }; + + var startSymbol = $interpolate.startSymbol(), + endSymbol = $interpolate.endSymbol(), + denormalizeTemplate = (startSymbol == '{{' || endSymbol == '}}') + ? identity + : function denormalizeTemplate(template) { + return template.replace(/\{\{/g, startSymbol).replace(/}}/g, endSymbol); + }; + + + return compile; + + //================================ + + function compile($compileNode, transcludeFn, maxPriority) { + if (!($compileNode instanceof jqLite)) { + // jquery always rewraps, where as we need to preserve the original selector so that we can modify it. + $compileNode = jqLite($compileNode); + } + // We can not compile top level text elements since text nodes can be merged and we will + // not be able to attach scope data to them, so we will wrap them in + forEach($compileNode, function(node, index){ + if (node.nodeType == 3 /* text node */) { + $compileNode[index] = jqLite(node).wrap('').parent()[0]; + } + }); + var compositeLinkFn = compileNodes($compileNode, transcludeFn, $compileNode, maxPriority); + return function(scope, cloneConnectFn){ + assertArg(scope, 'scope'); + // important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart + // and sometimes changes the structure of the DOM. + var $linkNode = cloneConnectFn + ? JQLitePrototype.clone.call($compileNode) // IMPORTANT!!! + : $compileNode; + $linkNode.data('$scope', scope); + safeAddClass($linkNode, 'ng-scope'); + if (cloneConnectFn) cloneConnectFn($linkNode, scope); + if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode); + return $linkNode; + }; + } + + function wrongMode(localName, mode) { + throw Error("Unsupported '" + mode + "' for '" + localName + "'."); + } + + function safeAddClass($element, className) { + try { + $element.addClass(className); + } catch(e) { + // ignore, since it means that we are trying to set class on + // SVG element, where class name is read-only. + } + } + + /** + * Compile function matches each node in nodeList against the directives. Once all directives + * for a particular node are collected their compile functions are executed. The compile + * functions return values - the linking functions - are combined into a composite linking + * function, which is the a linking function for the node. + * + * @param {NodeList} nodeList an array of nodes to compile + * @param {function(angular.Scope[, cloneAttachFn]} transcludeFn A linking function, where the + * scope argument is auto-generated to the new child of the transcluded parent scope. + * @param {DOMElement=} $rootElement If the nodeList is the root of the compilation tree then the + * rootElement must be set the jqLite collection of the compile root. This is + * needed so that the jqLite collection items can be replaced with widgets. + * @param {number=} max directive priority + * @returns {?function} A composite linking function of all of the matched directives or null. + */ + function compileNodes(nodeList, transcludeFn, $rootElement, maxPriority) { + var linkFns = [], + nodeLinkFn, childLinkFn, directives, attrs, linkFnFound; + + for(var i = 0; i < nodeList.length; i++) { + attrs = new Attributes(); + + // we must always refer to nodeList[i] since the nodes can be replaced underneath us. + directives = collectDirectives(nodeList[i], [], attrs, maxPriority); + + nodeLinkFn = (directives.length) + ? applyDirectivesToNode(directives, nodeList[i], attrs, transcludeFn, $rootElement) + : null; + + childLinkFn = (nodeLinkFn && nodeLinkFn.terminal) + ? null + : compileNodes(nodeList[i].childNodes, + nodeLinkFn ? nodeLinkFn.transclude : transcludeFn); + + linkFns.push(nodeLinkFn); + linkFns.push(childLinkFn); + linkFnFound = (linkFnFound || nodeLinkFn || childLinkFn); + } + + // return a linking function if we have found anything, null otherwise + return linkFnFound ? compositeLinkFn : null; + + function compositeLinkFn(scope, nodeList, $rootElement, boundTranscludeFn) { + var nodeLinkFn, childLinkFn, node, childScope, childTranscludeFn; + + for(var i = 0, n = 0, ii = linkFns.length; i < ii; n++) { + node = nodeList[n]; + nodeLinkFn = linkFns[i++]; + childLinkFn = linkFns[i++]; + + if (nodeLinkFn) { + if (nodeLinkFn.scope) { + childScope = scope.$new(isObject(nodeLinkFn.scope)); + jqLite(node).data('$scope', childScope); + } else { + childScope = scope; + } + childTranscludeFn = nodeLinkFn.transclude; + if (childTranscludeFn || (!boundTranscludeFn && transcludeFn)) { + nodeLinkFn(childLinkFn, childScope, node, $rootElement, + (function(transcludeFn) { + return function(cloneFn) { + var transcludeScope = scope.$new(); + + return transcludeFn(transcludeScope, cloneFn). + bind('$destroy', bind(transcludeScope, transcludeScope.$destroy)); + }; + })(childTranscludeFn || transcludeFn) + ); + } else { + nodeLinkFn(childLinkFn, childScope, node, undefined, boundTranscludeFn); + } + } else if (childLinkFn) { + childLinkFn(scope, node.childNodes, undefined, boundTranscludeFn); + } + } + } + } + + + /** + * Looks for directives on the given node ands them to the directive collection which is sorted. + * + * @param node node to search + * @param directives an array to which the directives are added to. This array is sorted before + * the function returns. + * @param attrs the shared attrs object which is used to populate the normalized attributes. + * @param {number=} max directive priority + */ + function collectDirectives(node, directives, attrs, maxPriority) { + var nodeType = node.nodeType, + attrsMap = attrs.$attr, + match, + className; + + switch(nodeType) { + case 1: /* Element */ + // use the node name: + addDirective(directives, + directiveNormalize(nodeName_(node).toLowerCase()), 'E', maxPriority); + + // iterate over the attributes + for (var attr, name, nName, value, nAttrs = node.attributes, + j = 0, jj = nAttrs && nAttrs.length; j < jj; j++) { + attr = nAttrs[j]; + if (attr.specified) { + name = attr.name; + nName = directiveNormalize(name.toLowerCase()); + attrsMap[nName] = name; + attrs[nName] = value = trim((msie && name == 'href') + ? decodeURIComponent(node.getAttribute(name, 2)) + : attr.value); + if (getBooleanAttrName(node, nName)) { + attrs[nName] = true; // presence means true + } + addAttrInterpolateDirective(node, directives, value, nName); + addDirective(directives, nName, 'A', maxPriority); + } + } + + // use class as directive + className = node.className; + if (isString(className)) { + while (match = CLASS_DIRECTIVE_REGEXP.exec(className)) { + nName = directiveNormalize(match[2]); + if (addDirective(directives, nName, 'C', maxPriority)) { + attrs[nName] = trim(match[3]); + } + className = className.substr(match.index + match[0].length); + } + } + break; + case 3: /* Text Node */ + addTextInterpolateDirective(directives, node.nodeValue); + break; + case 8: /* Comment */ + try { + match = COMMENT_DIRECTIVE_REGEXP.exec(node.nodeValue); + if (match) { + nName = directiveNormalize(match[1]); + if (addDirective(directives, nName, 'M', maxPriority)) { + attrs[nName] = trim(match[2]); + } + } + } catch (e) { + // turns out that under some circumstances IE9 throws errors when one attempts to read comment's node value. + // Just ignore it and continue. (Can't seem to reproduce in test case.) + } + break; + } + + directives.sort(byPriority); + return directives; + } + + + /** + * Once the directives have been collected their compile functions is executed. This method + * is responsible for inlining directive templates as well as terminating the application + * of the directives if the terminal directive has been reached.. + * + * @param {Array} directives Array of collected directives to execute their compile function. + * this needs to be pre-sorted by priority order. + * @param {Node} compileNode The raw DOM node to apply the compile functions to + * @param {Object} templateAttrs The shared attribute function + * @param {function(angular.Scope[, cloneAttachFn]} transcludeFn A linking function, where the + * scope argument is auto-generated to the new child of the transcluded parent scope. + * @param {DOMElement} $rootElement If we are working on the root of the compile tree then this + * argument has the root jqLite array so that we can replace widgets on it. + * @returns linkFn + */ + function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn, $rootElement) { + var terminalPriority = -Number.MAX_VALUE, + preLinkFns = [], + postLinkFns = [], + newScopeDirective = null, + newIsolatedScopeDirective = null, + templateDirective = null, + $compileNode = templateAttrs.$$element = jqLite(compileNode), + directive, + directiveName, + $template, + transcludeDirective, + childTranscludeFn = transcludeFn, + controllerDirectives, + linkFn, + directiveValue; + + // executes all directives on the current element + for(var i = 0, ii = directives.length; i < ii; i++) { + directive = directives[i]; + $template = undefined; + + if (terminalPriority > directive.priority) { + break; // prevent further processing of directives + } + + if (directiveValue = directive.scope) { + assertNoDuplicate('isolated scope', newIsolatedScopeDirective, directive, $compileNode); + if (isObject(directiveValue)) { + safeAddClass($compileNode, 'ng-isolate-scope'); + newIsolatedScopeDirective = directive; + } + safeAddClass($compileNode, 'ng-scope'); + newScopeDirective = newScopeDirective || directive; + } + + directiveName = directive.name; + + if (directiveValue = directive.controller) { + controllerDirectives = controllerDirectives || {}; + assertNoDuplicate("'" + directiveName + "' controller", + controllerDirectives[directiveName], directive, $compileNode); + controllerDirectives[directiveName] = directive; + } + + if (directiveValue = directive.transclude) { + assertNoDuplicate('transclusion', transcludeDirective, directive, $compileNode); + transcludeDirective = directive; + terminalPriority = directive.priority; + if (directiveValue == 'element') { + $template = jqLite(compileNode); + $compileNode = templateAttrs.$$element = + jqLite(''); + compileNode = $compileNode[0]; + replaceWith($rootElement, jqLite($template[0]), compileNode); + childTranscludeFn = compile($template, transcludeFn, terminalPriority); + } else { + $template = jqLite(JQLiteClone(compileNode)).contents(); + $compileNode.html(''); // clear contents + childTranscludeFn = compile($template, transcludeFn); + } + } + + if ((directiveValue = directive.template)) { + assertNoDuplicate('template', templateDirective, directive, $compileNode); + templateDirective = directive; + directiveValue = denormalizeTemplate(directiveValue); + + if (directive.replace) { + $template = jqLite('
    ' + + trim(directiveValue) + + '
    ').contents(); + compileNode = $template[0]; + + if ($template.length != 1 || compileNode.nodeType !== 1) { + throw new Error(MULTI_ROOT_TEMPLATE_ERROR + directiveValue); + } + + replaceWith($rootElement, $compileNode, compileNode); + + var newTemplateAttrs = {$attr: {}}; + + // combine directives from the original node and from the template: + // - take the array of directives for this element + // - split it into two parts, those that were already applied and those that weren't + // - collect directives from the template, add them to the second group and sort them + // - append the second group with new directives to the first group + directives = directives.concat( + collectDirectives( + compileNode, + directives.splice(i + 1, directives.length - (i + 1)), + newTemplateAttrs + ) + ); + mergeTemplateAttributes(templateAttrs, newTemplateAttrs); + + ii = directives.length; + } else { + $compileNode.html(directiveValue); + } + } + + if (directive.templateUrl) { + assertNoDuplicate('template', templateDirective, directive, $compileNode); + templateDirective = directive; + nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), + nodeLinkFn, $compileNode, templateAttrs, $rootElement, directive.replace, + childTranscludeFn); + ii = directives.length; + } else if (directive.compile) { + try { + linkFn = directive.compile($compileNode, templateAttrs, childTranscludeFn); + if (isFunction(linkFn)) { + addLinkFns(null, linkFn); + } else if (linkFn) { + addLinkFns(linkFn.pre, linkFn.post); + } + } catch (e) { + $exceptionHandler(e, startingTag($compileNode)); + } + } + + if (directive.terminal) { + nodeLinkFn.terminal = true; + terminalPriority = Math.max(terminalPriority, directive.priority); + } + + } + + nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope; + nodeLinkFn.transclude = transcludeDirective && childTranscludeFn; + + // might be normal or delayed nodeLinkFn depending on if templateUrl is present + return nodeLinkFn; + + //////////////////// + + function addLinkFns(pre, post) { + if (pre) { + pre.require = directive.require; + preLinkFns.push(pre); + } + if (post) { + post.require = directive.require; + postLinkFns.push(post); + } + } + + + function getControllers(require, $element) { + var value, retrievalMethod = 'data', optional = false; + if (isString(require)) { + while((value = require.charAt(0)) == '^' || value == '?') { + require = require.substr(1); + if (value == '^') { + retrievalMethod = 'inheritedData'; + } + optional = optional || value == '?'; + } + value = $element[retrievalMethod]('$' + require + 'Controller'); + if (!value && !optional) { + throw Error("No controller: " + require); + } + return value; + } else if (isArray(require)) { + value = []; + forEach(require, function(require) { + value.push(getControllers(require, $element)); + }); + } + return value; + } + + + function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) { + var attrs, $element, i, ii, linkFn, controller; + + if (compileNode === linkNode) { + attrs = templateAttrs; + } else { + attrs = shallowCopy(templateAttrs, new Attributes(jqLite(linkNode), templateAttrs.$attr)); + } + $element = attrs.$$element; + + if (newScopeDirective && isObject(newScopeDirective.scope)) { + var LOCAL_REGEXP = /^\s*([@=&])\s*(\w*)\s*$/; + + var parentScope = scope.$parent || scope; + + forEach(newScopeDirective.scope, function(definiton, scopeName) { + var match = definiton.match(LOCAL_REGEXP) || [], + attrName = match[2]|| scopeName, + mode = match[1], // @, =, or & + lastValue, + parentGet, parentSet; + + switch (mode) { + + case '@': { + attrs.$observe(attrName, function(value) { + scope[scopeName] = value; + }); + attrs.$$observers[attrName].$$scope = parentScope; + break; + } + + case '=': { + parentGet = $parse(attrs[attrName]); + parentSet = parentGet.assign || function() { + // reset the change, or we will throw this exception on every $digest + lastValue = scope[scopeName] = parentGet(parentScope); + throw Error(NON_ASSIGNABLE_MODEL_EXPRESSION + attrs[attrName] + + ' (directive: ' + newScopeDirective.name + ')'); + }; + lastValue = scope[scopeName] = parentGet(parentScope); + scope.$watch(function() { + var parentValue = parentGet(parentScope); + + if (parentValue !== scope[scopeName]) { + // we are out of sync and need to copy + if (parentValue !== lastValue) { + // parent changed and it has precedence + lastValue = scope[scopeName] = parentValue; + } else { + // if the parent can be assigned then do so + parentSet(parentScope, lastValue = scope[scopeName]); + } + } + return parentValue; + }); + break; + } + + case '&': { + parentGet = $parse(attrs[attrName]); + scope[scopeName] = function(locals) { + return parentGet(parentScope, locals); + } + break; + } + + default: { + throw Error('Invalid isolate scope definition for directive ' + + newScopeDirective.name + ': ' + definiton); + } + } + }); + } + + if (controllerDirectives) { + forEach(controllerDirectives, function(directive) { + var locals = { + $scope: scope, + $element: $element, + $attrs: attrs, + $transclude: boundTranscludeFn + }; + + controller = directive.controller; + if (controller == '@') { + controller = attrs[directive.name]; + } + + $element.data( + '$' + directive.name + 'Controller', + $controller(controller, locals)); + }); + } + + // PRELINKING + for(i = 0, ii = preLinkFns.length; i < ii; i++) { + try { + linkFn = preLinkFns[i]; + linkFn(scope, $element, attrs, + linkFn.require && getControllers(linkFn.require, $element)); + } catch (e) { + $exceptionHandler(e, startingTag($element)); + } + } + + // RECURSION + childLinkFn && childLinkFn(scope, linkNode.childNodes, undefined, boundTranscludeFn); + + // POSTLINKING + for(i = 0, ii = postLinkFns.length; i < ii; i++) { + try { + linkFn = postLinkFns[i]; + linkFn(scope, $element, attrs, + linkFn.require && getControllers(linkFn.require, $element)); + } catch (e) { + $exceptionHandler(e, startingTag($element)); + } + } + } + } + + + /** + * looks up the directive and decorates it with exception handling and proper parameters. We + * call this the boundDirective. + * + * @param {string} name name of the directive to look up. + * @param {string} location The directive must be found in specific format. + * String containing any of theses characters: + * + * * `E`: element name + * * `A': attribute + * * `C`: class + * * `M`: comment + * @returns true if directive was added. + */ + function addDirective(tDirectives, name, location, maxPriority) { + var match = false; + if (hasDirectives.hasOwnProperty(name)) { + for(var directive, directives = $injector.get(name + Suffix), + i = 0, ii = directives.length; i directive.priority) && + directive.restrict.indexOf(location) != -1) { + tDirectives.push(directive); + match = true; + } + } catch(e) { $exceptionHandler(e); } + } + } + return match; + } + + + /** + * When the element is replaced with HTML template then the new attributes + * on the template need to be merged with the existing attributes in the DOM. + * The desired effect is to have both of the attributes present. + * + * @param {object} dst destination attributes (original DOM) + * @param {object} src source attributes (from the directive template) + */ + function mergeTemplateAttributes(dst, src) { + var srcAttr = src.$attr, + dstAttr = dst.$attr, + $element = dst.$$element; + + // reapply the old attributes to the new element + forEach(dst, function(value, key) { + if (key.charAt(0) != '$') { + if (src[key]) { + value += (key === 'style' ? ';' : ' ') + src[key]; + } + dst.$set(key, value, true, srcAttr[key]); + } + }); + + // copy the new attributes on the old attrs object + forEach(src, function(value, key) { + if (key == 'class') { + safeAddClass($element, value); + dst['class'] = (dst['class'] ? dst['class'] + ' ' : '') + value; + } else if (key == 'style') { + $element.attr('style', $element.attr('style') + ';' + value); + } else if (key.charAt(0) != '$' && !dst.hasOwnProperty(key)) { + dst[key] = value; + dstAttr[key] = srcAttr[key]; + } + }); + } + + + function compileTemplateUrl(directives, beforeTemplateNodeLinkFn, $compileNode, tAttrs, + $rootElement, replace, childTranscludeFn) { + var linkQueue = [], + afterTemplateNodeLinkFn, + afterTemplateChildLinkFn, + beforeTemplateCompileNode = $compileNode[0], + origAsyncDirective = directives.shift(), + // The fact that we have to copy and patch the directive seems wrong! + derivedSyncDirective = extend({}, origAsyncDirective, { + controller: null, templateUrl: null, transclude: null + }); + + $compileNode.html(''); + + $http.get(origAsyncDirective.templateUrl, {cache: $templateCache}). + success(function(content) { + var compileNode, tempTemplateAttrs, $template; + + content = denormalizeTemplate(content); + + if (replace) { + $template = jqLite('
    ' + trim(content) + '
    ').contents(); + compileNode = $template[0]; + + if ($template.length != 1 || compileNode.nodeType !== 1) { + throw new Error(MULTI_ROOT_TEMPLATE_ERROR + content); + } + + tempTemplateAttrs = {$attr: {}}; + replaceWith($rootElement, $compileNode, compileNode); + collectDirectives(compileNode, directives, tempTemplateAttrs); + mergeTemplateAttributes(tAttrs, tempTemplateAttrs); + } else { + compileNode = beforeTemplateCompileNode; + $compileNode.html(content); + } + + directives.unshift(derivedSyncDirective); + afterTemplateNodeLinkFn = applyDirectivesToNode(directives, $compileNode, tAttrs, childTranscludeFn); + afterTemplateChildLinkFn = compileNodes($compileNode.contents(), childTranscludeFn); + + + while(linkQueue.length) { + var controller = linkQueue.pop(), + linkRootElement = linkQueue.pop(), + beforeTemplateLinkNode = linkQueue.pop(), + scope = linkQueue.pop(), + linkNode = compileNode; + + if (beforeTemplateLinkNode !== beforeTemplateCompileNode) { + // it was cloned therefore we have to clone as well. + linkNode = JQLiteClone(compileNode); + replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode); + } + + afterTemplateNodeLinkFn(function() { + beforeTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, linkNode, $rootElement, controller); + }, scope, linkNode, $rootElement, controller); + } + linkQueue = null; + }). + error(function(response, code, headers, config) { + throw Error('Failed to load template: ' + config.url); + }); + + return function delayedNodeLinkFn(ignoreChildLinkFn, scope, node, rootElement, controller) { + if (linkQueue) { + linkQueue.push(scope); + linkQueue.push(node); + linkQueue.push(rootElement); + linkQueue.push(controller); + } else { + afterTemplateNodeLinkFn(function() { + beforeTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement, controller); + }, scope, node, rootElement, controller); + } + }; + } + + + /** + * Sorting function for bound directives. + */ + function byPriority(a, b) { + return b.priority - a.priority; + } + + + function assertNoDuplicate(what, previousDirective, directive, element) { + if (previousDirective) { + throw Error('Multiple directives [' + previousDirective.name + ', ' + + directive.name + '] asking for ' + what + ' on: ' + startingTag(element)); + } + } + + + function addTextInterpolateDirective(directives, text) { + var interpolateFn = $interpolate(text, true); + if (interpolateFn) { + directives.push({ + priority: 0, + compile: valueFn(function(scope, node) { + var parent = node.parent(), + bindings = parent.data('$binding') || []; + bindings.push(interpolateFn); + safeAddClass(parent.data('$binding', bindings), 'ng-binding'); + scope.$watch(interpolateFn, function(value) { + node[0].nodeValue = value; + }); + }) + }); + } + } + + + function addAttrInterpolateDirective(node, directives, value, name) { + var interpolateFn = $interpolate(value, true); + + + // no interpolation found -> ignore + if (!interpolateFn) return; + + directives.push({ + priority: 100, + compile: valueFn(function(scope, element, attr) { + var $$observers = (attr.$$observers || (attr.$$observers = {})); + + if (name === 'class') { + // we need to interpolate classes again, in the case the element was replaced + // and therefore the two class attrs got merged - we want to interpolate the result + interpolateFn = $interpolate(attr[name], true); + } + + attr[name] = undefined; + ($$observers[name] || ($$observers[name] = [])).$$inter = true; + (attr.$$observers && attr.$$observers[name].$$scope || scope). + $watch(interpolateFn, function(value) { + attr.$set(name, value); + }); + }) + }); + } + + + /** + * This is a special jqLite.replaceWith, which can replace items which + * have no parents, provided that the containing jqLite collection is provided. + * + * @param {JqLite=} $rootElement The root of the compile tree. Used so that we can replace nodes + * in the root of the tree. + * @param {JqLite} $element The jqLite element which we are going to replace. We keep the shell, + * but replace its DOM node reference. + * @param {Node} newNode The new DOM node. + */ + function replaceWith($rootElement, $element, newNode) { + var oldNode = $element[0], + parent = oldNode.parentNode, + i, ii; + + if ($rootElement) { + for(i = 0, ii = $rootElement.length; i < ii; i++) { + if ($rootElement[i] == oldNode) { + $rootElement[i] = newNode; + break; + } + } + } + + if (parent) { + parent.replaceChild(newNode, oldNode); + } + + newNode[jqLite.expando] = oldNode[jqLite.expando]; + $element[0] = newNode; + } + }]; +} + +var PREFIX_REGEXP = /^(x[\:\-_]|data[\:\-_])/i; +/** + * Converts all accepted directives format into proper directive name. + * All of these will become 'myDirective': + * my:DiRective + * my-directive + * x-my-directive + * data-my:directive + * + * Also there is special case for Moz prefix starting with upper case letter. + * @param name Name to normalize + */ +function directiveNormalize(name) { + return camelCase(name.replace(PREFIX_REGEXP, '')); +} + +/** + * @ngdoc object + * @name ng.$compile.directive.Attributes + * @description + * + * A shared object between directive compile / linking functions which contains normalized DOM element + * attributes. The the values reflect current binding state `{{ }}`. The normalization is needed + * since all of these are treated as equivalent in Angular: + * + * + */ + +/** + * @ngdoc property + * @name ng.$compile.directive.Attributes#$attr + * @propertyOf ng.$compile.directive.Attributes + * @returns {object} A map of DOM element attribute names to the normalized name. This is + * needed to do reverse lookup from normalized name back to actual name. + */ + + +/** + * @ngdoc function + * @name ng.$compile.directive.Attributes#$set + * @methodOf ng.$compile.directive.Attributes + * @function + * + * @description + * Set DOM element attribute value. + * + * + * @param {string} name Normalized element attribute name of the property to modify. The name is + * revers translated using the {@link ng.$compile.directive.Attributes#$attr $attr} + * property to the original name. + * @param {string} value Value to set the attribute to. + */ + + + +/** + * Closure compiler type information + */ + +function nodesetLinkingFn( + /* angular.Scope */ scope, + /* NodeList */ nodeList, + /* Element */ rootElement, + /* function(Function) */ boundTranscludeFn +){} + +function directiveLinkingFn( + /* nodesetLinkingFn */ nodesetLinkingFn, + /* angular.Scope */ scope, + /* Node */ node, + /* Element */ rootElement, + /* function(Function) */ boundTranscludeFn +){} + +/** + * @ngdoc object + * @name ng.$controllerProvider + * @description + * The {@link ng.$controller $controller service} is used by Angular to create new + * controllers. + * + * This provider allows controller registration via the + * {@link ng.$controllerProvider#register register} method. + */ +function $ControllerProvider() { + var controllers = {}; + + + /** + * @ngdoc function + * @name ng.$controllerProvider#register + * @methodOf ng.$controllerProvider + * @param {string} name Controller name + * @param {Function|Array} constructor Controller constructor fn (optionally decorated with DI + * annotations in the array notation). + */ + this.register = function(name, constructor) { + if (isObject(name)) { + extend(controllers, name) + } else { + controllers[name] = constructor; + } + }; + + + this.$get = ['$injector', '$window', function($injector, $window) { + + /** + * @ngdoc function + * @name ng.$controller + * @requires $injector + * + * @param {Function|string} constructor If called with a function then it's considered to be the + * controller constructor function. Otherwise it's considered to be a string which is used + * to retrieve the controller constructor using the following steps: + * + * * check if a controller with given name is registered via `$controllerProvider` + * * check if evaluating the string on the current scope returns a constructor + * * check `window[constructor]` on the global `window` object + * + * @param {Object} locals Injection locals for Controller. + * @return {Object} Instance of given controller. + * + * @description + * `$controller` service is responsible for instantiating controllers. + * + * It's just simple call to {@link AUTO.$injector $injector}, but extracted into + * a service, so that one can override this service with {@link https://gist.github.com/1649788 + * BC version}. + */ + return function(constructor, locals) { + if(isString(constructor)) { + var name = constructor; + constructor = controllers.hasOwnProperty(name) + ? controllers[name] + : getter(locals.$scope, name, true) || getter($window, name, true); + + assertArgFn(constructor, name, true); + } + + return $injector.instantiate(constructor, locals); + }; + }]; +} + +/** + * @ngdoc object + * @name ng.$document + * @requires $window + * + * @description + * A {@link angular.element jQuery (lite)}-wrapped reference to the browser's `window.document` + * element. + */ +function $DocumentProvider(){ + this.$get = ['$window', function(window){ + return jqLite(window.document); + }]; +} + +/** + * @ngdoc function + * @name ng.$exceptionHandler + * @requires $log + * + * @description + * Any uncaught exception in angular expressions is delegated to this service. + * The default implementation simply delegates to `$log.error` which logs it into + * the browser console. + * + * In unit tests, if `angular-mocks.js` is loaded, this service is overridden by + * {@link ngMock.$exceptionHandler mock $exceptionHandler} + * + * @param {Error} exception Exception associated with the error. + * @param {string=} cause optional information about the context in which + * the error was thrown. + */ +function $ExceptionHandlerProvider() { + this.$get = ['$log', function($log){ + return function(exception, cause) { + $log.error.apply($log, arguments); + }; + }]; +} + +/** + * @ngdoc object + * @name ng.$interpolateProvider + * @function + * + * @description + * + * Used for configuring the interpolation markup. Defaults to `{{` and `}}`. + */ +function $InterpolateProvider() { + var startSymbol = '{{'; + var endSymbol = '}}'; + + /** + * @ngdoc method + * @name ng.$interpolateProvider#startSymbol + * @methodOf ng.$interpolateProvider + * @description + * Symbol to denote start of expression in the interpolated string. Defaults to `{{`. + * + * @param {string=} value new value to set the starting symbol to. + * @returns {string|self} Returns the symbol when used as getter and self if used as setter. + */ + this.startSymbol = function(value){ + if (value) { + startSymbol = value; + return this; + } else { + return startSymbol; + } + }; + + /** + * @ngdoc method + * @name ng.$interpolateProvider#endSymbol + * @methodOf ng.$interpolateProvider + * @description + * Symbol to denote the end of expression in the interpolated string. Defaults to `}}`. + * + * @param {string=} value new value to set the ending symbol to. + * @returns {string|self} Returns the symbol when used as getter and self if used as setter. + */ + this.endSymbol = function(value){ + if (value) { + endSymbol = value; + return this; + } else { + return endSymbol; + } + }; + + + this.$get = ['$parse', function($parse) { + var startSymbolLength = startSymbol.length, + endSymbolLength = endSymbol.length; + + /** + * @ngdoc function + * @name ng.$interpolate + * @function + * + * @requires $parse + * + * @description + * + * Compiles a string with markup into an interpolation function. This service is used by the + * HTML {@link ng.$compile $compile} service for data binding. See + * {@link ng.$interpolateProvider $interpolateProvider} for configuring the + * interpolation markup. + * + * +
    +         var $interpolate = ...; // injected
    +         var exp = $interpolate('Hello {{name}}!');
    +         expect(exp({name:'Angular'}).toEqual('Hello Angular!');
    +       
    + * + * + * @param {string} text The text with markup to interpolate. + * @param {boolean=} mustHaveExpression if set to true then the interpolation string must have + * embedded expression in order to return an interpolation function. Strings with no + * embedded expression will return null for the interpolation function. + * @returns {function(context)} an interpolation function which is used to compute the interpolated + * string. The function has these parameters: + * + * * `context`: an object against which any expressions embedded in the strings are evaluated + * against. + * + */ + function $interpolate(text, mustHaveExpression) { + var startIndex, + endIndex, + index = 0, + parts = [], + length = text.length, + hasInterpolation = false, + fn, + exp, + concat = []; + + while(index < length) { + if ( ((startIndex = text.indexOf(startSymbol, index)) != -1) && + ((endIndex = text.indexOf(endSymbol, startIndex + startSymbolLength)) != -1) ) { + (index != startIndex) && parts.push(text.substring(index, startIndex)); + parts.push(fn = $parse(exp = text.substring(startIndex + startSymbolLength, endIndex))); + fn.exp = exp; + index = endIndex + endSymbolLength; + hasInterpolation = true; + } else { + // we did not find anything, so we have to add the remainder to the parts array + (index != length) && parts.push(text.substring(index)); + index = length; + } + } + + if (!(length = parts.length)) { + // we added, nothing, must have been an empty string. + parts.push(''); + length = 1; + } + + if (!mustHaveExpression || hasInterpolation) { + concat.length = length; + fn = function(context) { + for(var i = 0, ii = length, part; i html5 url + } else { + return composeProtocolHostPort(match.protocol, match.host, match.port) + + pathPrefixFromBase(basePath) + match.hash.substr(hashPrefix.length); + } +} + + +function convertToHashbangUrl(url, basePath, hashPrefix) { + var match = matchUrl(url); + + // already hashbang url + if (decodeURIComponent(match.path) == basePath) { + return url; + // convert html5 url -> hashbang url + } else { + var search = match.search && '?' + match.search || '', + hash = match.hash && '#' + match.hash || '', + pathPrefix = pathPrefixFromBase(basePath), + path = match.path.substr(pathPrefix.length); + + if (match.path.indexOf(pathPrefix) !== 0) { + throw Error('Invalid url "' + url + '", missing path prefix "' + pathPrefix + '" !'); + } + + return composeProtocolHostPort(match.protocol, match.host, match.port) + basePath + + '#' + hashPrefix + path + search + hash; + } +} + + +/** + * LocationUrl represents an url + * This object is exposed as $location service when HTML5 mode is enabled and supported + * + * @constructor + * @param {string} url HTML5 url + * @param {string} pathPrefix + */ +function LocationUrl(url, pathPrefix, appBaseUrl) { + pathPrefix = pathPrefix || ''; + + /** + * Parse given html5 (regular) url string into properties + * @param {string} newAbsoluteUrl HTML5 url + * @private + */ + this.$$parse = function(newAbsoluteUrl) { + var match = matchUrl(newAbsoluteUrl, this); + + if (match.path.indexOf(pathPrefix) !== 0) { + throw Error('Invalid url "' + newAbsoluteUrl + '", missing path prefix "' + pathPrefix + '" !'); + } + + this.$$path = decodeURIComponent(match.path.substr(pathPrefix.length)); + this.$$search = parseKeyValue(match.search); + this.$$hash = match.hash && decodeURIComponent(match.hash) || ''; + + this.$$compose(); + }; + + /** + * Compose url and update `absUrl` property + * @private + */ + this.$$compose = function() { + var search = toKeyValue(this.$$search), + hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : ''; + + this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash; + this.$$absUrl = composeProtocolHostPort(this.$$protocol, this.$$host, this.$$port) + + pathPrefix + this.$$url; + }; + + + this.$$rewriteAppUrl = function(absoluteLinkUrl) { + if(absoluteLinkUrl.indexOf(appBaseUrl) == 0) { + return absoluteLinkUrl; + } + } + + + this.$$parse(url); +} + + +/** + * LocationHashbangUrl represents url + * This object is exposed as $location service when html5 history api is disabled or not supported + * + * @constructor + * @param {string} url Legacy url + * @param {string} hashPrefix Prefix for hash part (containing path and search) + */ +function LocationHashbangUrl(url, hashPrefix, appBaseUrl) { + var basePath; + + /** + * Parse given hashbang url into properties + * @param {string} url Hashbang url + * @private + */ + this.$$parse = function(url) { + var match = matchUrl(url, this); + + + if (match.hash && match.hash.indexOf(hashPrefix) !== 0) { + throw Error('Invalid url "' + url + '", missing hash prefix "' + hashPrefix + '" !'); + } + + basePath = match.path + (match.search ? '?' + match.search : ''); + match = HASH_MATCH.exec((match.hash || '').substr(hashPrefix.length)); + if (match[1]) { + this.$$path = (match[1].charAt(0) == '/' ? '' : '/') + decodeURIComponent(match[1]); + } else { + this.$$path = ''; + } + + this.$$search = parseKeyValue(match[3]); + this.$$hash = match[5] && decodeURIComponent(match[5]) || ''; + + this.$$compose(); + }; + + /** + * Compose hashbang url and update `absUrl` property + * @private + */ + this.$$compose = function() { + var search = toKeyValue(this.$$search), + hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : ''; + + this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash; + this.$$absUrl = composeProtocolHostPort(this.$$protocol, this.$$host, this.$$port) + + basePath + (this.$$url ? '#' + hashPrefix + this.$$url : ''); + }; + + this.$$rewriteAppUrl = function(absoluteLinkUrl) { + if(absoluteLinkUrl.indexOf(appBaseUrl) == 0) { + return absoluteLinkUrl; + } + } + + + this.$$parse(url); +} + + +LocationUrl.prototype = { + + /** + * Has any change been replacing ? + * @private + */ + $$replace: false, + + /** + * @ngdoc method + * @name ng.$location#absUrl + * @methodOf ng.$location + * + * @description + * This method is getter only. + * + * Return full url representation with all segments encoded according to rules specified in + * {@link http://www.ietf.org/rfc/rfc3986.txt RFC 3986}. + * + * @return {string} full url + */ + absUrl: locationGetter('$$absUrl'), + + /** + * @ngdoc method + * @name ng.$location#url + * @methodOf ng.$location + * + * @description + * This method is getter / setter. + * + * Return url (e.g. `/path?a=b#hash`) when called without any parameter. + * + * Change path, search and hash, when called with parameter and return `$location`. + * + * @param {string=} url New url without base prefix (e.g. `/path?a=b#hash`) + * @return {string} url + */ + url: function(url, replace) { + if (isUndefined(url)) + return this.$$url; + + var match = PATH_MATCH.exec(url); + if (match[1]) this.path(decodeURIComponent(match[1])); + if (match[2] || match[1]) this.search(match[3] || ''); + this.hash(match[5] || '', replace); + + return this; + }, + + /** + * @ngdoc method + * @name ng.$location#protocol + * @methodOf ng.$location + * + * @description + * This method is getter only. + * + * Return protocol of current url. + * + * @return {string} protocol of current url + */ + protocol: locationGetter('$$protocol'), + + /** + * @ngdoc method + * @name ng.$location#host + * @methodOf ng.$location + * + * @description + * This method is getter only. + * + * Return host of current url. + * + * @return {string} host of current url. + */ + host: locationGetter('$$host'), + + /** + * @ngdoc method + * @name ng.$location#port + * @methodOf ng.$location + * + * @description + * This method is getter only. + * + * Return port of current url. + * + * @return {Number} port + */ + port: locationGetter('$$port'), + + /** + * @ngdoc method + * @name ng.$location#path + * @methodOf ng.$location + * + * @description + * This method is getter / setter. + * + * Return path of current url when called without any parameter. + * + * Change path when called with parameter and return `$location`. + * + * Note: Path should always begin with forward slash (/), this method will add the forward slash + * if it is missing. + * + * @param {string=} path New path + * @return {string} path + */ + path: locationGetterSetter('$$path', function(path) { + return path.charAt(0) == '/' ? path : '/' + path; + }), + + /** + * @ngdoc method + * @name ng.$location#search + * @methodOf ng.$location + * + * @description + * This method is getter / setter. + * + * Return search part (as object) of current url when called without any parameter. + * + * Change search part when called with parameter and return `$location`. + * + * @param {string|object=} search New search params - string or hash object + * @param {string=} paramValue If `search` is a string, then `paramValue` will override only a + * single search parameter. If the value is `null`, the parameter will be deleted. + * + * @return {string} search + */ + search: function(search, paramValue) { + if (isUndefined(search)) + return this.$$search; + + if (isDefined(paramValue)) { + if (paramValue === null) { + delete this.$$search[search]; + } else { + this.$$search[search] = paramValue; + } + } else { + this.$$search = isString(search) ? parseKeyValue(search) : search; + } + + this.$$compose(); + return this; + }, + + /** + * @ngdoc method + * @name ng.$location#hash + * @methodOf ng.$location + * + * @description + * This method is getter / setter. + * + * Return hash fragment when called without any parameter. + * + * Change hash fragment when called with parameter and return `$location`. + * + * @param {string=} hash New hash fragment + * @return {string} hash + */ + hash: locationGetterSetter('$$hash', identity), + + /** + * @ngdoc method + * @name ng.$location#replace + * @methodOf ng.$location + * + * @description + * If called, all changes to $location during current `$digest` will be replacing current history + * record, instead of adding new one. + */ + replace: function() { + this.$$replace = true; + return this; + } +}; + +LocationHashbangUrl.prototype = inherit(LocationUrl.prototype); + +function LocationHashbangInHtml5Url(url, hashPrefix, appBaseUrl, baseExtra) { + LocationHashbangUrl.apply(this, arguments); + + + this.$$rewriteAppUrl = function(absoluteLinkUrl) { + if (absoluteLinkUrl.indexOf(appBaseUrl) == 0) { + return appBaseUrl + baseExtra + '#' + hashPrefix + absoluteLinkUrl.substr(appBaseUrl.length); + } + } +} + +LocationHashbangInHtml5Url.prototype = inherit(LocationHashbangUrl.prototype); + +function locationGetter(property) { + return function() { + return this[property]; + }; +} + + +function locationGetterSetter(property, preprocess) { + return function(value) { + if (isUndefined(value)) + return this[property]; + + this[property] = preprocess(value); + this.$$compose(); + + return this; + }; +} + + +/** + * @ngdoc object + * @name ng.$location + * + * @requires $browser + * @requires $sniffer + * @requires $rootElement + * + * @description + * The $location service parses the URL in the browser address bar (based on the + * {@link https://developer.mozilla.org/en/window.location window.location}) and makes the URL + * available to your application. Changes to the URL in the address bar are reflected into + * $location service and changes to $location are reflected into the browser address bar. + * + * **The $location service:** + * + * - Exposes the current URL in the browser address bar, so you can + * - Watch and observe the URL. + * - Change the URL. + * - Synchronizes the URL with the browser when the user + * - Changes the address bar. + * - Clicks the back or forward button (or clicks a History link). + * - Clicks on a link. + * - Represents the URL object as a set of methods (protocol, host, port, path, search, hash). + * + * For more information see {@link guide/dev_guide.services.$location Developer Guide: Angular + * Services: Using $location} + */ + +/** + * @ngdoc object + * @name ng.$locationProvider + * @description + * Use the `$locationProvider` to configure how the application deep linking paths are stored. + */ +function $LocationProvider(){ + var hashPrefix = '', + html5Mode = false; + + /** + * @ngdoc property + * @name ng.$locationProvider#hashPrefix + * @methodOf ng.$locationProvider + * @description + * @param {string=} prefix Prefix for hash part (containing path and search) + * @returns {*} current value if used as getter or itself (chaining) if used as setter + */ + this.hashPrefix = function(prefix) { + if (isDefined(prefix)) { + hashPrefix = prefix; + return this; + } else { + return hashPrefix; + } + }; + + /** + * @ngdoc property + * @name ng.$locationProvider#html5Mode + * @methodOf ng.$locationProvider + * @description + * @param {string=} mode Use HTML5 strategy if available. + * @returns {*} current value if used as getter or itself (chaining) if used as setter + */ + this.html5Mode = function(mode) { + if (isDefined(mode)) { + html5Mode = mode; + return this; + } else { + return html5Mode; + } + }; + + this.$get = ['$rootScope', '$browser', '$sniffer', '$rootElement', + function( $rootScope, $browser, $sniffer, $rootElement) { + var $location, + basePath, + pathPrefix, + initUrl = $browser.url(), + initUrlParts = matchUrl(initUrl), + appBaseUrl; + + if (html5Mode) { + basePath = $browser.baseHref() || '/'; + pathPrefix = pathPrefixFromBase(basePath); + appBaseUrl = + composeProtocolHostPort(initUrlParts.protocol, initUrlParts.host, initUrlParts.port) + + pathPrefix + '/'; + + if ($sniffer.history) { + $location = new LocationUrl( + convertToHtml5Url(initUrl, basePath, hashPrefix), + pathPrefix, appBaseUrl); + } else { + $location = new LocationHashbangInHtml5Url( + convertToHashbangUrl(initUrl, basePath, hashPrefix), + hashPrefix, appBaseUrl, basePath.substr(pathPrefix.length + 1)); + } + } else { + appBaseUrl = + composeProtocolHostPort(initUrlParts.protocol, initUrlParts.host, initUrlParts.port) + + (initUrlParts.path || '') + + (initUrlParts.search ? ('?' + initUrlParts.search) : '') + + '#' + hashPrefix + '/'; + + $location = new LocationHashbangUrl(initUrl, hashPrefix, appBaseUrl); + } + + $rootElement.bind('click', function(event) { + // TODO(vojta): rewrite link when opening in new tab/window (in legacy browser) + // currently we open nice url link and redirect then + + if (event.ctrlKey || event.metaKey || event.which == 2) return; + + var elm = jqLite(event.target); + + // traverse the DOM up to find first A tag + while (lowercase(elm[0].nodeName) !== 'a') { + // ignore rewriting if no A tag (reached root element, or no parent - removed from document) + if (elm[0] === $rootElement[0] || !(elm = elm.parent())[0]) return; + } + + var absHref = elm.prop('href'), + rewrittenUrl = $location.$$rewriteAppUrl(absHref); + + if (absHref && !elm.attr('target') && rewrittenUrl) { + // update location manually + $location.$$parse(rewrittenUrl); + $rootScope.$apply(); + event.preventDefault(); + // hack to work around FF6 bug 684208 when scenario runner clicks on links + window.angular['ff-684208-preventDefault'] = true; + } + }); + + + // rewrite hashbang url <> html5 url + if ($location.absUrl() != initUrl) { + $browser.url($location.absUrl(), true); + } + + // update $location when $browser url changes + $browser.onUrlChange(function(newUrl) { + if ($location.absUrl() != newUrl) { + $rootScope.$evalAsync(function() { + var oldUrl = $location.absUrl(); + + $location.$$parse(newUrl); + afterLocationChange(oldUrl); + }); + if (!$rootScope.$$phase) $rootScope.$digest(); + } + }); + + // update browser + var changeCounter = 0; + $rootScope.$watch(function $locationWatch() { + var oldUrl = $browser.url(); + + if (!changeCounter || oldUrl != $location.absUrl()) { + changeCounter++; + $rootScope.$evalAsync(function() { + if ($rootScope.$broadcast('$locationChangeStart', $location.absUrl(), oldUrl). + defaultPrevented) { + $location.$$parse(oldUrl); + } else { + $browser.url($location.absUrl(), $location.$$replace); + $location.$$replace = false; + afterLocationChange(oldUrl); + } + }); + } + + return changeCounter; + }); + + return $location; + + function afterLocationChange(oldUrl) { + $rootScope.$broadcast('$locationChangeSuccess', $location.absUrl(), oldUrl); + } +}]; +} + +/** + * @ngdoc object + * @name ng.$log + * @requires $window + * + * @description + * Simple service for logging. Default implementation writes the message + * into the browser's console (if present). + * + * The main purpose of this service is to simplify debugging and troubleshooting. + * + * @example + + + function LogCtrl($scope, $log) { + $scope.$log = $log; + $scope.message = 'Hello World!'; + } + + +
    +

    Reload this page with open console, enter text and hit the log button...

    + Message: + + + + + +
    +
    +
    + */ + +function $LogProvider(){ + this.$get = ['$window', function($window){ + return { + /** + * @ngdoc method + * @name ng.$log#log + * @methodOf ng.$log + * + * @description + * Write a log message + */ + log: consoleLog('log'), + + /** + * @ngdoc method + * @name ng.$log#warn + * @methodOf ng.$log + * + * @description + * Write a warning message + */ + warn: consoleLog('warn'), + + /** + * @ngdoc method + * @name ng.$log#info + * @methodOf ng.$log + * + * @description + * Write an information message + */ + info: consoleLog('info'), + + /** + * @ngdoc method + * @name ng.$log#error + * @methodOf ng.$log + * + * @description + * Write an error message + */ + error: consoleLog('error') + }; + + function formatError(arg) { + if (arg instanceof Error) { + if (arg.stack) { + arg = (arg.message && arg.stack.indexOf(arg.message) === -1) + ? 'Error: ' + arg.message + '\n' + arg.stack + : arg.stack; + } else if (arg.sourceURL) { + arg = arg.message + '\n' + arg.sourceURL + ':' + arg.line; + } + } + return arg; + } + + function consoleLog(type) { + var console = $window.console || {}, + logFn = console[type] || console.log || noop; + + if (logFn.apply) { + return function() { + var args = []; + forEach(arguments, function(arg) { + args.push(formatError(arg)); + }); + return logFn.apply(console, args); + }; + } + + // we are IE which either doesn't have window.console => this is noop and we do nothing, + // or we are IE where console.log doesn't have apply so we log at least first 2 args + return function(arg1, arg2) { + logFn(arg1, arg2); + } + } + }]; +} + +var OPERATORS = { + 'null':function(){return null;}, + 'true':function(){return true;}, + 'false':function(){return false;}, + undefined:noop, + '+':function(self, locals, a,b){a=a(self, locals); b=b(self, locals); return (isDefined(a)?a:0)+(isDefined(b)?b:0);}, + '-':function(self, locals, a,b){a=a(self, locals); b=b(self, locals); return (isDefined(a)?a:0)-(isDefined(b)?b:0);}, + '*':function(self, locals, a,b){return a(self, locals)*b(self, locals);}, + '/':function(self, locals, a,b){return a(self, locals)/b(self, locals);}, + '%':function(self, locals, a,b){return a(self, locals)%b(self, locals);}, + '^':function(self, locals, a,b){return a(self, locals)^b(self, locals);}, + '=':noop, + '==':function(self, locals, a,b){return a(self, locals)==b(self, locals);}, + '!=':function(self, locals, a,b){return a(self, locals)!=b(self, locals);}, + '<':function(self, locals, a,b){return a(self, locals)':function(self, locals, a,b){return a(self, locals)>b(self, locals);}, + '<=':function(self, locals, a,b){return a(self, locals)<=b(self, locals);}, + '>=':function(self, locals, a,b){return a(self, locals)>=b(self, locals);}, + '&&':function(self, locals, a,b){return a(self, locals)&&b(self, locals);}, + '||':function(self, locals, a,b){return a(self, locals)||b(self, locals);}, + '&':function(self, locals, a,b){return a(self, locals)&b(self, locals);}, +// '|':function(self, locals, a,b){return a|b;}, + '|':function(self, locals, a,b){return b(self, locals)(self, locals, a(self, locals));}, + '!':function(self, locals, a){return !a(self, locals);} +}; +var ESCAPE = {"n":"\n", "f":"\f", "r":"\r", "t":"\t", "v":"\v", "'":"'", '"':'"'}; + +function lex(text, csp){ + var tokens = [], + token, + index = 0, + json = [], + ch, + lastCh = ':'; // can start regexp + + while (index < text.length) { + ch = text.charAt(index); + if (is('"\'')) { + readString(ch); + } else if (isNumber(ch) || is('.') && isNumber(peek())) { + readNumber(); + } else if (isIdent(ch)) { + readIdent(); + // identifiers can only be if the preceding char was a { or , + if (was('{,') && json[0]=='{' && + (token=tokens[tokens.length-1])) { + token.json = token.text.indexOf('.') == -1; + } + } else if (is('(){}[].,;:')) { + tokens.push({ + index:index, + text:ch, + json:(was(':[,') && is('{[')) || is('}]:,') + }); + if (is('{[')) json.unshift(ch); + if (is('}]')) json.shift(); + index++; + } else if (isWhitespace(ch)) { + index++; + continue; + } else { + var ch2 = ch + peek(), + fn = OPERATORS[ch], + fn2 = OPERATORS[ch2]; + if (fn2) { + tokens.push({index:index, text:ch2, fn:fn2}); + index += 2; + } else if (fn) { + tokens.push({index:index, text:ch, fn:fn, json: was('[,:') && is('+-')}); + index += 1; + } else { + throwError("Unexpected next character ", index, index+1); + } + } + lastCh = ch; + } + return tokens; + + function is(chars) { + return chars.indexOf(ch) != -1; + } + + function was(chars) { + return chars.indexOf(lastCh) != -1; + } + + function peek() { + return index + 1 < text.length ? text.charAt(index + 1) : false; + } + function isNumber(ch) { + return '0' <= ch && ch <= '9'; + } + function isWhitespace(ch) { + return ch == ' ' || ch == '\r' || ch == '\t' || + ch == '\n' || ch == '\v' || ch == '\u00A0'; // IE treats non-breaking space as \u00A0 + } + function isIdent(ch) { + return 'a' <= ch && ch <= 'z' || + 'A' <= ch && ch <= 'Z' || + '_' == ch || ch == '$'; + } + function isExpOperator(ch) { + return ch == '-' || ch == '+' || isNumber(ch); + } + + function throwError(error, start, end) { + end = end || index; + throw Error("Lexer Error: " + error + " at column" + + (isDefined(start) + ? "s " + start + "-" + index + " [" + text.substring(start, end) + "]" + : " " + end) + + " in expression [" + text + "]."); + } + + function readNumber() { + var number = ""; + var start = index; + while (index < text.length) { + var ch = lowercase(text.charAt(index)); + if (ch == '.' || isNumber(ch)) { + number += ch; + } else { + var peekCh = peek(); + if (ch == 'e' && isExpOperator(peekCh)) { + number += ch; + } else if (isExpOperator(ch) && + peekCh && isNumber(peekCh) && + number.charAt(number.length - 1) == 'e') { + number += ch; + } else if (isExpOperator(ch) && + (!peekCh || !isNumber(peekCh)) && + number.charAt(number.length - 1) == 'e') { + throwError('Invalid exponent'); + } else { + break; + } + } + index++; + } + number = 1 * number; + tokens.push({index:start, text:number, json:true, + fn:function() {return number;}}); + } + function readIdent() { + var ident = "", + start = index, + lastDot, peekIndex, methodName; + + while (index < text.length) { + var ch = text.charAt(index); + if (ch == '.' || isIdent(ch) || isNumber(ch)) { + if (ch == '.') lastDot = index; + ident += ch; + } else { + break; + } + index++; + } + + //check if this is not a method invocation and if it is back out to last dot + if (lastDot) { + peekIndex = index; + while(peekIndex < text.length) { + var ch = text.charAt(peekIndex); + if (ch == '(') { + methodName = ident.substr(lastDot - start + 1); + ident = ident.substr(0, lastDot - start); + index = peekIndex; + break; + } + if(isWhitespace(ch)) { + peekIndex++; + } else { + break; + } + } + } + + + var token = { + index:start, + text:ident + }; + + if (OPERATORS.hasOwnProperty(ident)) { + token.fn = token.json = OPERATORS[ident]; + } else { + var getter = getterFn(ident, csp); + token.fn = extend(function(self, locals) { + return (getter(self, locals)); + }, { + assign: function(self, value) { + return setter(self, ident, value); + } + }); + } + + tokens.push(token); + + if (methodName) { + tokens.push({ + index:lastDot, + text: '.', + json: false + }); + tokens.push({ + index: lastDot + 1, + text: methodName, + json: false + }); + } + } + + function readString(quote) { + var start = index; + index++; + var string = ""; + var rawString = quote; + var escape = false; + while (index < text.length) { + var ch = text.charAt(index); + rawString += ch; + if (escape) { + if (ch == 'u') { + var hex = text.substring(index + 1, index + 5); + if (!hex.match(/[\da-f]{4}/i)) + throwError( "Invalid unicode escape [\\u" + hex + "]"); + index += 4; + string += String.fromCharCode(parseInt(hex, 16)); + } else { + var rep = ESCAPE[ch]; + if (rep) { + string += rep; + } else { + string += ch; + } + } + escape = false; + } else if (ch == '\\') { + escape = true; + } else if (ch == quote) { + index++; + tokens.push({ + index:start, + text:rawString, + string:string, + json:true, + fn:function() { return string; } + }); + return; + } else { + string += ch; + } + index++; + } + throwError("Unterminated quote", start); + } +} + +///////////////////////////////////////// + +function parser(text, json, $filter, csp){ + var ZERO = valueFn(0), + value, + tokens = lex(text, csp), + assignment = _assignment, + functionCall = _functionCall, + fieldAccess = _fieldAccess, + objectIndex = _objectIndex, + filterChain = _filterChain; + + if(json){ + // The extra level of aliasing is here, just in case the lexer misses something, so that + // we prevent any accidental execution in JSON. + assignment = logicalOR; + functionCall = + fieldAccess = + objectIndex = + filterChain = + function() { throwError("is not valid json", {text:text, index:0}); }; + value = primary(); + } else { + value = statements(); + } + if (tokens.length !== 0) { + throwError("is an unexpected token", tokens[0]); + } + return value; + + /////////////////////////////////// + function throwError(msg, token) { + throw Error("Syntax Error: Token '" + token.text + + "' " + msg + " at column " + + (token.index + 1) + " of the expression [" + + text + "] starting at [" + text.substring(token.index) + "]."); + } + + function peekToken() { + if (tokens.length === 0) + throw Error("Unexpected end of expression: " + text); + return tokens[0]; + } + + function peek(e1, e2, e3, e4) { + if (tokens.length > 0) { + var token = tokens[0]; + var t = token.text; + if (t==e1 || t==e2 || t==e3 || t==e4 || + (!e1 && !e2 && !e3 && !e4)) { + return token; + } + } + return false; + } + + function expect(e1, e2, e3, e4){ + var token = peek(e1, e2, e3, e4); + if (token) { + if (json && !token.json) { + throwError("is not valid json", token); + } + tokens.shift(); + return token; + } + return false; + } + + function consume(e1){ + if (!expect(e1)) { + throwError("is unexpected, expecting [" + e1 + "]", peek()); + } + } + + function unaryFn(fn, right) { + return function(self, locals) { + return fn(self, locals, right); + }; + } + + function binaryFn(left, fn, right) { + return function(self, locals) { + return fn(self, locals, left, right); + }; + } + + function statements() { + var statements = []; + while(true) { + if (tokens.length > 0 && !peek('}', ')', ';', ']')) + statements.push(filterChain()); + if (!expect(';')) { + // optimize for the common case where there is only one statement. + // TODO(size): maybe we should not support multiple statements? + return statements.length == 1 + ? statements[0] + : function(self, locals){ + var value; + for ( var i = 0; i < statements.length; i++) { + var statement = statements[i]; + if (statement) + value = statement(self, locals); + } + return value; + }; + } + } + } + + function _filterChain() { + var left = expression(); + var token; + while(true) { + if ((token = expect('|'))) { + left = binaryFn(left, token.fn, filter()); + } else { + return left; + } + } + } + + function filter() { + var token = expect(); + var fn = $filter(token.text); + var argsFn = []; + while(true) { + if ((token = expect(':'))) { + argsFn.push(expression()); + } else { + var fnInvoke = function(self, locals, input){ + var args = [input]; + for ( var i = 0; i < argsFn.length; i++) { + args.push(argsFn[i](self, locals)); + } + return fn.apply(self, args); + }; + return function() { + return fnInvoke; + }; + } + } + } + + function expression() { + return assignment(); + } + + function _assignment() { + var left = logicalOR(); + var right; + var token; + if ((token = expect('='))) { + if (!left.assign) { + throwError("implies assignment but [" + + text.substring(0, token.index) + "] can not be assigned to", token); + } + right = logicalOR(); + return function(self, locals){ + return left.assign(self, right(self, locals), locals); + }; + } else { + return left; + } + } + + function logicalOR() { + var left = logicalAND(); + var token; + while(true) { + if ((token = expect('||'))) { + left = binaryFn(left, token.fn, logicalAND()); + } else { + return left; + } + } + } + + function logicalAND() { + var left = equality(); + var token; + if ((token = expect('&&'))) { + left = binaryFn(left, token.fn, logicalAND()); + } + return left; + } + + function equality() { + var left = relational(); + var token; + if ((token = expect('==','!='))) { + left = binaryFn(left, token.fn, equality()); + } + return left; + } + + function relational() { + var left = additive(); + var token; + if ((token = expect('<', '>', '<=', '>='))) { + left = binaryFn(left, token.fn, relational()); + } + return left; + } + + function additive() { + var left = multiplicative(); + var token; + while ((token = expect('+','-'))) { + left = binaryFn(left, token.fn, multiplicative()); + } + return left; + } + + function multiplicative() { + var left = unary(); + var token; + while ((token = expect('*','/','%'))) { + left = binaryFn(left, token.fn, unary()); + } + return left; + } + + function unary() { + var token; + if (expect('+')) { + return primary(); + } else if ((token = expect('-'))) { + return binaryFn(ZERO, token.fn, unary()); + } else if ((token = expect('!'))) { + return unaryFn(token.fn, unary()); + } else { + return primary(); + } + } + + + function primary() { + var primary; + if (expect('(')) { + primary = filterChain(); + consume(')'); + } else if (expect('[')) { + primary = arrayDeclaration(); + } else if (expect('{')) { + primary = object(); + } else { + var token = expect(); + primary = token.fn; + if (!primary) { + throwError("not a primary expression", token); + } + } + + var next, context; + while ((next = expect('(', '[', '.'))) { + if (next.text === '(') { + primary = functionCall(primary, context); + context = null; + } else if (next.text === '[') { + context = primary; + primary = objectIndex(primary); + } else if (next.text === '.') { + context = primary; + primary = fieldAccess(primary); + } else { + throwError("IMPOSSIBLE"); + } + } + return primary; + } + + function _fieldAccess(object) { + var field = expect().text; + var getter = getterFn(field, csp); + return extend( + function(self, locals) { + return getter(object(self, locals), locals); + }, + { + assign:function(self, value, locals) { + return setter(object(self, locals), field, value); + } + } + ); + } + + function _objectIndex(obj) { + var indexFn = expression(); + consume(']'); + return extend( + function(self, locals){ + var o = obj(self, locals), + i = indexFn(self, locals), + v, p; + + if (!o) return undefined; + v = o[i]; + if (v && v.then) { + p = v; + if (!('$$v' in v)) { + p.$$v = undefined; + p.then(function(val) { p.$$v = val; }); + } + v = v.$$v; + } + return v; + }, { + assign:function(self, value, locals){ + return obj(self, locals)[indexFn(self, locals)] = value; + } + }); + } + + function _functionCall(fn, contextGetter) { + var argsFn = []; + if (peekToken().text != ')') { + do { + argsFn.push(expression()); + } while (expect(',')); + } + consume(')'); + return function(self, locals){ + var args = [], + context = contextGetter ? contextGetter(self, locals) : self; + + for ( var i = 0; i < argsFn.length; i++) { + args.push(argsFn[i](self, locals)); + } + var fnPtr = fn(self, locals) || noop; + // IE stupidity! + return fnPtr.apply + ? fnPtr.apply(context, args) + : fnPtr(args[0], args[1], args[2], args[3], args[4]); + }; + } + + // This is used with json array declaration + function arrayDeclaration () { + var elementFns = []; + if (peekToken().text != ']') { + do { + elementFns.push(expression()); + } while (expect(',')); + } + consume(']'); + return function(self, locals){ + var array = []; + for ( var i = 0; i < elementFns.length; i++) { + array.push(elementFns[i](self, locals)); + } + return array; + }; + } + + function object () { + var keyValues = []; + if (peekToken().text != '}') { + do { + var token = expect(), + key = token.string || token.text; + consume(":"); + var value = expression(); + keyValues.push({key:key, value:value}); + } while (expect(',')); + } + consume('}'); + return function(self, locals){ + var object = {}; + for ( var i = 0; i < keyValues.length; i++) { + var keyValue = keyValues[i]; + var value = keyValue.value(self, locals); + object[keyValue.key] = value; + } + return object; + }; + } +} + +////////////////////////////////////////////////// +// Parser helper functions +////////////////////////////////////////////////// + +function setter(obj, path, setValue) { + var element = path.split('.'); + for (var i = 0; element.length > 1; i++) { + var key = element.shift(); + var propertyObj = obj[key]; + if (!propertyObj) { + propertyObj = {}; + obj[key] = propertyObj; + } + obj = propertyObj; + } + obj[element.shift()] = setValue; + return setValue; +} + +/** + * Return the value accesible from the object by path. Any undefined traversals are ignored + * @param {Object} obj starting object + * @param {string} path path to traverse + * @param {boolean=true} bindFnToScope + * @returns value as accesbile by path + */ +//TODO(misko): this function needs to be removed +function getter(obj, path, bindFnToScope) { + if (!path) return obj; + var keys = path.split('.'); + var key; + var lastInstance = obj; + var len = keys.length; + + for (var i = 0; i < len; i++) { + key = keys[i]; + if (obj) { + obj = (lastInstance = obj)[key]; + } + } + if (!bindFnToScope && isFunction(obj)) { + return bind(lastInstance, obj); + } + return obj; +} + +var getterFnCache = {}; + +/** + * Implementation of the "Black Hole" variant from: + * - http://jsperf.com/angularjs-parse-getter/4 + * - http://jsperf.com/path-evaluation-simplified/7 + */ +function cspSafeGetterFn(key0, key1, key2, key3, key4) { + return function(scope, locals) { + var pathVal = (locals && locals.hasOwnProperty(key0)) ? locals : scope, + promise; + + if (pathVal === null || pathVal === undefined) return pathVal; + + pathVal = pathVal[key0]; + if (pathVal && pathVal.then) { + if (!("$$v" in pathVal)) { + promise = pathVal; + promise.$$v = undefined; + promise.then(function(val) { promise.$$v = val; }); + } + pathVal = pathVal.$$v; + } + if (!key1 || pathVal === null || pathVal === undefined) return pathVal; + + pathVal = pathVal[key1]; + if (pathVal && pathVal.then) { + if (!("$$v" in pathVal)) { + promise = pathVal; + promise.$$v = undefined; + promise.then(function(val) { promise.$$v = val; }); + } + pathVal = pathVal.$$v; + } + if (!key2 || pathVal === null || pathVal === undefined) return pathVal; + + pathVal = pathVal[key2]; + if (pathVal && pathVal.then) { + if (!("$$v" in pathVal)) { + promise = pathVal; + promise.$$v = undefined; + promise.then(function(val) { promise.$$v = val; }); + } + pathVal = pathVal.$$v; + } + if (!key3 || pathVal === null || pathVal === undefined) return pathVal; + + pathVal = pathVal[key3]; + if (pathVal && pathVal.then) { + if (!("$$v" in pathVal)) { + promise = pathVal; + promise.$$v = undefined; + promise.then(function(val) { promise.$$v = val; }); + } + pathVal = pathVal.$$v; + } + if (!key4 || pathVal === null || pathVal === undefined) return pathVal; + + pathVal = pathVal[key4]; + if (pathVal && pathVal.then) { + if (!("$$v" in pathVal)) { + promise = pathVal; + promise.$$v = undefined; + promise.then(function(val) { promise.$$v = val; }); + } + pathVal = pathVal.$$v; + } + return pathVal; + }; +}; + +function getterFn(path, csp) { + if (getterFnCache.hasOwnProperty(path)) { + return getterFnCache[path]; + } + + var pathKeys = path.split('.'), + pathKeysLength = pathKeys.length, + fn; + + if (csp) { + fn = (pathKeysLength < 6) + ? cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4]) + : function(scope, locals) { + var i = 0, val + do { + val = cspSafeGetterFn( + pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++] + )(scope, locals); + + locals = undefined; // clear after first iteration + scope = val; + } while (i < pathKeysLength); + return val; + } + } else { + var code = 'var l, fn, p;\n'; + forEach(pathKeys, function(key, index) { + code += 'if(s === null || s === undefined) return s;\n' + + 'l=s;\n' + + 's='+ (index + // we simply dereference 's' on any .dot notation + ? 's' + // but if we are first then we check locals first, and if so read it first + : '((k&&k.hasOwnProperty("' + key + '"))?k:s)') + '["' + key + '"]' + ';\n' + + 'if (s && s.then) {\n' + + ' if (!("$$v" in s)) {\n' + + ' p=s;\n' + + ' p.$$v = undefined;\n' + + ' p.then(function(v) {p.$$v=v;});\n' + + '}\n' + + ' s=s.$$v\n' + + '}\n'; + }); + code += 'return s;'; + fn = Function('s', 'k', code); // s=scope, k=locals + fn.toString = function() { return code; }; + } + + return getterFnCache[path] = fn; +} + +/////////////////////////////////// + +/** + * @ngdoc function + * @name ng.$parse + * @function + * + * @description + * + * Converts Angular {@link guide/expression expression} into a function. + * + *
    + *   var getter = $parse('user.name');
    + *   var setter = getter.assign;
    + *   var context = {user:{name:'angular'}};
    + *   var locals = {user:{name:'local'}};
    + *
    + *   expect(getter(context)).toEqual('angular');
    + *   setter(context, 'newValue');
    + *   expect(context.user.name).toEqual('newValue');
    + *   expect(getter(context, locals)).toEqual('local');
    + * 
    + * + * + * @param {string} expression String expression to compile. + * @returns {function(context, locals)} a function which represents the compiled expression: + * + * * `context`: an object against which any expressions embedded in the strings are evaluated + * against (Topically a scope object). + * * `locals`: local variables context object, useful for overriding values in `context`. + * + * The return function also has an `assign` property, if the expression is assignable, which + * allows one to set values to expressions. + * + */ +function $ParseProvider() { + var cache = {}; + this.$get = ['$filter', '$sniffer', function($filter, $sniffer) { + return function(exp) { + switch(typeof exp) { + case 'string': + return cache.hasOwnProperty(exp) + ? cache[exp] + : cache[exp] = parser(exp, false, $filter, $sniffer.csp); + case 'function': + return exp; + default: + return noop; + } + }; + }]; +} + +/** + * @ngdoc service + * @name ng.$q + * @requires $rootScope + * + * @description + * A promise/deferred implementation inspired by [Kris Kowal's Q](https://github.com/kriskowal/q). + * + * [The CommonJS Promise proposal](http://wiki.commonjs.org/wiki/Promises) describes a promise as an + * interface for interacting with an object that represents the result of an action that is + * performed asynchronously, and may or may not be finished at any given point in time. + * + * From the perspective of dealing with error handling, deferred and promise apis are to + * asynchronous programing what `try`, `catch` and `throw` keywords are to synchronous programing. + * + *
    + *   // for the purpose of this example let's assume that variables `$q` and `scope` are
    + *   // available in the current lexical scope (they could have been injected or passed in).
    + *
    + *   function asyncGreet(name) {
    + *     var deferred = $q.defer();
    + *
    + *     setTimeout(function() {
    + *       // since this fn executes async in a future turn of the event loop, we need to wrap
    + *       // our code into an $apply call so that the model changes are properly observed.
    + *       scope.$apply(function() {
    + *         if (okToGreet(name)) {
    + *           deferred.resolve('Hello, ' + name + '!');
    + *         } else {
    + *           deferred.reject('Greeting ' + name + ' is not allowed.');
    + *         }
    + *       });
    + *     }, 1000);
    + *
    + *     return deferred.promise;
    + *   }
    + *
    + *   var promise = asyncGreet('Robin Hood');
    + *   promise.then(function(greeting) {
    + *     alert('Success: ' + greeting);
    + *   }, function(reason) {
    + *     alert('Failed: ' + reason);
    + *   );
    + * 
    + * + * At first it might not be obvious why this extra complexity is worth the trouble. The payoff + * comes in the way of + * [guarantees that promise and deferred apis make](https://github.com/kriskowal/uncommonjs/blob/master/promises/specification.md). + * + * Additionally the promise api allows for composition that is very hard to do with the + * traditional callback ([CPS](http://en.wikipedia.org/wiki/Continuation-passing_style)) approach. + * For more on this please see the [Q documentation](https://github.com/kriskowal/q) especially the + * section on serial or parallel joining of promises. + * + * + * # The Deferred API + * + * A new instance of deferred is constructed by calling `$q.defer()`. + * + * The purpose of the deferred object is to expose the associated Promise instance as well as apis + * that can be used for signaling the successful or unsuccessful completion of the task. + * + * **Methods** + * + * - `resolve(value)` – resolves the derived promise with the `value`. If the value is a rejection + * constructed via `$q.reject`, the promise will be rejected instead. + * - `reject(reason)` – rejects the derived promise with the `reason`. This is equivalent to + * resolving it with a rejection constructed via `$q.reject`. + * + * **Properties** + * + * - promise – `{Promise}` – promise object associated with this deferred. + * + * + * # The Promise API + * + * A new promise instance is created when a deferred instance is created and can be retrieved by + * calling `deferred.promise`. + * + * The purpose of the promise object is to allow for interested parties to get access to the result + * of the deferred task when it completes. + * + * **Methods** + * + * - `then(successCallback, errorCallback)` – regardless of when the promise was or will be resolved + * or rejected calls one of the success or error callbacks asynchronously as soon as the result + * is available. The callbacks are called with a single argument the result or rejection reason. + * + * This method *returns a new promise* which is resolved or rejected via the return value of the + * `successCallback` or `errorCallback`. + * + * + * # Chaining promises + * + * Because calling `then` api of a promise returns a new derived promise, it is easily possible + * to create a chain of promises: + * + *
    + *   promiseB = promiseA.then(function(result) {
    + *     return result + 1;
    + *   });
    + *
    + *   // promiseB will be resolved immediately after promiseA is resolved and it's value will be
    + *   // the result of promiseA incremented by 1
    + * 
    + * + * It is possible to create chains of any length and since a promise can be resolved with another + * promise (which will defer its resolution further), it is possible to pause/defer resolution of + * the promises at any point in the chain. This makes it possible to implement powerful apis like + * $http's response interceptors. + * + * + * # Differences between Kris Kowal's Q and $q + * + * There are three main differences: + * + * - $q is integrated with the {@link ng.$rootScope.Scope} Scope model observation + * mechanism in angular, which means faster propagation of resolution or rejection into your + * models and avoiding unnecessary browser repaints, which would result in flickering UI. + * - $q promises are recognized by the templating engine in angular, which means that in templates + * you can treat promises attached to a scope as if they were the resulting values. + * - Q has many more features that $q, but that comes at a cost of bytes. $q is tiny, but contains + * all the important functionality needed for common async tasks. + */ +function $QProvider() { + + this.$get = ['$rootScope', '$exceptionHandler', function($rootScope, $exceptionHandler) { + return qFactory(function(callback) { + $rootScope.$evalAsync(callback); + }, $exceptionHandler); + }]; +} + + +/** + * Constructs a promise manager. + * + * @param {function(function)} nextTick Function for executing functions in the next turn. + * @param {function(...*)} exceptionHandler Function into which unexpected exceptions are passed for + * debugging purposes. + * @returns {object} Promise manager. + */ +function qFactory(nextTick, exceptionHandler) { + + /** + * @ngdoc + * @name ng.$q#defer + * @methodOf ng.$q + * @description + * Creates a `Deferred` object which represents a task which will finish in the future. + * + * @returns {Deferred} Returns a new instance of deferred. + */ + var defer = function() { + var pending = [], + value, deferred; + + deferred = { + + resolve: function(val) { + if (pending) { + var callbacks = pending; + pending = undefined; + value = ref(val); + + if (callbacks.length) { + nextTick(function() { + var callback; + for (var i = 0, ii = callbacks.length; i < ii; i++) { + callback = callbacks[i]; + value.then(callback[0], callback[1]); + } + }); + } + } + }, + + + reject: function(reason) { + deferred.resolve(reject(reason)); + }, + + + promise: { + then: function(callback, errback) { + var result = defer(); + + var wrappedCallback = function(value) { + try { + result.resolve((callback || defaultCallback)(value)); + } catch(e) { + exceptionHandler(e); + result.reject(e); + } + }; + + var wrappedErrback = function(reason) { + try { + result.resolve((errback || defaultErrback)(reason)); + } catch(e) { + exceptionHandler(e); + result.reject(e); + } + }; + + if (pending) { + pending.push([wrappedCallback, wrappedErrback]); + } else { + value.then(wrappedCallback, wrappedErrback); + } + + return result.promise; + } + } + }; + + return deferred; + }; + + + var ref = function(value) { + if (value && value.then) return value; + return { + then: function(callback) { + var result = defer(); + nextTick(function() { + result.resolve(callback(value)); + }); + return result.promise; + } + }; + }; + + + /** + * @ngdoc + * @name ng.$q#reject + * @methodOf ng.$q + * @description + * Creates a promise that is resolved as rejected with the specified `reason`. This api should be + * used to forward rejection in a chain of promises. If you are dealing with the last promise in + * a promise chain, you don't need to worry about it. + * + * When comparing deferreds/promises to the familiar behavior of try/catch/throw, think of + * `reject` as the `throw` keyword in JavaScript. This also means that if you "catch" an error via + * a promise error callback and you want to forward the error to the promise derived from the + * current promise, you have to "rethrow" the error by returning a rejection constructed via + * `reject`. + * + *
    +   *   promiseB = promiseA.then(function(result) {
    +   *     // success: do something and resolve promiseB
    +   *     //          with the old or a new result
    +   *     return result;
    +   *   }, function(reason) {
    +   *     // error: handle the error if possible and
    +   *     //        resolve promiseB with newPromiseOrValue,
    +   *     //        otherwise forward the rejection to promiseB
    +   *     if (canHandle(reason)) {
    +   *      // handle the error and recover
    +   *      return newPromiseOrValue;
    +   *     }
    +   *     return $q.reject(reason);
    +   *   });
    +   * 
    + * + * @param {*} reason Constant, message, exception or an object representing the rejection reason. + * @returns {Promise} Returns a promise that was already resolved as rejected with the `reason`. + */ + var reject = function(reason) { + return { + then: function(callback, errback) { + var result = defer(); + nextTick(function() { + result.resolve((errback || defaultErrback)(reason)); + }); + return result.promise; + } + }; + }; + + + /** + * @ngdoc + * @name ng.$q#when + * @methodOf ng.$q + * @description + * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. + * This is useful when you are dealing with on object that might or might not be a promise, or if + * the promise comes from a source that can't be trusted. + * + * @param {*} value Value or a promise + * @returns {Promise} Returns a single promise that will be resolved with an array of values, + * each value coresponding to the promise at the same index in the `promises` array. If any of + * the promises is resolved with a rejection, this resulting promise will be resolved with the + * same rejection. + */ + var when = function(value, callback, errback) { + var result = defer(), + done; + + var wrappedCallback = function(value) { + try { + return (callback || defaultCallback)(value); + } catch (e) { + exceptionHandler(e); + return reject(e); + } + }; + + var wrappedErrback = function(reason) { + try { + return (errback || defaultErrback)(reason); + } catch (e) { + exceptionHandler(e); + return reject(e); + } + }; + + nextTick(function() { + ref(value).then(function(value) { + if (done) return; + done = true; + result.resolve(ref(value).then(wrappedCallback, wrappedErrback)); + }, function(reason) { + if (done) return; + done = true; + result.resolve(wrappedErrback(reason)); + }); + }); + + return result.promise; + }; + + + function defaultCallback(value) { + return value; + } + + + function defaultErrback(reason) { + return reject(reason); + } + + + /** + * @ngdoc + * @name ng.$q#all + * @methodOf ng.$q + * @description + * Combines multiple promises into a single promise that is resolved when all of the input + * promises are resolved. + * + * @param {Array.} promises An array of promises. + * @returns {Promise} Returns a single promise that will be resolved with an array of values, + * each value coresponding to the promise at the same index in the `promises` array. If any of + * the promises is resolved with a rejection, this resulting promise will be resolved with the + * same rejection. + */ + function all(promises) { + var deferred = defer(), + counter = promises.length, + results = []; + + if (counter) { + forEach(promises, function(promise, index) { + ref(promise).then(function(value) { + if (index in results) return; + results[index] = value; + if (!(--counter)) deferred.resolve(results); + }, function(reason) { + if (index in results) return; + deferred.reject(reason); + }); + }); + } else { + deferred.resolve(results); + } + + return deferred.promise; + } + + return { + defer: defer, + reject: reject, + when: when, + all: all + }; +} + +/** + * @ngdoc object + * @name ng.$routeProvider + * @function + * + * @description + * + * Used for configuring routes. See {@link ng.$route $route} for an example. + */ +function $RouteProvider(){ + var routes = {}; + + /** + * @ngdoc method + * @name ng.$routeProvider#when + * @methodOf ng.$routeProvider + * + * @param {string} path Route path (matched against `$location.path`). If `$location.path` + * contains redundant trailing slash or is missing one, the route will still match and the + * `$location.path` will be updated to add or drop the trailing slash to exacly match the + * route definition. + * @param {Object} route Mapping information to be assigned to `$route.current` on route + * match. + * + * Object properties: + * + * - `controller` – `{(string|function()=}` – Controller fn that should be associated with newly + * created scope or the name of a {@link angular.Module#controller registered controller} + * if passed as a string. + * - `template` – `{string=}` – html template as a string that should be used by + * {@link ng.directive:ngView ngView} or + * {@link ng.directive:ngInclude ngInclude} directives. + * this property takes precedence over `templateUrl`. + * - `templateUrl` – `{string=}` – path to an html template that should be used by + * {@link ng.directive:ngView ngView}. + * - `resolve` - `{Object.=}` - An optional map of dependencies which should + * be injected into the controller. If any of these dependencies are promises, they will be + * resolved and converted to a value before the controller is instantiated and the + * `$afterRouteChange` event is fired. The map object is: + * + * - `key` – `{string}`: a name of a dependency to be injected into the controller. + * - `factory` - `{string|function}`: If `string` then it is an alias for a service. + * Otherwise if function, then it is {@link api/AUTO.$injector#invoke injected} + * and the return value is treated as the dependency. If the result is a promise, it is resolved + * before its value is injected into the controller. + * + * - `redirectTo` – {(string|function())=} – value to update + * {@link ng.$location $location} path with and trigger route redirection. + * + * If `redirectTo` is a function, it will be called with the following parameters: + * + * - `{Object.}` - route parameters extracted from the current + * `$location.path()` by applying the current route templateUrl. + * - `{string}` - current `$location.path()` + * - `{Object}` - current `$location.search()` + * + * The custom `redirectTo` function is expected to return a string which will be used + * to update `$location.path()` and `$location.search()`. + * + * - `[reloadOnSearch=true]` - {boolean=} - reload route when only $location.search() + * changes. + * + * If the option is set to `false` and url in the browser changes, then + * `$routeUpdate` event is broadcasted on the root scope. + * + * @returns {Object} self + * + * @description + * Adds a new route definition to the `$route` service. + */ + this.when = function(path, route) { + routes[path] = extend({reloadOnSearch: true}, route); + + // create redirection for trailing slashes + if (path) { + var redirectPath = (path[path.length-1] == '/') + ? path.substr(0, path.length-1) + : path +'/'; + + routes[redirectPath] = {redirectTo: path}; + } + + return this; + }; + + /** + * @ngdoc method + * @name ng.$routeProvider#otherwise + * @methodOf ng.$routeProvider + * + * @description + * Sets route definition that will be used on route change when no other route definition + * is matched. + * + * @param {Object} params Mapping information to be assigned to `$route.current`. + * @returns {Object} self + */ + this.otherwise = function(params) { + this.when(null, params); + return this; + }; + + + this.$get = ['$rootScope', '$location', '$routeParams', '$q', '$injector', '$http', '$templateCache', + function( $rootScope, $location, $routeParams, $q, $injector, $http, $templateCache) { + + /** + * @ngdoc object + * @name ng.$route + * @requires $location + * @requires $routeParams + * + * @property {Object} current Reference to the current route definition. + * The route definition contains: + * + * - `controller`: The controller constructor as define in route definition. + * - `locals`: A map of locals which is used by {@link ng.$controller $controller} service for + * controller instantiation. The `locals` contain + * the resolved values of the `resolve` map. Additionally the `locals` also contain: + * + * - `$scope` - The current route scope. + * - `$template` - The current route template HTML. + * + * @property {Array.} routes Array of all configured routes. + * + * @description + * Is used for deep-linking URLs to controllers and views (HTML partials). + * It watches `$location.url()` and tries to map the path to an existing route definition. + * + * You can define routes through {@link ng.$routeProvider $routeProvider}'s API. + * + * The `$route` service is typically used in conjunction with {@link ng.directive:ngView ngView} + * directive and the {@link ng.$routeParams $routeParams} service. + * + * @example + This example shows how changing the URL hash causes the `$route` to match a route against the + URL, and the `ngView` pulls in the partial. + + Note that this example is using {@link ng.directive:script inlined templates} + to get it working on jsfiddle as well. + + + +
    + Choose: + Moby | + Moby: Ch1 | + Gatsby | + Gatsby: Ch4 | + Scarlet Letter
    + +
    +
    + +
    $location.path() = {{$location.path()}}
    +
    $route.current.templateUrl = {{$route.current.templateUrl}}
    +
    $route.current.params = {{$route.current.params}}
    +
    $route.current.scope.name = {{$route.current.scope.name}}
    +
    $routeParams = {{$routeParams}}
    +
    +
    + + + controller: {{name}}
    + Book Id: {{params.bookId}}
    +
    + + + controller: {{name}}
    + Book Id: {{params.bookId}}
    + Chapter Id: {{params.chapterId}} +
    + + + angular.module('ngView', [], function($routeProvider, $locationProvider) { + $routeProvider.when('/Book/:bookId', { + templateUrl: 'book.html', + controller: BookCntl, + resolve: { + // I will cause a 1 second delay + delay: function($q, $timeout) { + var delay = $q.defer(); + $timeout(delay.resolve, 1000); + return delay.promise; + } + } + }); + $routeProvider.when('/Book/:bookId/ch/:chapterId', { + templateUrl: 'chapter.html', + controller: ChapterCntl + }); + + // configure html5 to get links working on jsfiddle + $locationProvider.html5Mode(true); + }); + + function MainCntl($scope, $route, $routeParams, $location) { + $scope.$route = $route; + $scope.$location = $location; + $scope.$routeParams = $routeParams; + } + + function BookCntl($scope, $routeParams) { + $scope.name = "BookCntl"; + $scope.params = $routeParams; + } + + function ChapterCntl($scope, $routeParams) { + $scope.name = "ChapterCntl"; + $scope.params = $routeParams; + } + + + + it('should load and compile correct template', function() { + element('a:contains("Moby: Ch1")').click(); + var content = element('.doc-example-live [ng-view]').text(); + expect(content).toMatch(/controller\: ChapterCntl/); + expect(content).toMatch(/Book Id\: Moby/); + expect(content).toMatch(/Chapter Id\: 1/); + + element('a:contains("Scarlet")').click(); + sleep(2); // promises are not part of scenario waiting + content = element('.doc-example-live [ng-view]').text(); + expect(content).toMatch(/controller\: BookCntl/); + expect(content).toMatch(/Book Id\: Scarlet/); + }); + +
    + */ + + /** + * @ngdoc event + * @name ng.$route#$routeChangeStart + * @eventOf ng.$route + * @eventType broadcast on root scope + * @description + * Broadcasted before a route change. At this point the route services starts + * resolving all of the dependencies needed for the route change to occurs. + * Typically this involves fetching the view template as well as any dependencies + * defined in `resolve` route property. Once all of the dependencies are resolved + * `$routeChangeSuccess` is fired. + * + * @param {Route} next Future route information. + * @param {Route} current Current route information. + */ + + /** + * @ngdoc event + * @name ng.$route#$routeChangeSuccess + * @eventOf ng.$route + * @eventType broadcast on root scope + * @description + * Broadcasted after a route dependencies are resolved. + * {@link ng.directive:ngView ngView} listens for the directive + * to instantiate the controller and render the view. + * + * @param {Route} current Current route information. + * @param {Route} previous Previous route information. + */ + + /** + * @ngdoc event + * @name ng.$route#$routeChangeError + * @eventOf ng.$route + * @eventType broadcast on root scope + * @description + * Broadcasted if any of the resolve promises are rejected. + * + * @param {Route} current Current route information. + * @param {Route} previous Previous route information. + * @param {Route} rejection Rejection of the promise. Usually the error of the failed promise. + */ + + /** + * @ngdoc event + * @name ng.$route#$routeUpdate + * @eventOf ng.$route + * @eventType broadcast on root scope + * @description + * + * The `reloadOnSearch` property has been set to false, and we are reusing the same + * instance of the Controller. + */ + + var matcher = switchRouteMatcher, + forceReload = false, + $route = { + routes: routes, + + /** + * @ngdoc method + * @name ng.$route#reload + * @methodOf ng.$route + * + * @description + * Causes `$route` service to reload the current route even if + * {@link ng.$location $location} hasn't changed. + * + * As a result of that, {@link ng.directive:ngView ngView} + * creates new scope, reinstantiates the controller. + */ + reload: function() { + forceReload = true; + $rootScope.$evalAsync(updateRoute); + } + }; + + $rootScope.$on('$locationChangeSuccess', updateRoute); + + return $route; + + ///////////////////////////////////////////////////// + + function switchRouteMatcher(on, when) { + // TODO(i): this code is convoluted and inefficient, we should construct the route matching + // regex only once and then reuse it + var regex = '^' + when.replace(/([\.\\\(\)\^\$])/g, "\\$1") + '$', + params = [], + dst = {}; + forEach(when.split(/\W/), function(param) { + if (param) { + var paramRegExp = new RegExp(":" + param + "([\\W])"); + if (regex.match(paramRegExp)) { + regex = regex.replace(paramRegExp, "([^\\/]*)$1"); + params.push(param); + } + } + }); + var match = on.match(new RegExp(regex)); + if (match) { + forEach(params, function(name, index) { + dst[name] = match[index + 1]; + }); + } + return match ? dst : null; + } + + function updateRoute() { + var next = parseRoute(), + last = $route.current; + + if (next && last && next.$route === last.$route + && equals(next.pathParams, last.pathParams) && !next.reloadOnSearch && !forceReload) { + last.params = next.params; + copy(last.params, $routeParams); + $rootScope.$broadcast('$routeUpdate', last); + } else if (next || last) { + forceReload = false; + $rootScope.$broadcast('$routeChangeStart', next, last); + $route.current = next; + if (next) { + if (next.redirectTo) { + if (isString(next.redirectTo)) { + $location.path(interpolate(next.redirectTo, next.params)).search(next.params) + .replace(); + } else { + $location.url(next.redirectTo(next.pathParams, $location.path(), $location.search())) + .replace(); + } + } + } + + $q.when(next). + then(function() { + if (next) { + var keys = [], + values = [], + template; + + forEach(next.resolve || {}, function(value, key) { + keys.push(key); + values.push(isFunction(value) ? $injector.invoke(value) : $injector.get(value)); + }); + if (isDefined(template = next.template)) { + } else if (isDefined(template = next.templateUrl)) { + template = $http.get(template, {cache: $templateCache}). + then(function(response) { return response.data; }); + } + if (isDefined(template)) { + keys.push('$template'); + values.push(template); + } + return $q.all(values).then(function(values) { + var locals = {}; + forEach(values, function(value, index) { + locals[keys[index]] = value; + }); + return locals; + }); + } + }). + // after route change + then(function(locals) { + if (next == $route.current) { + if (next) { + next.locals = locals; + copy(next.params, $routeParams); + } + $rootScope.$broadcast('$routeChangeSuccess', next, last); + } + }, function(error) { + if (next == $route.current) { + $rootScope.$broadcast('$routeChangeError', next, last, error); + } + }); + } + } + + + /** + * @returns the current active route, by matching it against the URL + */ + function parseRoute() { + // Match a route + var params, match; + forEach(routes, function(route, path) { + if (!match && (params = matcher($location.path(), path))) { + match = inherit(route, { + params: extend({}, $location.search(), params), + pathParams: params}); + match.$route = route; + } + }); + // No route matched; fallback to "otherwise" route + return match || routes[null] && inherit(routes[null], {params: {}, pathParams:{}}); + } + + /** + * @returns interpolation of the redirect path with the parametrs + */ + function interpolate(string, params) { + var result = []; + forEach((string||'').split(':'), function(segment, i) { + if (i == 0) { + result.push(segment); + } else { + var segmentMatch = segment.match(/(\w+)(.*)/); + var key = segmentMatch[1]; + result.push(params[key]); + result.push(segmentMatch[2] || ''); + delete params[key]; + } + }); + return result.join(''); + } + }]; +} + +/** + * @ngdoc object + * @name ng.$routeParams + * @requires $route + * + * @description + * Current set of route parameters. The route parameters are a combination of the + * {@link ng.$location $location} `search()`, and `path()`. The `path` parameters + * are extracted when the {@link ng.$route $route} path is matched. + * + * In case of parameter name collision, `path` params take precedence over `search` params. + * + * The service guarantees that the identity of the `$routeParams` object will remain unchanged + * (but its properties will likely change) even when a route change occurs. + * + * @example + *
    + *  // Given:
    + *  // URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
    + *  // Route: /Chapter/:chapterId/Section/:sectionId
    + *  //
    + *  // Then
    + *  $routeParams ==> {chapterId:1, sectionId:2, search:'moby'}
    + * 
    + */ +function $RouteParamsProvider() { + this.$get = valueFn({}); +} + +/** + * DESIGN NOTES + * + * The design decisions behind the scope ware heavily favored for speed and memory consumption. + * + * The typical use of scope is to watch the expressions, which most of the time return the same + * value as last time so we optimize the operation. + * + * Closures construction is expensive from speed as well as memory: + * - no closures, instead ups prototypical inheritance for API + * - Internal state needs to be stored on scope directly, which means that private state is + * exposed as $$____ properties + * + * Loop operations are optimized by using while(count--) { ... } + * - this means that in order to keep the same order of execution as addition we have to add + * items to the array at the begging (shift) instead of at the end (push) + * + * Child scopes are created and removed often + * - Using array would be slow since inserts in meddle are expensive so we use linked list + * + * There are few watches then a lot of observers. This is why you don't want the observer to be + * implemented in the same way as watch. Watch requires return of initialization function which + * are expensive to construct. + */ + + +/** + * @ngdoc object + * @name ng.$rootScopeProvider + * @description + * + * Provider for the $rootScope service. + */ + +/** + * @ngdoc function + * @name ng.$rootScopeProvider#digestTtl + * @methodOf ng.$rootScopeProvider + * @description + * + * Sets the number of digest iteration the scope should attempt to execute before giving up and + * assuming that the model is unstable. + * + * The current default is 10 iterations. + * + * @param {number} limit The number of digest iterations. + */ + + +/** + * @ngdoc object + * @name ng.$rootScope + * @description + * + * Every application has a single root {@link ng.$rootScope.Scope scope}. + * All other scopes are child scopes of the root scope. Scopes provide mechanism for watching the model and provide + * event processing life-cycle. See {@link guide/scope developer guide on scopes}. + */ +function $RootScopeProvider(){ + var TTL = 10; + + this.digestTtl = function(value) { + if (arguments.length) { + TTL = value; + } + return TTL; + }; + + this.$get = ['$injector', '$exceptionHandler', '$parse', + function( $injector, $exceptionHandler, $parse) { + + /** + * @ngdoc function + * @name ng.$rootScope.Scope + * + * @description + * A root scope can be retrieved using the {@link ng.$rootScope $rootScope} key from the + * {@link AUTO.$injector $injector}. Child scopes are created using the + * {@link ng.$rootScope.Scope#$new $new()} method. (Most scopes are created automatically when + * compiled HTML template is executed.) + * + * Here is a simple scope snippet to show how you can interact with the scope. + *
    +        angular.injector(['ng']).invoke(function($rootScope) {
    +           var scope = $rootScope.$new();
    +           scope.salutation = 'Hello';
    +           scope.name = 'World';
    +
    +           expect(scope.greeting).toEqual(undefined);
    +
    +           scope.$watch('name', function() {
    +             this.greeting = this.salutation + ' ' + this.name + '!';
    +           }); // initialize the watch
    +
    +           expect(scope.greeting).toEqual(undefined);
    +           scope.name = 'Misko';
    +           // still old value, since watches have not been called yet
    +           expect(scope.greeting).toEqual(undefined);
    +
    +           scope.$digest(); // fire all  the watches
    +           expect(scope.greeting).toEqual('Hello Misko!');
    +        });
    +     * 
    + * + * # Inheritance + * A scope can inherit from a parent scope, as in this example: + *
    +         var parent = $rootScope;
    +         var child = parent.$new();
    +
    +         parent.salutation = "Hello";
    +         child.name = "World";
    +         expect(child.salutation).toEqual('Hello');
    +
    +         child.salutation = "Welcome";
    +         expect(child.salutation).toEqual('Welcome');
    +         expect(parent.salutation).toEqual('Hello');
    +     * 
    + * + * + * @param {Object.=} providers Map of service factory which need to be provided + * for the current scope. Defaults to {@link ng}. + * @param {Object.=} instanceCache Provides pre-instantiated services which should + * append/override services provided by `providers`. This is handy when unit-testing and having + * the need to override a default service. + * @returns {Object} Newly created scope. + * + */ + function Scope() { + this.$id = nextUid(); + this.$$phase = this.$parent = this.$$watchers = + this.$$nextSibling = this.$$prevSibling = + this.$$childHead = this.$$childTail = null; + this['this'] = this.$root = this; + this.$$asyncQueue = []; + this.$$listeners = {}; + } + + /** + * @ngdoc property + * @name ng.$rootScope.Scope#$id + * @propertyOf ng.$rootScope.Scope + * @returns {number} Unique scope ID (monotonically increasing alphanumeric sequence) useful for + * debugging. + */ + + + Scope.prototype = { + /** + * @ngdoc function + * @name ng.$rootScope.Scope#$new + * @methodOf ng.$rootScope.Scope + * @function + * + * @description + * Creates a new child {@link ng.$rootScope.Scope scope}. + * + * The parent scope will propagate the {@link ng.$rootScope.Scope#$digest $digest()} and + * {@link ng.$rootScope.Scope#$digest $digest()} events. The scope can be removed from the scope + * hierarchy using {@link ng.$rootScope.Scope#$destroy $destroy()}. + * + * {@link ng.$rootScope.Scope#$destroy $destroy()} must be called on a scope when it is desired for + * the scope and its child scopes to be permanently detached from the parent and thus stop + * participating in model change detection and listener notification by invoking. + * + * @param {boolean} isolate if true then the scoped does not prototypically inherit from the + * parent scope. The scope is isolated, as it can not se parent scope properties. + * When creating widgets it is useful for the widget to not accidently read parent + * state. + * + * @returns {Object} The newly created child scope. + * + */ + $new: function(isolate) { + var Child, + child; + + if (isFunction(isolate)) { + // TODO: remove at some point + throw Error('API-CHANGE: Use $controller to instantiate controllers.'); + } + if (isolate) { + child = new Scope(); + child.$root = this.$root; + } else { + Child = function() {}; // should be anonymous; This is so that when the minifier munges + // the name it does not become random set of chars. These will then show up as class + // name in the debugger. + Child.prototype = this; + child = new Child(); + child.$id = nextUid(); + } + child['this'] = child; + child.$$listeners = {}; + child.$parent = this; + child.$$asyncQueue = []; + child.$$watchers = child.$$nextSibling = child.$$childHead = child.$$childTail = null; + child.$$prevSibling = this.$$childTail; + if (this.$$childHead) { + this.$$childTail.$$nextSibling = child; + this.$$childTail = child; + } else { + this.$$childHead = this.$$childTail = child; + } + return child; + }, + + /** + * @ngdoc function + * @name ng.$rootScope.Scope#$watch + * @methodOf ng.$rootScope.Scope + * @function + * + * @description + * Registers a `listener` callback to be executed whenever the `watchExpression` changes. + * + * - The `watchExpression` is called on every call to {@link ng.$rootScope.Scope#$digest $digest()} and + * should return the value which will be watched. (Since {@link ng.$rootScope.Scope#$digest $digest()} + * reruns when it detects changes the `watchExpression` can execute multiple times per + * {@link ng.$rootScope.Scope#$digest $digest()} and should be idempotent.) + * - The `listener` is called only when the value from the current `watchExpression` and the + * previous call to `watchExpression' are not equal (with the exception of the initial run + * see below). The inequality is determined according to + * {@link angular.equals} function. To save the value of the object for later comparison + * {@link angular.copy} function is used. It also means that watching complex options will + * have adverse memory and performance implications. + * - The watch `listener` may change the model, which may trigger other `listener`s to fire. This + * is achieved by rerunning the watchers until no changes are detected. The rerun iteration + * limit is 100 to prevent infinity loop deadlock. + * + * + * If you want to be notified whenever {@link ng.$rootScope.Scope#$digest $digest} is called, + * you can register an `watchExpression` function with no `listener`. (Since `watchExpression`, + * can execute multiple times per {@link ng.$rootScope.Scope#$digest $digest} cycle when a change is + * detected, be prepared for multiple calls to your listener.) + * + * After a watcher is registered with the scope, the `listener` fn is called asynchronously + * (via {@link ng.$rootScope.Scope#$evalAsync $evalAsync}) to initialize the + * watcher. In rare cases, this is undesirable because the listener is called when the result + * of `watchExpression` didn't change. To detect this scenario within the `listener` fn, you + * can compare the `newVal` and `oldVal`. If these two values are identical (`===`) then the + * listener was called due to initialization. + * + * + * # Example + *
    +           // let's assume that scope was dependency injected as the $rootScope
    +           var scope = $rootScope;
    +           scope.name = 'misko';
    +           scope.counter = 0;
    +
    +           expect(scope.counter).toEqual(0);
    +           scope.$watch('name', function(newValue, oldValue) { counter = counter + 1; });
    +           expect(scope.counter).toEqual(0);
    +
    +           scope.$digest();
    +           // no variable change
    +           expect(scope.counter).toEqual(0);
    +
    +           scope.name = 'adam';
    +           scope.$digest();
    +           expect(scope.counter).toEqual(1);
    +       * 
    + * + * + * + * @param {(function()|string)} watchExpression Expression that is evaluated on each + * {@link ng.$rootScope.Scope#$digest $digest} cycle. A change in the return value triggers a + * call to the `listener`. + * + * - `string`: Evaluated as {@link guide/expression expression} + * - `function(scope)`: called with current `scope` as a parameter. + * @param {(function()|string)=} listener Callback called whenever the return value of + * the `watchExpression` changes. + * + * - `string`: Evaluated as {@link guide/expression expression} + * - `function(newValue, oldValue, scope)`: called with current and previous values as parameters. + * + * @param {boolean=} objectEquality Compare object for equality rather then for refference. + * @returns {function()} Returns a deregistration function for this listener. + */ + $watch: function(watchExp, listener, objectEquality) { + var scope = this, + get = compileToFn(watchExp, 'watch'), + array = scope.$$watchers, + watcher = { + fn: listener, + last: initWatchVal, + get: get, + exp: watchExp, + eq: !!objectEquality + }; + + // in the case user pass string, we need to compile it, do we really need this ? + if (!isFunction(listener)) { + var listenFn = compileToFn(listener || noop, 'listener'); + watcher.fn = function(newVal, oldVal, scope) {listenFn(scope);}; + } + + if (!array) { + array = scope.$$watchers = []; + } + // we use unshift since we use a while loop in $digest for speed. + // the while loop reads in reverse order. + array.unshift(watcher); + + return function() { + arrayRemove(array, watcher); + }; + }, + + /** + * @ngdoc function + * @name ng.$rootScope.Scope#$digest + * @methodOf ng.$rootScope.Scope + * @function + * + * @description + * Process all of the {@link ng.$rootScope.Scope#$watch watchers} of the current scope and its children. + * Because a {@link ng.$rootScope.Scope#$watch watcher}'s listener can change the model, the + * `$digest()` keeps calling the {@link ng.$rootScope.Scope#$watch watchers} until no more listeners are + * firing. This means that it is possible to get into an infinite loop. This function will throw + * `'Maximum iteration limit exceeded.'` if the number of iterations exceeds 10. + * + * Usually you don't call `$digest()` directly in + * {@link ng.directive:ngController controllers} or in + * {@link ng.$compileProvider#directive directives}. + * Instead a call to {@link ng.$rootScope.Scope#$apply $apply()} (typically from within a + * {@link ng.$compileProvider#directive directives}) will force a `$digest()`. + * + * If you want to be notified whenever `$digest()` is called, + * you can register a `watchExpression` function with {@link ng.$rootScope.Scope#$watch $watch()} + * with no `listener`. + * + * You may have a need to call `$digest()` from within unit-tests, to simulate the scope + * life-cycle. + * + * # Example + *
    +           var scope = ...;
    +           scope.name = 'misko';
    +           scope.counter = 0;
    +
    +           expect(scope.counter).toEqual(0);
    +           scope.$watch('name', function(newValue, oldValue) {
    +             counter = counter + 1;
    +           });
    +           expect(scope.counter).toEqual(0);
    +
    +           scope.$digest();
    +           // no variable change
    +           expect(scope.counter).toEqual(0);
    +
    +           scope.name = 'adam';
    +           scope.$digest();
    +           expect(scope.counter).toEqual(1);
    +       * 
    + * + */ + $digest: function() { + var watch, value, last, + watchers, + asyncQueue, + length, + dirty, ttl = TTL, + next, current, target = this, + watchLog = [], + logIdx, logMsg; + + beginPhase('$digest'); + + do { + dirty = false; + current = target; + do { + asyncQueue = current.$$asyncQueue; + while(asyncQueue.length) { + try { + current.$eval(asyncQueue.shift()); + } catch (e) { + $exceptionHandler(e); + } + } + if ((watchers = current.$$watchers)) { + // process our watches + length = watchers.length; + while (length--) { + try { + watch = watchers[length]; + // Most common watches are on primitives, in which case we can short + // circuit it with === operator, only when === fails do we use .equals + if ((value = watch.get(current)) !== (last = watch.last) && + !(watch.eq + ? equals(value, last) + : (typeof value == 'number' && typeof last == 'number' + && isNaN(value) && isNaN(last)))) { + dirty = true; + watch.last = watch.eq ? copy(value) : value; + watch.fn(value, ((last === initWatchVal) ? value : last), current); + if (ttl < 5) { + logIdx = 4 - ttl; + if (!watchLog[logIdx]) watchLog[logIdx] = []; + logMsg = (isFunction(watch.exp)) + ? 'fn: ' + (watch.exp.name || watch.exp.toString()) + : watch.exp; + logMsg += '; newVal: ' + toJson(value) + '; oldVal: ' + toJson(last); + watchLog[logIdx].push(logMsg); + } + } + } catch (e) { + $exceptionHandler(e); + } + } + } + + // Insanity Warning: scope depth-first traversal + // yes, this code is a bit crazy, but it works and we have tests to prove it! + // this piece should be kept in sync with the traversal in $broadcast + if (!(next = (current.$$childHead || (current !== target && current.$$nextSibling)))) { + while(current !== target && !(next = current.$$nextSibling)) { + current = current.$parent; + } + } + } while ((current = next)); + + if(dirty && !(ttl--)) { + clearPhase(); + throw Error(TTL + ' $digest() iterations reached. Aborting!\n' + + 'Watchers fired in the last 5 iterations: ' + toJson(watchLog)); + } + } while (dirty || asyncQueue.length); + + clearPhase(); + }, + + + /** + * @ngdoc event + * @name ng.$rootScope.Scope#$destroy + * @eventOf ng.$rootScope.Scope + * @eventType broadcast on scope being destroyed + * + * @description + * Broadcasted when a scope and its children are being destroyed. + */ + + /** + * @ngdoc function + * @name ng.$rootScope.Scope#$destroy + * @methodOf ng.$rootScope.Scope + * @function + * + * @description + * Remove the current scope (and all of its children) from the parent scope. Removal implies + * that calls to {@link ng.$rootScope.Scope#$digest $digest()} will no longer + * propagate to the current scope and its children. Removal also implies that the current + * scope is eligible for garbage collection. + * + * The `$destroy()` is usually used by directives such as + * {@link ng.directive:ngRepeat ngRepeat} for managing the + * unrolling of the loop. + * + * Just before a scope is destroyed a `$destroy` event is broadcasted on this scope. + * Application code can register a `$destroy` event handler that will give it chance to + * perform any necessary cleanup. + */ + $destroy: function() { + if ($rootScope == this) return; // we can't remove the root node; + var parent = this.$parent; + + this.$broadcast('$destroy'); + + if (parent.$$childHead == this) parent.$$childHead = this.$$nextSibling; + if (parent.$$childTail == this) parent.$$childTail = this.$$prevSibling; + if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling; + if (this.$$nextSibling) this.$$nextSibling.$$prevSibling = this.$$prevSibling; + }, + + /** + * @ngdoc function + * @name ng.$rootScope.Scope#$eval + * @methodOf ng.$rootScope.Scope + * @function + * + * @description + * Executes the `expression` on the current scope returning the result. Any exceptions in the + * expression are propagated (uncaught). This is useful when evaluating engular expressions. + * + * # Example + *
    +           var scope = ng.$rootScope.Scope();
    +           scope.a = 1;
    +           scope.b = 2;
    +
    +           expect(scope.$eval('a+b')).toEqual(3);
    +           expect(scope.$eval(function(scope){ return scope.a + scope.b; })).toEqual(3);
    +       * 
    + * + * @param {(string|function())=} expression An angular expression to be executed. + * + * - `string`: execute using the rules as defined in {@link guide/expression expression}. + * - `function(scope)`: execute the function with the current `scope` parameter. + * + * @returns {*} The result of evaluating the expression. + */ + $eval: function(expr, locals) { + return $parse(expr)(this, locals); + }, + + /** + * @ngdoc function + * @name ng.$rootScope.Scope#$evalAsync + * @methodOf ng.$rootScope.Scope + * @function + * + * @description + * Executes the expression on the current scope at a later point in time. + * + * The `$evalAsync` makes no guarantees as to when the `expression` will be executed, only that: + * + * - it will execute in the current script execution context (before any DOM rendering). + * - at least one {@link ng.$rootScope.Scope#$digest $digest cycle} will be performed after + * `expression` execution. + * + * Any exceptions from the execution of the expression are forwarded to the + * {@link ng.$exceptionHandler $exceptionHandler} service. + * + * @param {(string|function())=} expression An angular expression to be executed. + * + * - `string`: execute using the rules as defined in {@link guide/expression expression}. + * - `function(scope)`: execute the function with the current `scope` parameter. + * + */ + $evalAsync: function(expr) { + this.$$asyncQueue.push(expr); + }, + + /** + * @ngdoc function + * @name ng.$rootScope.Scope#$apply + * @methodOf ng.$rootScope.Scope + * @function + * + * @description + * `$apply()` is used to execute an expression in angular from outside of the angular framework. + * (For example from browser DOM events, setTimeout, XHR or third party libraries). + * Because we are calling into the angular framework we need to perform proper scope life-cycle + * of {@link ng.$exceptionHandler exception handling}, + * {@link ng.$rootScope.Scope#$digest executing watches}. + * + * ## Life cycle + * + * # Pseudo-Code of `$apply()` + *
    +           function $apply(expr) {
    +             try {
    +               return $eval(expr);
    +             } catch (e) {
    +               $exceptionHandler(e);
    +             } finally {
    +               $root.$digest();
    +             }
    +           }
    +       * 
    + * + * + * Scope's `$apply()` method transitions through the following stages: + * + * 1. The {@link guide/expression expression} is executed using the + * {@link ng.$rootScope.Scope#$eval $eval()} method. + * 2. Any exceptions from the execution of the expression are forwarded to the + * {@link ng.$exceptionHandler $exceptionHandler} service. + * 3. The {@link ng.$rootScope.Scope#$watch watch} listeners are fired immediately after the expression + * was executed using the {@link ng.$rootScope.Scope#$digest $digest()} method. + * + * + * @param {(string|function())=} exp An angular expression to be executed. + * + * - `string`: execute using the rules as defined in {@link guide/expression expression}. + * - `function(scope)`: execute the function with current `scope` parameter. + * + * @returns {*} The result of evaluating the expression. + */ + $apply: function(expr) { + try { + beginPhase('$apply'); + return this.$eval(expr); + } catch (e) { + $exceptionHandler(e); + } finally { + clearPhase(); + try { + $rootScope.$digest(); + } catch (e) { + $exceptionHandler(e); + throw e; + } + } + }, + + /** + * @ngdoc function + * @name ng.$rootScope.Scope#$on + * @methodOf ng.$rootScope.Scope + * @function + * + * @description + * Listen on events of a given type. See {@link ng.$rootScope.Scope#$emit $emit} for discussion of + * event life cycle. + * + * @param {string} name Event name to listen on. + * @param {function(event)} listener Function to call when the event is emitted. + * @returns {function()} Returns a deregistration function for this listener. + * + * The event listener function format is: `function(event, args...)`. The `event` object + * passed into the listener has the following attributes: + * + * - `targetScope` - {Scope}: the scope on which the event was `$emit`-ed or `$broadcast`-ed. + * - `currentScope` - {Scope}: the current scope which is handling the event. + * - `name` - {string}: Name of the event. + * - `stopPropagation` - {function=}: calling `stopPropagation` function will cancel further event propagation + * (available only for events that were `$emit`-ed). + * - `preventDefault` - {function}: calling `preventDefault` sets `defaultPrevented` flag to true. + * - `defaultPrevented` - {boolean}: true if `preventDefault` was called. + */ + $on: function(name, listener) { + var namedListeners = this.$$listeners[name]; + if (!namedListeners) { + this.$$listeners[name] = namedListeners = []; + } + namedListeners.push(listener); + + return function() { + arrayRemove(namedListeners, listener); + }; + }, + + + /** + * @ngdoc function + * @name ng.$rootScope.Scope#$emit + * @methodOf ng.$rootScope.Scope + * @function + * + * @description + * Dispatches an event `name` upwards through the scope hierarchy notifying the + * registered {@link ng.$rootScope.Scope#$on} listeners. + * + * The event life cycle starts at the scope on which `$emit` was called. All + * {@link ng.$rootScope.Scope#$on listeners} listening for `name` event on this scope get notified. + * Afterwards, the event traverses upwards toward the root scope and calls all registered + * listeners along the way. The event will stop propagating if one of the listeners cancels it. + * + * Any exception emmited from the {@link ng.$rootScope.Scope#$on listeners} will be passed + * onto the {@link ng.$exceptionHandler $exceptionHandler} service. + * + * @param {string} name Event name to emit. + * @param {...*} args Optional set of arguments which will be passed onto the event listeners. + * @return {Object} Event object, see {@link ng.$rootScope.Scope#$on} + */ + $emit: function(name, args) { + var empty = [], + namedListeners, + scope = this, + stopPropagation = false, + event = { + name: name, + targetScope: scope, + stopPropagation: function() {stopPropagation = true;}, + preventDefault: function() { + event.defaultPrevented = true; + }, + defaultPrevented: false + }, + listenerArgs = concat([event], arguments, 1), + i, length; + + do { + namedListeners = scope.$$listeners[name] || empty; + event.currentScope = scope; + for (i=0, length=namedListeners.length; i 7), + hasEvent: function(event) { + // IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have + // it. In particular the event is not fired when backspace or delete key are pressed or + // when cut operation is performed. + if (event == 'input' && msie == 9) return false; + + if (isUndefined(eventSupport[event])) { + var divElm = $window.document.createElement('div'); + eventSupport[event] = 'on' + event in divElm; + } + + return eventSupport[event]; + }, + // TODO(i): currently there is no way to feature detect CSP without triggering alerts + csp: false + }; + }]; +} + +/** + * @ngdoc object + * @name ng.$window + * + * @description + * A reference to the browser's `window` object. While `window` + * is globally available in JavaScript, it causes testability problems, because + * it is a global variable. In angular we always refer to it through the + * `$window` service, so it may be overriden, removed or mocked for testing. + * + * All expressions are evaluated with respect to current scope so they don't + * suffer from window globality. + * + * @example + + + + + + + + + */ +function $WindowProvider(){ + this.$get = valueFn(window); +} + +/** + * Parse headers into key value object + * + * @param {string} headers Raw headers as a string + * @returns {Object} Parsed headers as key value object + */ +function parseHeaders(headers) { + var parsed = {}, key, val, i; + + if (!headers) return parsed; + + forEach(headers.split('\n'), function(line) { + i = line.indexOf(':'); + key = lowercase(trim(line.substr(0, i))); + val = trim(line.substr(i + 1)); + + if (key) { + if (parsed[key]) { + parsed[key] += ', ' + val; + } else { + parsed[key] = val; + } + } + }); + + return parsed; +} + + +/** + * Returns a function that provides access to parsed headers. + * + * Headers are lazy parsed when first requested. + * @see parseHeaders + * + * @param {(string|Object)} headers Headers to provide access to. + * @returns {function(string=)} Returns a getter function which if called with: + * + * - if called with single an argument returns a single header value or null + * - if called with no arguments returns an object containing all headers. + */ +function headersGetter(headers) { + var headersObj = isObject(headers) ? headers : undefined; + + return function(name) { + if (!headersObj) headersObj = parseHeaders(headers); + + if (name) { + return headersObj[lowercase(name)] || null; + } + + return headersObj; + }; +} + + +/** + * Chain all given functions + * + * This function is used for both request and response transforming + * + * @param {*} data Data to transform. + * @param {function(string=)} headers Http headers getter fn. + * @param {(function|Array.)} fns Function or an array of functions. + * @returns {*} Transformed data. + */ +function transformData(data, headers, fns) { + if (isFunction(fns)) + return fns(data, headers); + + forEach(fns, function(fn) { + data = fn(data, headers); + }); + + return data; +} + + +function isSuccess(status) { + return 200 <= status && status < 300; +} + + +function $HttpProvider() { + var JSON_START = /^\s*(\[|\{[^\{])/, + JSON_END = /[\}\]]\s*$/, + PROTECTION_PREFIX = /^\)\]\}',?\n/; + + var $config = this.defaults = { + // transform incoming response data + transformResponse: [function(data) { + if (isString(data)) { + // strip json vulnerability protection prefix + data = data.replace(PROTECTION_PREFIX, ''); + if (JSON_START.test(data) && JSON_END.test(data)) + data = fromJson(data, true); + } + return data; + }], + + // transform outgoing request data + transformRequest: [function(d) { + return isObject(d) && !isFile(d) ? toJson(d) : d; + }], + + // default headers + headers: { + common: { + 'Accept': 'application/json, text/plain, */*', + 'X-Requested-With': 'XMLHttpRequest' + }, + post: {'Content-Type': 'application/json;charset=utf-8'}, + put: {'Content-Type': 'application/json;charset=utf-8'} + } + }; + + var providerResponseInterceptors = this.responseInterceptors = []; + + this.$get = ['$httpBackend', '$browser', '$cacheFactory', '$rootScope', '$q', '$injector', + function($httpBackend, $browser, $cacheFactory, $rootScope, $q, $injector) { + + var defaultCache = $cacheFactory('$http'), + responseInterceptors = []; + + forEach(providerResponseInterceptors, function(interceptor) { + responseInterceptors.push( + isString(interceptor) + ? $injector.get(interceptor) + : $injector.invoke(interceptor) + ); + }); + + + /** + * @ngdoc function + * @name ng.$http + * @requires $httpBacked + * @requires $browser + * @requires $cacheFactory + * @requires $rootScope + * @requires $q + * @requires $injector + * + * @description + * The `$http` service is a core Angular service that facilitates communication with the remote + * HTTP servers via browser's {@link https://developer.mozilla.org/en/xmlhttprequest + * XMLHttpRequest} object or via {@link http://en.wikipedia.org/wiki/JSONP JSONP}. + * + * For unit testing applications that use `$http` service, see + * {@link ngMock.$httpBackend $httpBackend mock}. + * + * For a higher level of abstraction, please check out the {@link ngResource.$resource + * $resource} service. + * + * The $http API is based on the {@link ng.$q deferred/promise APIs} exposed by + * the $q service. While for simple usage patters this doesn't matter much, for advanced usage, + * it is important to familiarize yourself with these apis and guarantees they provide. + * + * + * # General usage + * The `$http` service is a function which takes a single argument — a configuration object — + * that is used to generate an http request and returns a {@link ng.$q promise} + * with two $http specific methods: `success` and `error`. + * + *
    +     *   $http({method: 'GET', url: '/someUrl'}).
    +     *     success(function(data, status, headers, config) {
    +     *       // this callback will be called asynchronously
    +     *       // when the response is available
    +     *     }).
    +     *     error(function(data, status, headers, config) {
    +     *       // called asynchronously if an error occurs
    +     *       // or server returns response with status
    +     *       // code outside of the <200, 400) range
    +     *     });
    +     * 
    + * + * Since the returned value of calling the $http function is a Promise object, you can also use + * the `then` method to register callbacks, and these callbacks will receive a single argument – + * an object representing the response. See the api signature and type info below for more + * details. + * + * + * # Shortcut methods + * + * Since all invocation of the $http service require definition of the http method and url and + * POST and PUT requests require response body/data to be provided as well, shortcut methods + * were created to simplify using the api: + * + *
    +     *   $http.get('/someUrl').success(successCallback);
    +     *   $http.post('/someUrl', data).success(successCallback);
    +     * 
    + * + * Complete list of shortcut methods: + * + * - {@link ng.$http#get $http.get} + * - {@link ng.$http#head $http.head} + * - {@link ng.$http#post $http.post} + * - {@link ng.$http#put $http.put} + * - {@link ng.$http#delete $http.delete} + * - {@link ng.$http#jsonp $http.jsonp} + * + * + * # Setting HTTP Headers + * + * The $http service will automatically add certain http headers to all requests. These defaults + * can be fully configured by accessing the `$httpProvider.defaults.headers` configuration + * object, which currently contains this default configuration: + * + * - `$httpProvider.defaults.headers.common` (headers that are common for all requests): + * - `Accept: application/json, text/plain, * / *` + * - `X-Requested-With: XMLHttpRequest` + * - `$httpProvider.defaults.headers.post`: (header defaults for HTTP POST requests) + * - `Content-Type: application/json` + * - `$httpProvider.defaults.headers.put` (header defaults for HTTP PUT requests) + * - `Content-Type: application/json` + * + * To add or overwrite these defaults, simply add or remove a property from this configuration + * objects. To add headers for an HTTP method other than POST or PUT, simply add a new object + * with name equal to the lower-cased http method name, e.g. + * `$httpProvider.defaults.headers.get['My-Header']='value'`. + * + * Additionally, the defaults can be set at runtime via the `$http.defaults` object in a similar + * fassion as described above. + * + * + * # Transforming Requests and Responses + * + * Both requests and responses can be transformed using transform functions. By default, Angular + * applies these transformations: + * + * Request transformations: + * + * - if the `data` property of the request config object contains an object, serialize it into + * JSON format. + * + * Response transformations: + * + * - if XSRF prefix is detected, strip it (see Security Considerations section below) + * - if json response is detected, deserialize it using a JSON parser + * + * To override these transformation locally, specify transform functions as `transformRequest` + * and/or `transformResponse` properties of the config object. To globally override the default + * transforms, override the `$httpProvider.defaults.transformRequest` and + * `$httpProvider.defaults.transformResponse` properties of the `$httpProvider`. + * + * + * # Caching + * + * To enable caching set the configuration property `cache` to `true`. When the cache is + * enabled, `$http` stores the response from the server in local cache. Next time the + * response is served from the cache without sending a request to the server. + * + * Note that even if the response is served from cache, delivery of the data is asynchronous in + * the same way that real requests are. + * + * If there are multiple GET requests for the same url that should be cached using the same + * cache, but the cache is not populated yet, only one request to the server will be made and + * the remaining requests will be fulfilled using the response for the first request. + * + * + * # Response interceptors + * + * Before you start creating interceptors, be sure to understand the + * {@link ng.$q $q and deferred/promise APIs}. + * + * For purposes of global error handling, authentication or any kind of synchronous or + * asynchronous preprocessing of received responses, it is desirable to be able to intercept + * responses for http requests before they are handed over to the application code that + * initiated these requests. The response interceptors leverage the {@link ng.$q + * promise apis} to fulfil this need for both synchronous and asynchronous preprocessing. + * + * The interceptors are service factories that are registered with the $httpProvider by + * adding them to the `$httpProvider.responseInterceptors` array. The factory is called and + * injected with dependencies (if specified) and returns the interceptor — a function that + * takes a {@link ng.$q promise} and returns the original or a new promise. + * + *
    +     *   // register the interceptor as a service
    +     *   $provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {
    +     *     return function(promise) {
    +     *       return promise.then(function(response) {
    +     *         // do something on success
    +     *       }, function(response) {
    +     *         // do something on error
    +     *         if (canRecover(response)) {
    +     *           return responseOrNewPromise
    +     *         }
    +     *         return $q.reject(response);
    +     *       });
    +     *     }
    +     *   });
    +     *
    +     *   $httpProvider.responseInterceptors.push('myHttpInterceptor');
    +     *
    +     *
    +     *   // register the interceptor via an anonymous factory
    +     *   $httpProvider.responseInterceptors.push(function($q, dependency1, dependency2) {
    +     *     return function(promise) {
    +     *       // same as above
    +     *     }
    +     *   });
    +     * 
    + * + * + * # Security Considerations + * + * When designing web applications, consider security threats from: + * + * - {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx + * JSON Vulnerability} + * - {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF} + * + * Both server and the client must cooperate in order to eliminate these threats. Angular comes + * pre-configured with strategies that address these issues, but for this to work backend server + * cooperation is required. + * + * ## JSON Vulnerability Protection + * + * A {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx + * JSON Vulnerability} allows third party web-site to turn your JSON resource URL into + * {@link http://en.wikipedia.org/wiki/JSON#JSONP JSONP} request under some conditions. To + * counter this your server can prefix all JSON requests with following string `")]}',\n"`. + * Angular will automatically strip the prefix before processing it as JSON. + * + * For example if your server needs to return: + *
    +     * ['one','two']
    +     * 
    + * + * which is vulnerable to attack, your server can return: + *
    +     * )]}',
    +     * ['one','two']
    +     * 
    + * + * Angular will strip the prefix, before processing the JSON. + * + * + * ## Cross Site Request Forgery (XSRF) Protection + * + * {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF} is a technique by which + * an unauthorized site can gain your user's private data. Angular provides following mechanism + * to counter XSRF. When performing XHR requests, the $http service reads a token from a cookie + * called `XSRF-TOKEN` and sets it as the HTTP header `X-XSRF-TOKEN`. Since only JavaScript that + * runs on your domain could read the cookie, your server can be assured that the XHR came from + * JavaScript running on your domain. + * + * To take advantage of this, your server needs to set a token in a JavaScript readable session + * cookie called `XSRF-TOKEN` on first HTTP GET request. On subsequent non-GET requests the + * server can verify that the cookie matches `X-XSRF-TOKEN` HTTP header, and therefore be sure + * that only JavaScript running on your domain could have read the token. The token must be + * unique for each user and must be verifiable by the server (to prevent the JavaScript making + * up its own tokens). We recommend that the token is a digest of your site's authentication + * cookie with {@link http://en.wikipedia.org/wiki/Rainbow_table salt for added security}. + * + * + * @param {object} config Object describing the request to be made and how it should be + * processed. The object has following properties: + * + * - **method** – `{string}` – HTTP method (e.g. 'GET', 'POST', etc) + * - **url** – `{string}` – Absolute or relative URL of the resource that is being requested. + * - **params** – `{Object.}` – Map of strings or objects which will be turned to + * `?key1=value1&key2=value2` after the url. If the value is not a string, it will be JSONified. + * - **data** – `{string|Object}` – Data to be sent as the request message data. + * - **headers** – `{Object}` – Map of strings representing HTTP headers to send to the server. + * - **transformRequest** – `{function(data, headersGetter)|Array.}` – + * transform function or an array of such functions. The transform function takes the http + * request body and headers and returns its transformed (typically serialized) version. + * - **transformResponse** – `{function(data, headersGetter)|Array.}` – + * transform function or an array of such functions. The transform function takes the http + * response body and headers and returns its transformed (typically deserialized) version. + * - **cache** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the + * GET request, otherwise if a cache instance built with + * {@link ng.$cacheFactory $cacheFactory}, this cache will be used for + * caching. + * - **timeout** – `{number}` – timeout in milliseconds. + * - **withCredentials** - `{boolean}` - whether to to set the `withCredentials` flag on the + * XHR object. See {@link https://developer.mozilla.org/en/http_access_control#section_5 + * requests with credentials} for more information. + * + * @returns {HttpPromise} Returns a {@link ng.$q promise} object with the + * standard `then` method and two http specific methods: `success` and `error`. The `then` + * method takes two arguments a success and an error callback which will be called with a + * response object. The `success` and `error` methods take a single argument - a function that + * will be called when the request succeeds or fails respectively. The arguments passed into + * these functions are destructured representation of the response object passed into the + * `then` method. The response object has these properties: + * + * - **data** – `{string|Object}` – The response body transformed with the transform functions. + * - **status** – `{number}` – HTTP status code of the response. + * - **headers** – `{function([headerName])}` – Header getter function. + * - **config** – `{Object}` – The configuration object that was used to generate the request. + * + * @property {Array.} pendingRequests Array of config objects for currently pending + * requests. This is primarily meant to be used for debugging purposes. + * + * + * @example + + +
    + + +
    + + + +
    http status code: {{status}}
    +
    http response data: {{data}}
    +
    +
    + + function FetchCtrl($scope, $http, $templateCache) { + $scope.method = 'GET'; + $scope.url = 'http-hello.html'; + + $scope.fetch = function() { + $scope.code = null; + $scope.response = null; + + $http({method: $scope.method, url: $scope.url, cache: $templateCache}). + success(function(data, status) { + $scope.status = status; + $scope.data = data; + }). + error(function(data, status) { + $scope.data = data || "Request failed"; + $scope.status = status; + }); + }; + + $scope.updateModel = function(method, url) { + $scope.method = method; + $scope.url = url; + }; + } + + + Hello, $http! + + + it('should make an xhr GET request', function() { + element(':button:contains("Sample GET")').click(); + element(':button:contains("fetch")').click(); + expect(binding('status')).toBe('200'); + expect(binding('data')).toMatch(/Hello, \$http!/); + }); + + it('should make a JSONP request to angularjs.org', function() { + element(':button:contains("Sample JSONP")').click(); + element(':button:contains("fetch")').click(); + expect(binding('status')).toBe('200'); + expect(binding('data')).toMatch(/Super Hero!/); + }); + + it('should make JSONP request to invalid URL and invoke the error handler', + function() { + element(':button:contains("Invalid JSONP")').click(); + element(':button:contains("fetch")').click(); + expect(binding('status')).toBe('0'); + expect(binding('data')).toBe('Request failed'); + }); + +
    + */ + function $http(config) { + config.method = uppercase(config.method); + + var reqTransformFn = config.transformRequest || $config.transformRequest, + respTransformFn = config.transformResponse || $config.transformResponse, + defHeaders = $config.headers, + reqHeaders = extend({'X-XSRF-TOKEN': $browser.cookies()['XSRF-TOKEN']}, + defHeaders.common, defHeaders[lowercase(config.method)], config.headers), + reqData = transformData(config.data, headersGetter(reqHeaders), reqTransformFn), + promise; + + // strip content-type if data is undefined + if (isUndefined(config.data)) { + delete reqHeaders['Content-Type']; + } + + // send request + promise = sendReq(config, reqData, reqHeaders); + + + // transform future response + promise = promise.then(transformResponse, transformResponse); + + // apply interceptors + forEach(responseInterceptors, function(interceptor) { + promise = interceptor(promise); + }); + + promise.success = function(fn) { + promise.then(function(response) { + fn(response.data, response.status, response.headers, config); + }); + return promise; + }; + + promise.error = function(fn) { + promise.then(null, function(response) { + fn(response.data, response.status, response.headers, config); + }); + return promise; + }; + + return promise; + + function transformResponse(response) { + // make a copy since the response must be cacheable + var resp = extend({}, response, { + data: transformData(response.data, response.headers, respTransformFn) + }); + return (isSuccess(response.status)) + ? resp + : $q.reject(resp); + } + } + + $http.pendingRequests = []; + + /** + * @ngdoc method + * @name ng.$http#get + * @methodOf ng.$http + * + * @description + * Shortcut method to perform `GET` request + * + * @param {string} url Relative or absolute URL specifying the destination of the request + * @param {Object=} config Optional configuration object + * @returns {HttpPromise} Future object + */ + + /** + * @ngdoc method + * @name ng.$http#delete + * @methodOf ng.$http + * + * @description + * Shortcut method to perform `DELETE` request + * + * @param {string} url Relative or absolute URL specifying the destination of the request + * @param {Object=} config Optional configuration object + * @returns {HttpPromise} Future object + */ + + /** + * @ngdoc method + * @name ng.$http#head + * @methodOf ng.$http + * + * @description + * Shortcut method to perform `HEAD` request + * + * @param {string} url Relative or absolute URL specifying the destination of the request + * @param {Object=} config Optional configuration object + * @returns {HttpPromise} Future object + */ + + /** + * @ngdoc method + * @name ng.$http#jsonp + * @methodOf ng.$http + * + * @description + * Shortcut method to perform `JSONP` request + * + * @param {string} url Relative or absolute URL specifying the destination of the request. + * Should contain `JSON_CALLBACK` string. + * @param {Object=} config Optional configuration object + * @returns {HttpPromise} Future object + */ + createShortMethods('get', 'delete', 'head', 'jsonp'); + + /** + * @ngdoc method + * @name ng.$http#post + * @methodOf ng.$http + * + * @description + * Shortcut method to perform `POST` request + * + * @param {string} url Relative or absolute URL specifying the destination of the request + * @param {*} data Request content + * @param {Object=} config Optional configuration object + * @returns {HttpPromise} Future object + */ + + /** + * @ngdoc method + * @name ng.$http#put + * @methodOf ng.$http + * + * @description + * Shortcut method to perform `PUT` request + * + * @param {string} url Relative or absolute URL specifying the destination of the request + * @param {*} data Request content + * @param {Object=} config Optional configuration object + * @returns {HttpPromise} Future object + */ + createShortMethodsWithData('post', 'put'); + + /** + * @ngdoc property + * @name ng.$http#defaults + * @propertyOf ng.$http + * + * @description + * Runtime equivalent of the `$httpProvider.defaults` property. Allows configuration of + * default headers as well as request and response transformations. + * + * See "Setting HTTP Headers" and "Transforming Requests and Responses" sections above. + */ + $http.defaults = $config; + + + return $http; + + + function createShortMethods(names) { + forEach(arguments, function(name) { + $http[name] = function(url, config) { + return $http(extend(config || {}, { + method: name, + url: url + })); + }; + }); + } + + + function createShortMethodsWithData(name) { + forEach(arguments, function(name) { + $http[name] = function(url, data, config) { + return $http(extend(config || {}, { + method: name, + url: url, + data: data + })); + }; + }); + } + + + /** + * Makes the request + * + * !!! ACCESSES CLOSURE VARS: + * $httpBackend, $config, $log, $rootScope, defaultCache, $http.pendingRequests + */ + function sendReq(config, reqData, reqHeaders) { + var deferred = $q.defer(), + promise = deferred.promise, + cache, + cachedResp, + url = buildUrl(config.url, config.params); + + $http.pendingRequests.push(config); + promise.then(removePendingReq, removePendingReq); + + + if (config.cache && config.method == 'GET') { + cache = isObject(config.cache) ? config.cache : defaultCache; + } + + if (cache) { + cachedResp = cache.get(url); + if (cachedResp) { + if (cachedResp.then) { + // cached request has already been sent, but there is no response yet + cachedResp.then(removePendingReq, removePendingReq); + return cachedResp; + } else { + // serving from cache + if (isArray(cachedResp)) { + resolvePromise(cachedResp[1], cachedResp[0], copy(cachedResp[2])); + } else { + resolvePromise(cachedResp, 200, {}); + } + } + } else { + // put the promise for the non-transformed response into cache as a placeholder + cache.put(url, promise); + } + } + + // if we won't have the response in cache, send the request to the backend + if (!cachedResp) { + $httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout, + config.withCredentials); + } + + return promise; + + + /** + * Callback registered to $httpBackend(): + * - caches the response if desired + * - resolves the raw $http promise + * - calls $apply + */ + function done(status, response, headersString) { + if (cache) { + if (isSuccess(status)) { + cache.put(url, [status, response, parseHeaders(headersString)]); + } else { + // remove promise from the cache + cache.remove(url); + } + } + + resolvePromise(response, status, headersString); + $rootScope.$apply(); + } + + + /** + * Resolves the raw $http promise. + */ + function resolvePromise(response, status, headers) { + // normalize internal statuses to 0 + status = Math.max(status, 0); + + (isSuccess(status) ? deferred.resolve : deferred.reject)({ + data: response, + status: status, + headers: headersGetter(headers), + config: config + }); + } + + + function removePendingReq() { + var idx = indexOf($http.pendingRequests, config); + if (idx !== -1) $http.pendingRequests.splice(idx, 1); + } + } + + + function buildUrl(url, params) { + if (!params) return url; + var parts = []; + forEachSorted(params, function(value, key) { + if (value == null || value == undefined) return; + if (isObject(value)) { + value = toJson(value); + } + parts.push(encodeURIComponent(key) + '=' + encodeURIComponent(value)); + }); + return url + ((url.indexOf('?') == -1) ? '?' : '&') + parts.join('&'); + } + + + }]; +} +var XHR = window.XMLHttpRequest || function() { + try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) {} + try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e2) {} + try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e3) {} + throw new Error("This browser does not support XMLHttpRequest."); +}; + + +/** + * @ngdoc object + * @name ng.$httpBackend + * @requires $browser + * @requires $window + * @requires $document + * + * @description + * HTTP backend used by the {@link ng.$http service} that delegates to + * XMLHttpRequest object or JSONP and deals with browser incompatibilities. + * + * You should never need to use this service directly, instead use the higher-level abstractions: + * {@link ng.$http $http} or {@link ngResource.$resource $resource}. + * + * During testing this implementation is swapped with {@link ngMock.$httpBackend mock + * $httpBackend} which can be trained with responses. + */ +function $HttpBackendProvider() { + this.$get = ['$browser', '$window', '$document', function($browser, $window, $document) { + return createHttpBackend($browser, XHR, $browser.defer, $window.angular.callbacks, + $document[0], $window.location.protocol.replace(':', '')); + }]; +} + +function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument, locationProtocol) { + // TODO(vojta): fix the signature + return function(method, url, post, callback, headers, timeout, withCredentials) { + $browser.$$incOutstandingRequestCount(); + url = url || $browser.url(); + + if (lowercase(method) == 'jsonp') { + var callbackId = '_' + (callbacks.counter++).toString(36); + callbacks[callbackId] = function(data) { + callbacks[callbackId].data = data; + }; + + jsonpReq(url.replace('JSON_CALLBACK', 'angular.callbacks.' + callbackId), + function() { + if (callbacks[callbackId].data) { + completeRequest(callback, 200, callbacks[callbackId].data); + } else { + completeRequest(callback, -2); + } + delete callbacks[callbackId]; + }); + } else { + var xhr = new XHR(); + xhr.open(method, url, true); + forEach(headers, function(value, key) { + if (value) xhr.setRequestHeader(key, value); + }); + + var status; + + // In IE6 and 7, this might be called synchronously when xhr.send below is called and the + // response is in the cache. the promise api will ensure that to the app code the api is + // always async + xhr.onreadystatechange = function() { + if (xhr.readyState == 4) { + completeRequest( + callback, status || xhr.status, xhr.responseText, xhr.getAllResponseHeaders()); + } + }; + + if (withCredentials) { + xhr.withCredentials = true; + } + + xhr.send(post || ''); + + if (timeout > 0) { + $browserDefer(function() { + status = -1; + xhr.abort(); + }, timeout); + } + } + + + function completeRequest(callback, status, response, headersString) { + // URL_MATCH is defined in src/service/location.js + var protocol = (url.match(URL_MATCH) || ['', locationProtocol])[1]; + + // fix status code for file protocol (it's always 0) + status = (protocol == 'file') ? (response ? 200 : 404) : status; + + // normalize IE bug (http://bugs.jquery.com/ticket/1450) + status = status == 1223 ? 204 : status; + + callback(status, response, headersString); + $browser.$$completeOutstandingRequest(noop); + } + }; + + function jsonpReq(url, done) { + // we can't use jQuery/jqLite here because jQuery does crazy shit with script elements, e.g.: + // - fetches local scripts via XHR and evals them + // - adds and immediately removes script elements from the document + var script = rawDocument.createElement('script'), + doneWrapper = function() { + rawDocument.body.removeChild(script); + if (done) done(); + }; + + script.type = 'text/javascript'; + script.src = url; + + if (msie) { + script.onreadystatechange = function() { + if (/loaded|complete/.test(script.readyState)) doneWrapper(); + }; + } else { + script.onload = script.onerror = doneWrapper; + } + + rawDocument.body.appendChild(script); + } +} + +/** + * @ngdoc object + * @name ng.$locale + * + * @description + * $locale service provides localization rules for various Angular components. As of right now the + * only public api is: + * + * * `id` – `{string}` – locale id formatted as `languageId-countryId` (e.g. `en-us`) + */ +function $LocaleProvider(){ + this.$get = function() { + return { + id: 'en-us', + + NUMBER_FORMATS: { + DECIMAL_SEP: '.', + GROUP_SEP: ',', + PATTERNS: [ + { // Decimal Pattern + minInt: 1, + minFrac: 0, + maxFrac: 3, + posPre: '', + posSuf: '', + negPre: '-', + negSuf: '', + gSize: 3, + lgSize: 3 + },{ //Currency Pattern + minInt: 1, + minFrac: 2, + maxFrac: 2, + posPre: '\u00A4', + posSuf: '', + negPre: '(\u00A4', + negSuf: ')', + gSize: 3, + lgSize: 3 + } + ], + CURRENCY_SYM: '$' + }, + + DATETIME_FORMATS: { + MONTH: 'January,February,March,April,May,June,July,August,September,October,November,December' + .split(','), + SHORTMONTH: 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec'.split(','), + DAY: 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday'.split(','), + SHORTDAY: 'Sun,Mon,Tue,Wed,Thu,Fri,Sat'.split(','), + AMPMS: ['AM','PM'], + medium: 'MMM d, y h:mm:ss a', + short: 'M/d/yy h:mm a', + fullDate: 'EEEE, MMMM d, y', + longDate: 'MMMM d, y', + mediumDate: 'MMM d, y', + shortDate: 'M/d/yy', + mediumTime: 'h:mm:ss a', + shortTime: 'h:mm a' + }, + + pluralCat: function(num) { + if (num === 1) { + return 'one'; + } + return 'other'; + } + }; + }; +} + +function $TimeoutProvider() { + this.$get = ['$rootScope', '$browser', '$q', '$exceptionHandler', + function($rootScope, $browser, $q, $exceptionHandler) { + var deferreds = {}; + + + /** + * @ngdoc function + * @name ng.$timeout + * @requires $browser + * + * @description + * Angular's wrapper for `window.setTimeout`. The `fn` function is wrapped into a try/catch + * block and delegates any exceptions to + * {@link ng.$exceptionHandler $exceptionHandler} service. + * + * The return value of registering a timeout function is a promise which will be resolved when + * the timeout is reached and the timeout function is executed. + * + * To cancel a the timeout request, call `$timeout.cancel(promise)`. + * + * In tests you can use {@link ngMock.$timeout `$timeout.flush()`} to + * synchronously flush the queue of deferred functions. + * + * @param {function()} fn A function, who's execution should be delayed. + * @param {number=} [delay=0] Delay in milliseconds. + * @param {boolean=} [invokeApply=true] If set to false skips model dirty checking, otherwise + * will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block. + * @returns {*} Promise that will be resolved when the timeout is reached. The value this + * promise will be resolved with is the return value of the `fn` function. + */ + function timeout(fn, delay, invokeApply) { + var deferred = $q.defer(), + promise = deferred.promise, + skipApply = (isDefined(invokeApply) && !invokeApply), + timeoutId, cleanup; + + timeoutId = $browser.defer(function() { + try { + deferred.resolve(fn()); + } catch(e) { + deferred.reject(e); + $exceptionHandler(e); + } + + if (!skipApply) $rootScope.$apply(); + }, delay); + + cleanup = function() { + delete deferreds[promise.$$timeoutId]; + }; + + promise.$$timeoutId = timeoutId; + deferreds[timeoutId] = deferred; + promise.then(cleanup, cleanup); + + return promise; + } + + + /** + * @ngdoc function + * @name ng.$timeout#cancel + * @methodOf ng.$timeout + * + * @description + * Cancels a task associated with the `promise`. As a result of this the promise will be + * resolved with a rejection. + * + * @param {Promise=} promise Promise returned by the `$timeout` function. + * @returns {boolean} Returns `true` if the task hasn't executed yet and was successfully + * canceled. + */ + timeout.cancel = function(promise) { + if (promise && promise.$$timeoutId in deferreds) { + deferreds[promise.$$timeoutId].reject('canceled'); + return $browser.defer.cancel(promise.$$timeoutId); + } + return false; + }; + + return timeout; + }]; +} + +/** + * @ngdoc object + * @name ng.$filterProvider + * @description + * + * Filters are just functions which transform input to an output. However filters need to be Dependency Injected. To + * achieve this a filter definition consists of a factory function which is annotated with dependencies and is + * responsible for creating a the filter function. + * + *
    + *   // Filter registration
    + *   function MyModule($provide, $filterProvider) {
    + *     // create a service to demonstrate injection (not always needed)
    + *     $provide.value('greet', function(name){
    + *       return 'Hello ' + name + '!';
    + *     });
    + *
    + *     // register a filter factory which uses the
    + *     // greet service to demonstrate DI.
    + *     $filterProvider.register('greet', function(greet){
    + *       // return the filter function which uses the greet service
    + *       // to generate salutation
    + *       return function(text) {
    + *         // filters need to be forgiving so check input validity
    + *         return text && greet(text) || text;
    + *       };
    + *     });
    + *   }
    + * 
    + * + * The filter function is registered with the `$injector` under the filter name suffixe with `Filter`. + *
    + *   it('should be the same instance', inject(
    + *     function($filterProvider) {
    + *       $filterProvider.register('reverse', function(){
    + *         return ...;
    + *       });
    + *     },
    + *     function($filter, reverseFilter) {
    + *       expect($filter('reverse')).toBe(reverseFilter);
    + *     });
    + * 
    + * + * + * For more information about how angular filters work, and how to create your own filters, see + * {@link guide/dev_guide.templates.filters Understanding Angular Filters} in the angular Developer + * Guide. + */ +/** + * @ngdoc method + * @name ng.$filterProvider#register + * @methodOf ng.$filterProvider + * @description + * Register filter factory function. + * + * @param {String} name Name of the filter. + * @param {function} fn The filter factory function which is injectable. + */ + + +/** + * @ngdoc function + * @name ng.$filter + * @function + * @description + * Filters are used for formatting data displayed to the user. + * + * The general syntax in templates is as follows: + * + * {{ expression | [ filter_name ] }} + * + * @param {String} name Name of the filter function to retrieve + * @return {Function} the filter function + */ +$FilterProvider.$inject = ['$provide']; +function $FilterProvider($provide) { + var suffix = 'Filter'; + + function register(name, factory) { + return $provide.factory(name + suffix, factory); + } + this.register = register; + + this.$get = ['$injector', function($injector) { + return function(name) { + return $injector.get(name + suffix); + } + }]; + + //////////////////////////////////////// + + register('currency', currencyFilter); + register('date', dateFilter); + register('filter', filterFilter); + register('json', jsonFilter); + register('limitTo', limitToFilter); + register('lowercase', lowercaseFilter); + register('number', numberFilter); + register('orderBy', orderByFilter); + register('uppercase', uppercaseFilter); +} + +/** + * @ngdoc filter + * @name ng.filter:filter + * @function + * + * @description + * Selects a subset of items from `array` and returns it as a new array. + * + * Note: This function is used to augment the `Array` type in Angular expressions. See + * {@link ng.$filter} for more information about Angular arrays. + * + * @param {Array} array The source array. + * @param {string|Object|function()} expression The predicate to be used for selecting items from + * `array`. + * + * Can be one of: + * + * - `string`: Predicate that results in a substring match using the value of `expression` + * string. All strings or objects with string properties in `array` that contain this string + * will be returned. The predicate can be negated by prefixing the string with `!`. + * + * - `Object`: A pattern object can be used to filter specific properties on objects contained + * by `array`. For example `{name:"M", phone:"1"}` predicate will return an array of items + * which have property `name` containing "M" and property `phone` containing "1". A special + * property name `$` can be used (as in `{$:"text"}`) to accept a match against any + * property of the object. That's equivalent to the simple substring match with a `string` + * as described above. + * + * - `function`: A predicate function can be used to write arbitrary filters. The function is + * called for each element of `array`. The final result is an array of those elements that + * the predicate returned true for. + * + * @example + + +
    + + Search: + + + + + + +
    NamePhone
    {{friend.name}}{{friend.phone}}
    +
    + Any:
    + Name only
    + Phone only
    + + + + + + +
    NamePhone
    {{friend.name}}{{friend.phone}}
    +
    + + it('should search across all fields when filtering with a string', function() { + input('searchText').enter('m'); + expect(repeater('#searchTextResults tr', 'friend in friends').column('friend.name')). + toEqual(['Mary', 'Mike', 'Adam']); + + input('searchText').enter('76'); + expect(repeater('#searchTextResults tr', 'friend in friends').column('friend.name')). + toEqual(['John', 'Julie']); + }); + + it('should search in specific fields when filtering with a predicate object', function() { + input('search.$').enter('i'); + expect(repeater('#searchObjResults tr', 'friend in friends').column('friend.name')). + toEqual(['Mary', 'Mike', 'Julie']); + }); + +
    + */ +function filterFilter() { + return function(array, expression) { + if (!(array instanceof Array)) return array; + var predicates = []; + predicates.check = function(value) { + for (var j = 0; j < predicates.length; j++) { + if(!predicates[j](value)) { + return false; + } + } + return true; + }; + var search = function(obj, text){ + if (text.charAt(0) === '!') { + return !search(obj, text.substr(1)); + } + switch (typeof obj) { + case "boolean": + case "number": + case "string": + return ('' + obj).toLowerCase().indexOf(text) > -1; + case "object": + for ( var objKey in obj) { + if (objKey.charAt(0) !== '$' && search(obj[objKey], text)) { + return true; + } + } + return false; + case "array": + for ( var i = 0; i < obj.length; i++) { + if (search(obj[i], text)) { + return true; + } + } + return false; + default: + return false; + } + }; + switch (typeof expression) { + case "boolean": + case "number": + case "string": + expression = {$:expression}; + case "object": + for (var key in expression) { + if (key == '$') { + (function() { + var text = (''+expression[key]).toLowerCase(); + if (!text) return; + predicates.push(function(value) { + return search(value, text); + }); + })(); + } else { + (function() { + var path = key; + var text = (''+expression[key]).toLowerCase(); + if (!text) return; + predicates.push(function(value) { + return search(getter(value, path), text); + }); + })(); + } + } + break; + case 'function': + predicates.push(expression); + break; + default: + return array; + } + var filtered = []; + for ( var j = 0; j < array.length; j++) { + var value = array[j]; + if (predicates.check(value)) { + filtered.push(value); + } + } + return filtered; + } +} + +/** + * @ngdoc filter + * @name ng.filter:currency + * @function + * + * @description + * Formats a number as a currency (ie $1,234.56). When no currency symbol is provided, default + * symbol for current locale is used. + * + * @param {number} amount Input to filter. + * @param {string=} symbol Currency symbol or identifier to be displayed. + * @returns {string} Formatted number. + * + * + * @example + + + +
    +
    + default currency symbol ($): {{amount | currency}}
    + custom currency identifier (USD$): {{amount | currency:"USD$"}} +
    +
    + + it('should init with 1234.56', function() { + expect(binding('amount | currency')).toBe('$1,234.56'); + expect(binding('amount | currency:"USD$"')).toBe('USD$1,234.56'); + }); + it('should update', function() { + input('amount').enter('-1234'); + expect(binding('amount | currency')).toBe('($1,234.00)'); + expect(binding('amount | currency:"USD$"')).toBe('(USD$1,234.00)'); + }); + +
    + */ +currencyFilter.$inject = ['$locale']; +function currencyFilter($locale) { + var formats = $locale.NUMBER_FORMATS; + return function(amount, currencySymbol){ + if (isUndefined(currencySymbol)) currencySymbol = formats.CURRENCY_SYM; + return formatNumber(amount, formats.PATTERNS[1], formats.GROUP_SEP, formats.DECIMAL_SEP, 2). + replace(/\u00A4/g, currencySymbol); + }; +} + +/** + * @ngdoc filter + * @name ng.filter:number + * @function + * + * @description + * Formats a number as text. + * + * If the input is not a number an empty string is returned. + * + * @param {number|string} number Number to format. + * @param {(number|string)=} [fractionSize=2] Number of decimal places to round the number to. + * @returns {string} Number rounded to decimalPlaces and places a “,” after each third digit. + * + * @example + + + +
    + Enter number:
    + Default formatting: {{val | number}}
    + No fractions: {{val | number:0}}
    + Negative number: {{-val | number:4}} +
    +
    + + it('should format numbers', function() { + expect(binding('val | number')).toBe('1,234.568'); + expect(binding('val | number:0')).toBe('1,235'); + expect(binding('-val | number:4')).toBe('-1,234.5679'); + }); + + it('should update', function() { + input('val').enter('3374.333'); + expect(binding('val | number')).toBe('3,374.333'); + expect(binding('val | number:0')).toBe('3,374'); + expect(binding('-val | number:4')).toBe('-3,374.3330'); + }); + +
    + */ + + +numberFilter.$inject = ['$locale']; +function numberFilter($locale) { + var formats = $locale.NUMBER_FORMATS; + return function(number, fractionSize) { + return formatNumber(number, formats.PATTERNS[0], formats.GROUP_SEP, formats.DECIMAL_SEP, + fractionSize); + }; +} + +var DECIMAL_SEP = '.'; +function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) { + if (isNaN(number) || !isFinite(number)) return ''; + + var isNegative = number < 0; + number = Math.abs(number); + var numStr = number + '', + formatedText = '', + parts = []; + + if (numStr.indexOf('e') !== -1) { + formatedText = numStr; + } else { + var fractionLen = (numStr.split(DECIMAL_SEP)[1] || '').length; + + // determine fractionSize if it is not specified + if (isUndefined(fractionSize)) { + fractionSize = Math.min(Math.max(pattern.minFrac, fractionLen), pattern.maxFrac); + } + + var pow = Math.pow(10, fractionSize); + number = Math.round(number * pow) / pow; + var fraction = ('' + number).split(DECIMAL_SEP); + var whole = fraction[0]; + fraction = fraction[1] || ''; + + var pos = 0, + lgroup = pattern.lgSize, + group = pattern.gSize; + + if (whole.length >= (lgroup + group)) { + pos = whole.length - lgroup; + for (var i = 0; i < pos; i++) { + if ((pos - i)%group === 0 && i !== 0) { + formatedText += groupSep; + } + formatedText += whole.charAt(i); + } + } + + for (i = pos; i < whole.length; i++) { + if ((whole.length - i)%lgroup === 0 && i !== 0) { + formatedText += groupSep; + } + formatedText += whole.charAt(i); + } + + // format fraction part. + while(fraction.length < fractionSize) { + fraction += '0'; + } + + if (fractionSize) formatedText += decimalSep + fraction.substr(0, fractionSize); + } + + parts.push(isNegative ? pattern.negPre : pattern.posPre); + parts.push(formatedText); + parts.push(isNegative ? pattern.negSuf : pattern.posSuf); + return parts.join(''); +} + +function padNumber(num, digits, trim) { + var neg = ''; + if (num < 0) { + neg = '-'; + num = -num; + } + num = '' + num; + while(num.length < digits) num = '0' + num; + if (trim) + num = num.substr(num.length - digits); + return neg + num; +} + + +function dateGetter(name, size, offset, trim) { + return function(date) { + var value = date['get' + name](); + if (offset > 0 || value > -offset) + value += offset; + if (value === 0 && offset == -12 ) value = 12; + return padNumber(value, size, trim); + }; +} + +function dateStrGetter(name, shortForm) { + return function(date, formats) { + var value = date['get' + name](); + var get = uppercase(shortForm ? ('SHORT' + name) : name); + + return formats[get][value]; + }; +} + +function timeZoneGetter(date) { + var offset = date.getTimezoneOffset(); + return padNumber(offset / 60, 2) + padNumber(Math.abs(offset % 60), 2); +} + +function ampmGetter(date, formats) { + return date.getHours() < 12 ? formats.AMPMS[0] : formats.AMPMS[1]; +} + +var DATE_FORMATS = { + yyyy: dateGetter('FullYear', 4), + yy: dateGetter('FullYear', 2, 0, true), + y: dateGetter('FullYear', 1), + MMMM: dateStrGetter('Month'), + MMM: dateStrGetter('Month', true), + MM: dateGetter('Month', 2, 1), + M: dateGetter('Month', 1, 1), + dd: dateGetter('Date', 2), + d: dateGetter('Date', 1), + HH: dateGetter('Hours', 2), + H: dateGetter('Hours', 1), + hh: dateGetter('Hours', 2, -12), + h: dateGetter('Hours', 1, -12), + mm: dateGetter('Minutes', 2), + m: dateGetter('Minutes', 1), + ss: dateGetter('Seconds', 2), + s: dateGetter('Seconds', 1), + EEEE: dateStrGetter('Day'), + EEE: dateStrGetter('Day', true), + a: ampmGetter, + Z: timeZoneGetter +}; + +var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/, + NUMBER_STRING = /^\d+$/; + +/** + * @ngdoc filter + * @name ng.filter:date + * @function + * + * @description + * Formats `date` to a string based on the requested `format`. + * + * `format` string can be composed of the following elements: + * + * * `'yyyy'`: 4 digit representation of year (e.g. AD 1 => 0001, AD 2010 => 2010) + * * `'yy'`: 2 digit representation of year, padded (00-99). (e.g. AD 2001 => 01, AD 2010 => 10) + * * `'y'`: 1 digit representation of year, e.g. (AD 1 => 1, AD 199 => 199) + * * `'MMMM'`: Month in year (January-December) + * * `'MMM'`: Month in year (Jan-Dec) + * * `'MM'`: Month in year, padded (01-12) + * * `'M'`: Month in year (1-12) + * * `'dd'`: Day in month, padded (01-31) + * * `'d'`: Day in month (1-31) + * * `'EEEE'`: Day in Week,(Sunday-Saturday) + * * `'EEE'`: Day in Week, (Sun-Sat) + * * `'HH'`: Hour in day, padded (00-23) + * * `'H'`: Hour in day (0-23) + * * `'hh'`: Hour in am/pm, padded (01-12) + * * `'h'`: Hour in am/pm, (1-12) + * * `'mm'`: Minute in hour, padded (00-59) + * * `'m'`: Minute in hour (0-59) + * * `'ss'`: Second in minute, padded (00-59) + * * `'s'`: Second in minute (0-59) + * * `'a'`: am/pm marker + * * `'Z'`: 4 digit (+sign) representation of the timezone offset (-1200-1200) + * + * `format` string can also be one of the following predefined + * {@link guide/i18n localizable formats}: + * + * * `'medium'`: equivalent to `'MMM d, y h:mm:ss a'` for en_US locale + * (e.g. Sep 3, 2010 12:05:08 pm) + * * `'short'`: equivalent to `'M/d/yy h:mm a'` for en_US locale (e.g. 9/3/10 12:05 pm) + * * `'fullDate'`: equivalent to `'EEEE, MMMM d,y'` for en_US locale + * (e.g. Friday, September 3, 2010) + * * `'longDate'`: equivalent to `'MMMM d, y'` for en_US locale (e.g. September 3, 2010 + * * `'mediumDate'`: equivalent to `'MMM d, y'` for en_US locale (e.g. Sep 3, 2010) + * * `'shortDate'`: equivalent to `'M/d/yy'` for en_US locale (e.g. 9/3/10) + * * `'mediumTime'`: equivalent to `'h:mm:ss a'` for en_US locale (e.g. 12:05:08 pm) + * * `'shortTime'`: equivalent to `'h:mm a'` for en_US locale (e.g. 12:05 pm) + * + * `format` string can contain literal values. These need to be quoted with single quotes (e.g. + * `"h 'in the morning'"`). In order to output single quote, use two single quotes in a sequence + * (e.g. `"h o''clock"`). + * + * @param {(Date|number|string)} date Date to format either as Date object, milliseconds (string or + * number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.SSSZ and it's + * shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ). + * @param {string=} format Formatting rules (see Description). If not specified, + * `mediumDate` is used. + * @returns {string} Formatted string or the input if input is not recognized as date/millis. + * + * @example + + + {{1288323623006 | date:'medium'}}: + {{1288323623006 | date:'medium'}}
    + {{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}: + {{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}
    + {{1288323623006 | date:'MM/dd/yyyy @ h:mma'}}: + {{'1288323623006' | date:'MM/dd/yyyy @ h:mma'}}
    +
    + + it('should format date', function() { + expect(binding("1288323623006 | date:'medium'")). + toMatch(/Oct 2\d, 2010 \d{1,2}:\d{2}:\d{2} (AM|PM)/); + expect(binding("1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'")). + toMatch(/2010\-10\-2\d \d{2}:\d{2}:\d{2} \-?\d{4}/); + expect(binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")). + toMatch(/10\/2\d\/2010 @ \d{1,2}:\d{2}(AM|PM)/); + }); + +
    + */ +dateFilter.$inject = ['$locale']; +function dateFilter($locale) { + + + var R_ISO8601_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d{3}))?)?)?(Z|([+-])(\d\d):?(\d\d)))?$/; + function jsonStringToDate(string){ + var match; + if (match = string.match(R_ISO8601_STR)) { + var date = new Date(0), + tzHour = 0, + tzMin = 0; + if (match[9]) { + tzHour = int(match[9] + match[10]); + tzMin = int(match[9] + match[11]); + } + date.setUTCFullYear(int(match[1]), int(match[2]) - 1, int(match[3])); + date.setUTCHours(int(match[4]||0) - tzHour, int(match[5]||0) - tzMin, int(match[6]||0), int(match[7]||0)); + return date; + } + return string; + } + + + return function(date, format) { + var text = '', + parts = [], + fn, match; + + format = format || 'mediumDate'; + format = $locale.DATETIME_FORMATS[format] || format; + if (isString(date)) { + if (NUMBER_STRING.test(date)) { + date = int(date); + } else { + date = jsonStringToDate(date); + } + } + + if (isNumber(date)) { + date = new Date(date); + } + + if (!isDate(date)) { + return date; + } + + while(format) { + match = DATE_FORMATS_SPLIT.exec(format); + if (match) { + parts = concat(parts, match, 1); + format = parts.pop(); + } else { + parts.push(format); + format = null; + } + } + + forEach(parts, function(value){ + fn = DATE_FORMATS[value]; + text += fn ? fn(date, $locale.DATETIME_FORMATS) + : value.replace(/(^'|'$)/g, '').replace(/''/g, "'"); + }); + + return text; + }; +} + + +/** + * @ngdoc filter + * @name ng.filter:json + * @function + * + * @description + * Allows you to convert a JavaScript object into JSON string. + * + * This filter is mostly useful for debugging. When using the double curly {{value}} notation + * the binding is automatically converted to JSON. + * + * @param {*} object Any JavaScript object (including arrays and primitive types) to filter. + * @returns {string} JSON string. + * + * + * @example: + + +
    {{ {'name':'value'} | json }}
    +
    + + it('should jsonify filtered objects', function() { + expect(binding("{'name':'value'}")).toMatch(/\{\n "name": ?"value"\n}/); + }); + +
    + * + */ +function jsonFilter() { + return function(object) { + return toJson(object, true); + }; +} + + +/** + * @ngdoc filter + * @name ng.filter:lowercase + * @function + * @description + * Converts string to lowercase. + * @see angular.lowercase + */ +var lowercaseFilter = valueFn(lowercase); + + +/** + * @ngdoc filter + * @name ng.filter:uppercase + * @function + * @description + * Converts string to uppercase. + * @see angular.uppercase + */ +var uppercaseFilter = valueFn(uppercase); + +/** + * @ngdoc function + * @name ng.filter:limitTo + * @function + * + * @description + * Creates a new array containing only a specified number of elements in an array. The elements + * are taken from either the beginning or the end of the source array, as specified by the + * value and sign (positive or negative) of `limit`. + * + * Note: This function is used to augment the `Array` type in Angular expressions. See + * {@link ng.$filter} for more information about Angular arrays. + * + * @param {Array} array Source array to be limited. + * @param {string|Number} limit The length of the returned array. If the `limit` number is + * positive, `limit` number of items from the beginning of the source array are copied. + * If the number is negative, `limit` number of items from the end of the source array are + * copied. The `limit` will be trimmed if it exceeds `array.length` + * @returns {Array} A new sub-array of length `limit` or less if input array had less than `limit` + * elements. + * + * @example + + + +
    + Limit {{numbers}} to: +

    Output: {{ numbers | limitTo:limit }}

    +
    +
    + + it('should limit the numer array to first three items', function() { + expect(element('.doc-example-live input[ng-model=limit]').val()).toBe('3'); + expect(binding('numbers | limitTo:limit')).toEqual('[1,2,3]'); + }); + + it('should update the output when -3 is entered', function() { + input('limit').enter(-3); + expect(binding('numbers | limitTo:limit')).toEqual('[7,8,9]'); + }); + + it('should not exceed the maximum size of input array', function() { + input('limit').enter(100); + expect(binding('numbers | limitTo:limit')).toEqual('[1,2,3,4,5,6,7,8,9]'); + }); + +
    + */ +function limitToFilter(){ + return function(array, limit) { + if (!(array instanceof Array)) return array; + limit = int(limit); + var out = [], + i, n; + + // check that array is iterable + if (!array || !(array instanceof Array)) + return out; + + // if abs(limit) exceeds maximum length, trim it + if (limit > array.length) + limit = array.length; + else if (limit < -array.length) + limit = -array.length; + + if (limit > 0) { + i = 0; + n = limit; + } else { + i = array.length + limit; + n = array.length; + } + + for (; i} expression A predicate to be + * used by the comparator to determine the order of elements. + * + * Can be one of: + * + * - `function`: Getter function. The result of this function will be sorted using the + * `<`, `=`, `>` operator. + * - `string`: An Angular expression which evaluates to an object to order by, such as 'name' + * to sort by a property called 'name'. Optionally prefixed with `+` or `-` to control + * ascending or descending sort order (for example, +name or -name). + * - `Array`: An array of function or string predicates. The first predicate in the array + * is used for sorting, but when two items are equivalent, the next predicate is used. + * + * @param {boolean=} reverse Reverse the order the array. + * @returns {Array} Sorted copy of the source array. + * + * @example + + + +
    +
    Sorting predicate = {{predicate}}; reverse = {{reverse}}
    +
    + [ unsorted ] + + + + + + + + + + + +
    Name + (^)Phone NumberAge
    {{friend.name}}{{friend.phone}}{{friend.age}}
    +
    +
    + + it('should be reverse ordered by aged', function() { + expect(binding('predicate')).toBe('-age'); + expect(repeater('table.friend', 'friend in friends').column('friend.age')). + toEqual(['35', '29', '21', '19', '10']); + expect(repeater('table.friend', 'friend in friends').column('friend.name')). + toEqual(['Adam', 'Julie', 'Mike', 'Mary', 'John']); + }); + + it('should reorder the table when user selects different predicate', function() { + element('.doc-example-live a:contains("Name")').click(); + expect(repeater('table.friend', 'friend in friends').column('friend.name')). + toEqual(['Adam', 'John', 'Julie', 'Mary', 'Mike']); + expect(repeater('table.friend', 'friend in friends').column('friend.age')). + toEqual(['35', '10', '29', '19', '21']); + + element('.doc-example-live a:contains("Phone")').click(); + expect(repeater('table.friend', 'friend in friends').column('friend.phone')). + toEqual(['555-9876', '555-8765', '555-5678', '555-4321', '555-1212']); + expect(repeater('table.friend', 'friend in friends').column('friend.name')). + toEqual(['Mary', 'Julie', 'Adam', 'Mike', 'John']); + }); + +
    + */ +orderByFilter.$inject = ['$parse']; +function orderByFilter($parse){ + return function(array, sortPredicate, reverseOrder) { + if (!(array instanceof Array)) return array; + if (!sortPredicate) return array; + sortPredicate = isArray(sortPredicate) ? sortPredicate: [sortPredicate]; + sortPredicate = map(sortPredicate, function(predicate){ + var descending = false, get = predicate || identity; + if (isString(predicate)) { + if ((predicate.charAt(0) == '+' || predicate.charAt(0) == '-')) { + descending = predicate.charAt(0) == '-'; + predicate = predicate.substring(1); + } + get = $parse(predicate); + } + return reverseComparator(function(a,b){ + return compare(get(a),get(b)); + }, descending); + }); + var arrayCopy = []; + for ( var i = 0; i < array.length; i++) { arrayCopy.push(array[i]); } + return arrayCopy.sort(reverseComparator(comparator, reverseOrder)); + + function comparator(o1, o2){ + for ( var i = 0; i < sortPredicate.length; i++) { + var comp = sortPredicate[i](o1, o2); + if (comp !== 0) return comp; + } + return 0; + } + function reverseComparator(comp, descending) { + return toBoolean(descending) + ? function(a,b){return comp(b,a);} + : comp; + } + function compare(v1, v2){ + var t1 = typeof v1; + var t2 = typeof v2; + if (t1 == t2) { + if (t1 == "string") v1 = v1.toLowerCase(); + if (t1 == "string") v2 = v2.toLowerCase(); + if (v1 === v2) return 0; + return v1 < v2 ? -1 : 1; + } else { + return t1 < t2 ? -1 : 1; + } + } + } +} + +function ngDirective(directive) { + if (isFunction(directive)) { + directive = { + link: directive + } + } + directive.restrict = directive.restrict || 'AC'; + return valueFn(directive); +} + +/** + * @ngdoc directive + * @name ng.directive:a + * @restrict E + * + * @description + * Modifies the default behavior of html A tag, so that the default action is prevented when href + * attribute is empty. + * + * The reasoning for this change is to allow easy creation of action links with `ngClick` directive + * without changing the location or causing page reloads, e.g.: + * Save + */ +var htmlAnchorDirective = valueFn({ + restrict: 'E', + compile: function(element, attr) { + // turn link into a link in IE + // but only if it doesn't have name attribute, in which case it's an anchor + if (!attr.href) { + attr.$set('href', ''); + } + + return function(scope, element) { + element.bind('click', function(event){ + // if we have no href url, then don't navigate anywhere. + if (!element.attr('href')) { + event.preventDefault(); + } + }); + } + } +}); + +/** + * @ngdoc directive + * @name ng.directive:ngHref + * @restrict A + * + * @description + * Using Angular markup like {{hash}} in an href attribute makes + * the page open to a wrong URL, if the user clicks that link before + * angular has a chance to replace the {{hash}} with actual URL, the + * link will be broken and will most likely return a 404 error. + * The `ngHref` directive solves this problem. + * + * The buggy way to write it: + *
    + * 
    + * 
    + * + * The correct way to write it: + *
    + * 
    + * 
    + * + * @element A + * @param {template} ngHref any string which can contain `{{}}` markup. + * + * @example + * This example uses `link` variable inside `href` attribute: + + +
    +
    link 1 (link, don't reload)
    + link 2 (link, don't reload)
    + link 3 (link, reload!)
    + anchor (link, don't reload)
    + anchor (no link)
    + link (link, change location) + + + it('should execute ng-click but not reload when href without value', function() { + element('#link-1').click(); + expect(input('value').val()).toEqual('1'); + expect(element('#link-1').attr('href')).toBe(""); + }); + + it('should execute ng-click but not reload when href empty string', function() { + element('#link-2').click(); + expect(input('value').val()).toEqual('2'); + expect(element('#link-2').attr('href')).toBe(""); + }); + + it('should execute ng-click and change url when ng-href specified', function() { + expect(element('#link-3').attr('href')).toBe("/123"); + + element('#link-3').click(); + expect(browser().window().path()).toEqual('/123'); + }); + + it('should execute ng-click but not reload when href empty string and name specified', function() { + element('#link-4').click(); + expect(input('value').val()).toEqual('4'); + expect(element('#link-4').attr('href')).toBe(''); + }); + + it('should execute ng-click but not reload when no href but name specified', function() { + element('#link-5').click(); + expect(input('value').val()).toEqual('5'); + expect(element('#link-5').attr('href')).toBe(''); + }); + + it('should only change url when only ng-href', function() { + input('value').enter('6'); + expect(element('#link-6').attr('href')).toBe('6'); + + element('#link-6').click(); + expect(browser().location().url()).toEqual('/6'); + }); + + + */ + +/** + * @ngdoc directive + * @name ng.directive:ngSrc + * @restrict A + * + * @description + * Using Angular markup like `{{hash}}` in a `src` attribute doesn't + * work right: The browser will fetch from the URL with the literal + * text `{{hash}}` until Angular replaces the expression inside + * `{{hash}}`. The `ngSrc` directive solves this problem. + * + * The buggy way to write it: + *
    + * 
    + * 
    + * + * The correct way to write it: + *
    + * 
    + * 
    + * + * @element IMG + * @param {template} ngSrc any string which can contain `{{}}` markup. + */ + +/** + * @ngdoc directive + * @name ng.directive:ngDisabled + * @restrict A + * + * @description + * + * The following markup will make the button enabled on Chrome/Firefox but not on IE8 and older IEs: + *
    + * 
    + * + *
    + *
    + * + * The HTML specs do not require browsers to preserve the special attributes such as disabled. + * (The presence of them means true and absence means false) + * This prevents the angular compiler from correctly retrieving the binding expression. + * To solve this problem, we introduce the `ngDisabled` directive. + * + * @example + + + Click me to toggle:
    + +
    + + it('should toggle button', function() { + expect(element('.doc-example-live :button').prop('disabled')).toBeFalsy(); + input('checked').check(); + expect(element('.doc-example-live :button').prop('disabled')).toBeTruthy(); + }); + +
    + * + * @element INPUT + * @param {expression} ngDisabled Angular expression that will be evaluated. + */ + + +/** + * @ngdoc directive + * @name ng.directive:ngChecked + * @restrict A + * + * @description + * The HTML specs do not require browsers to preserve the special attributes such as checked. + * (The presence of them means true and absence means false) + * This prevents the angular compiler from correctly retrieving the binding expression. + * To solve this problem, we introduce the `ngChecked` directive. + * @example + + + Check me to check both:
    + +
    + + it('should check both checkBoxes', function() { + expect(element('.doc-example-live #checkSlave').prop('checked')).toBeFalsy(); + input('master').check(); + expect(element('.doc-example-live #checkSlave').prop('checked')).toBeTruthy(); + }); + +
    + * + * @element INPUT + * @param {expression} ngChecked Angular expression that will be evaluated. + */ + + +/** + * @ngdoc directive + * @name ng.directive:ngMultiple + * @restrict A + * + * @description + * The HTML specs do not require browsers to preserve the special attributes such as multiple. + * (The presence of them means true and absence means false) + * This prevents the angular compiler from correctly retrieving the binding expression. + * To solve this problem, we introduce the `ngMultiple` directive. + * + * @example + + + Check me check multiple:
    + +
    + + it('should toggle multiple', function() { + expect(element('.doc-example-live #select').prop('multiple')).toBeFalsy(); + input('checked').check(); + expect(element('.doc-example-live #select').prop('multiple')).toBeTruthy(); + }); + +
    + * + * @element SELECT + * @param {expression} ngMultiple Angular expression that will be evaluated. + */ + + +/** + * @ngdoc directive + * @name ng.directive:ngReadonly + * @restrict A + * + * @description + * The HTML specs do not require browsers to preserve the special attributes such as readonly. + * (The presence of them means true and absence means false) + * This prevents the angular compiler from correctly retrieving the binding expression. + * To solve this problem, we introduce the `ngReadonly` directive. + * @example + + + Check me to make text readonly:
    + +
    + + it('should toggle readonly attr', function() { + expect(element('.doc-example-live :text').prop('readonly')).toBeFalsy(); + input('checked').check(); + expect(element('.doc-example-live :text').prop('readonly')).toBeTruthy(); + }); + +
    + * + * @element INPUT + * @param {string} expression Angular expression that will be evaluated. + */ + + +/** + * @ngdoc directive + * @name ng.directive:ngSelected + * @restrict A + * + * @description + * The HTML specs do not require browsers to preserve the special attributes such as selected. + * (The presence of them means true and absence means false) + * This prevents the angular compiler from correctly retrieving the binding expression. + * To solve this problem, we introduced the `ngSelected` directive. + * @example + + + Check me to select:
    + +
    + + it('should select Greetings!', function() { + expect(element('.doc-example-live #greet').prop('selected')).toBeFalsy(); + input('selected').check(); + expect(element('.doc-example-live #greet').prop('selected')).toBeTruthy(); + }); + +
    + * + * @element OPTION + * @param {string} expression Angular expression that will be evaluated. + */ + + +var ngAttributeAliasDirectives = {}; + + +// boolean attrs are evaluated +forEach(BOOLEAN_ATTR, function(propName, attrName) { + var normalized = directiveNormalize('ng-' + attrName); + ngAttributeAliasDirectives[normalized] = function() { + return { + priority: 100, + compile: function() { + return function(scope, element, attr) { + scope.$watch(attr[normalized], function(value) { + attr.$set(attrName, !!value); + }); + }; + } + }; + }; +}); + + +// ng-src, ng-href are interpolated +forEach(['src', 'href'], function(attrName) { + var normalized = directiveNormalize('ng-' + attrName); + ngAttributeAliasDirectives[normalized] = function() { + return { + priority: 99, // it needs to run after the attributes are interpolated + link: function(scope, element, attr) { + attr.$observe(normalized, function(value) { + attr.$set(attrName, value); + + // on IE, if "ng:src" directive declaration is used and "src" attribute doesn't exist + // then calling element.setAttribute('src', 'foo') doesn't do anything, so we need + // to set the property as well to achieve the desired effect + if (msie) element.prop(attrName, value); + }); + } + }; + }; +}); + +var nullFormCtrl = { + $addControl: noop, + $removeControl: noop, + $setValidity: noop, + $setDirty: noop +}; + +/** + * @ngdoc object + * @name ng.directive:form.FormController + * + * @property {boolean} $pristine True if user has not interacted with the form yet. + * @property {boolean} $dirty True if user has already interacted with the form. + * @property {boolean} $valid True if all of the containg forms and controls are valid. + * @property {boolean} $invalid True if at least one containing control or form is invalid. + * + * @property {Object} $error Is an object hash, containing references to all invalid controls or + * forms, where: + * + * - keys are validation tokens (error names) — such as `REQUIRED`, `URL` or `EMAIL`), + * - values are arrays of controls or forms that are invalid with given error. + * + * @description + * `FormController` keeps track of all its controls and nested forms as well as state of them, + * such as being valid/invalid or dirty/pristine. + * + * Each {@link ng.directive:form form} directive creates an instance + * of `FormController`. + * + */ +//asks for $scope to fool the BC controller module +FormController.$inject = ['$element', '$attrs', '$scope']; +function FormController(element, attrs) { + var form = this, + parentForm = element.parent().controller('form') || nullFormCtrl, + invalidCount = 0, // used to easily determine if we are valid + errors = form.$error = {}; + + // init state + form.$name = attrs.name; + form.$dirty = false; + form.$pristine = true; + form.$valid = true; + form.$invalid = false; + + parentForm.$addControl(form); + + // Setup initial state of the control + element.addClass(PRISTINE_CLASS); + toggleValidCss(true); + + // convenience method for easy toggling of classes + function toggleValidCss(isValid, validationErrorKey) { + validationErrorKey = validationErrorKey ? '-' + snake_case(validationErrorKey, '-') : ''; + element. + removeClass((isValid ? INVALID_CLASS : VALID_CLASS) + validationErrorKey). + addClass((isValid ? VALID_CLASS : INVALID_CLASS) + validationErrorKey); + } + + form.$addControl = function(control) { + if (control.$name && !form.hasOwnProperty(control.$name)) { + form[control.$name] = control; + } + }; + + form.$removeControl = function(control) { + if (control.$name && form[control.$name] === control) { + delete form[control.$name]; + } + forEach(errors, function(queue, validationToken) { + form.$setValidity(validationToken, true, control); + }); + }; + + form.$setValidity = function(validationToken, isValid, control) { + var queue = errors[validationToken]; + + if (isValid) { + if (queue) { + arrayRemove(queue, control); + if (!queue.length) { + invalidCount--; + if (!invalidCount) { + toggleValidCss(isValid); + form.$valid = true; + form.$invalid = false; + } + errors[validationToken] = false; + toggleValidCss(true, validationToken); + parentForm.$setValidity(validationToken, true, form); + } + } + + } else { + if (!invalidCount) { + toggleValidCss(isValid); + } + if (queue) { + if (includes(queue, control)) return; + } else { + errors[validationToken] = queue = []; + invalidCount++; + toggleValidCss(false, validationToken); + parentForm.$setValidity(validationToken, false, form); + } + queue.push(control); + + form.$valid = false; + form.$invalid = true; + } + }; + + form.$setDirty = function() { + element.removeClass(PRISTINE_CLASS).addClass(DIRTY_CLASS); + form.$dirty = true; + form.$pristine = false; + }; + +} + + +/** + * @ngdoc directive + * @name ng.directive:ngForm + * @restrict EAC + * + * @description + * Nestable alias of {@link ng.directive:form `form`} directive. HTML + * does not allow nesting of form elements. It is useful to nest forms, for example if the validity of a + * sub-group of controls needs to be determined. + * + * @param {string=} ngForm|name Name of the form. If specified, the form controller will be published into + * related scope, under this name. + * + */ + + /** + * @ngdoc directive + * @name ng.directive:form + * @restrict E + * + * @description + * Directive that instantiates + * {@link ng.directive:form.FormController FormController}. + * + * If `name` attribute is specified, the form controller is published onto the current scope under + * this name. + * + * # Alias: {@link ng.directive:ngForm `ngForm`} + * + * In angular forms can be nested. This means that the outer form is valid when all of the child + * forms are valid as well. However browsers do not allow nesting of `
    ` elements, for this + * reason angular provides {@link ng.directive:ngForm `ngForm`} alias + * which behaves identical to `` but allows form nesting. + * + * + * # CSS classes + * - `ng-valid` Is set if the form is valid. + * - `ng-invalid` Is set if the form is invalid. + * - `ng-pristine` Is set if the form is pristine. + * - `ng-dirty` Is set if the form is dirty. + * + * + * # Submitting a form and preventing default action + * + * Since the role of forms in client-side Angular applications is different than in classical + * roundtrip apps, it is desirable for the browser not to translate the form submission into a full + * page reload that sends the data to the server. Instead some javascript logic should be triggered + * to handle the form submission in application specific way. + * + * For this reason, Angular prevents the default action (form submission to the server) unless the + * `` element has an `action` attribute specified. + * + * You can use one of the following two ways to specify what javascript method should be called when + * a form is submitted: + * + * - {@link ng.directive:ngSubmit ngSubmit} directive on the form element + * - {@link ng.directive:ngClick ngClick} directive on the first + * button or input field of type submit (input[type=submit]) + * + * To prevent double execution of the handler, use only one of ngSubmit or ngClick directives. This + * is because of the following form submission rules coming from the html spec: + * + * - If a form has only one input field then hitting enter in this field triggers form submit + * (`ngSubmit`) + * - if a form has has 2+ input fields and no buttons or input[type=submit] then hitting enter + * doesn't trigger submit + * - if a form has one or more input fields and one or more buttons or input[type=submit] then + * hitting enter in any of the input fields will trigger the click handler on the *first* button or + * input[type=submit] (`ngClick`) *and* a submit handler on the enclosing form (`ngSubmit`) + * + * @param {string=} name Name of the form. If specified, the form controller will be published into + * related scope, under this name. + * + * @example + + + + + userType: + Required!
    + userType = {{userType}}
    + myForm.input.$valid = {{myForm.input.$valid}}
    + myForm.input.$error = {{myForm.input.$error}}
    + myForm.$valid = {{myForm.$valid}}
    + myForm.$error.REQUIRED = {{!!myForm.$error.REQUIRED}}
    + +
    + + it('should initialize to model', function() { + expect(binding('userType')).toEqual('guest'); + expect(binding('myForm.input.$valid')).toEqual('true'); + }); + + it('should be invalid if empty', function() { + input('userType').enter(''); + expect(binding('userType')).toEqual(''); + expect(binding('myForm.input.$valid')).toEqual('false'); + }); + +
    + */ +var formDirectiveFactory = function(isNgForm) { + return ['$timeout', function($timeout) { + var formDirective = { + name: 'form', + restrict: 'E', + controller: FormController, + compile: function() { + return { + pre: function(scope, formElement, attr, controller) { + if (!attr.action) { + // we can't use jq events because if a form is destroyed during submission the default + // action is not prevented. see #1238 + // + // IE 9 is not affected because it doesn't fire a submit event and try to do a full + // page reload if the form was destroyed by submission of the form via a click handler + // on a button in the form. Looks like an IE9 specific bug. + var preventDefaultListener = function(event) { + event.preventDefault + ? event.preventDefault() + : event.returnValue = false; // IE + }; + + addEventListenerFn(formElement[0], 'submit', preventDefaultListener); + + // unregister the preventDefault listener so that we don't not leak memory but in a + // way that will achieve the prevention of the default action. + formElement.bind('$destroy', function() { + $timeout(function() { + removeEventListenerFn(formElement[0], 'submit', preventDefaultListener); + }, 0, false); + }); + } + + var parentFormCtrl = formElement.parent().controller('form'), + alias = attr.name || attr.ngForm; + + if (alias) { + scope[alias] = controller; + } + if (parentFormCtrl) { + formElement.bind('$destroy', function() { + parentFormCtrl.$removeControl(controller); + if (alias) { + scope[alias] = undefined; + } + extend(controller, nullFormCtrl); //stop propagating child destruction handlers upwards + }); + } + } + }; + } + }; + + return isNgForm ? extend(copy(formDirective), {restrict: 'EAC'}) : formDirective; + }]; +}; + +var formDirective = formDirectiveFactory(); +var ngFormDirective = formDirectiveFactory(true); + +var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/; +var EMAIL_REGEXP = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/; +var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/; + +var inputType = { + + /** + * @ngdoc inputType + * @name ng.directive:input.text + * + * @description + * Standard HTML text input with angular data binding. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than + * minlength. + * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than + * maxlength. + * @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the + * RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for + * patterns defined as scope expressions. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
    + Single word: + + Required! + + Single word only! + + text = {{text}}
    + myForm.input.$valid = {{myForm.input.$valid}}
    + myForm.input.$error = {{myForm.input.$error}}
    + myForm.$valid = {{myForm.$valid}}
    + myForm.$error.required = {{!!myForm.$error.required}}
    +
    +
    + + it('should initialize to model', function() { + expect(binding('text')).toEqual('guest'); + expect(binding('myForm.input.$valid')).toEqual('true'); + }); + + it('should be invalid if empty', function() { + input('text').enter(''); + expect(binding('text')).toEqual(''); + expect(binding('myForm.input.$valid')).toEqual('false'); + }); + + it('should be invalid if multi word', function() { + input('text').enter('hello world'); + expect(binding('myForm.input.$valid')).toEqual('false'); + }); + +
    + */ + 'text': textInputType, + + + /** + * @ngdoc inputType + * @name ng.directive:input.number + * + * @description + * Text input with number validation and transformation. Sets the `number` validation + * error if not a valid number. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} min Sets the `min` validation error key if the value entered is less then `min`. + * @param {string=} max Sets the `max` validation error key if the value entered is greater then `min`. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than + * minlength. + * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than + * maxlength. + * @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the + * RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for + * patterns defined as scope expressions. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
    + Number: + + Required! + + Not valid number! + value = {{value}}
    + myForm.input.$valid = {{myForm.input.$valid}}
    + myForm.input.$error = {{myForm.input.$error}}
    + myForm.$valid = {{myForm.$valid}}
    + myForm.$error.required = {{!!myForm.$error.required}}
    +
    +
    + + it('should initialize to model', function() { + expect(binding('value')).toEqual('12'); + expect(binding('myForm.input.$valid')).toEqual('true'); + }); + + it('should be invalid if empty', function() { + input('value').enter(''); + expect(binding('value')).toEqual(''); + expect(binding('myForm.input.$valid')).toEqual('false'); + }); + + it('should be invalid if over max', function() { + input('value').enter('123'); + expect(binding('value')).toEqual(''); + expect(binding('myForm.input.$valid')).toEqual('false'); + }); + +
    + */ + 'number': numberInputType, + + + /** + * @ngdoc inputType + * @name ng.directive:input.url + * + * @description + * Text input with URL validation. Sets the `url` validation error key if the content is not a + * valid URL. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than + * minlength. + * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than + * maxlength. + * @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the + * RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for + * patterns defined as scope expressions. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
    + URL: + + Required! + + Not valid url! + text = {{text}}
    + myForm.input.$valid = {{myForm.input.$valid}}
    + myForm.input.$error = {{myForm.input.$error}}
    + myForm.$valid = {{myForm.$valid}}
    + myForm.$error.required = {{!!myForm.$error.required}}
    + myForm.$error.url = {{!!myForm.$error.url}}
    +
    +
    + + it('should initialize to model', function() { + expect(binding('text')).toEqual('http://google.com'); + expect(binding('myForm.input.$valid')).toEqual('true'); + }); + + it('should be invalid if empty', function() { + input('text').enter(''); + expect(binding('text')).toEqual(''); + expect(binding('myForm.input.$valid')).toEqual('false'); + }); + + it('should be invalid if not url', function() { + input('text').enter('xxx'); + expect(binding('myForm.input.$valid')).toEqual('false'); + }); + +
    + */ + 'url': urlInputType, + + + /** + * @ngdoc inputType + * @name ng.directive:input.email + * + * @description + * Text input with email validation. Sets the `email` validation error key if not a valid email + * address. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than + * minlength. + * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than + * maxlength. + * @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the + * RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for + * patterns defined as scope expressions. + * + * @example + + + +
    + Email: + + Required! + + Not valid email! + text = {{text}}
    + myForm.input.$valid = {{myForm.input.$valid}}
    + myForm.input.$error = {{myForm.input.$error}}
    + myForm.$valid = {{myForm.$valid}}
    + myForm.$error.required = {{!!myForm.$error.required}}
    + myForm.$error.email = {{!!myForm.$error.email}}
    +
    +
    + + it('should initialize to model', function() { + expect(binding('text')).toEqual('me@example.com'); + expect(binding('myForm.input.$valid')).toEqual('true'); + }); + + it('should be invalid if empty', function() { + input('text').enter(''); + expect(binding('text')).toEqual(''); + expect(binding('myForm.input.$valid')).toEqual('false'); + }); + + it('should be invalid if not email', function() { + input('text').enter('xxx'); + expect(binding('myForm.input.$valid')).toEqual('false'); + }); + +
    + */ + 'email': emailInputType, + + + /** + * @ngdoc inputType + * @name ng.directive:input.radio + * + * @description + * HTML radio button. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string} value The value to which the expression should be set when selected. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
    + Red
    + Green
    + Blue
    + color = {{color}}
    +
    +
    + + it('should change state', function() { + expect(binding('color')).toEqual('blue'); + + input('color').select('red'); + expect(binding('color')).toEqual('red'); + }); + +
    + */ + 'radio': radioInputType, + + + /** + * @ngdoc inputType + * @name ng.directive:input.checkbox + * + * @description + * HTML checkbox. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} ngTrueValue The value to which the expression should be set when selected. + * @param {string=} ngFalseValue The value to which the expression should be set when not selected. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
    + Value1:
    + Value2:
    + value1 = {{value1}}
    + value2 = {{value2}}
    +
    +
    + + it('should change state', function() { + expect(binding('value1')).toEqual('true'); + expect(binding('value2')).toEqual('YES'); + + input('value1').check(); + input('value2').check(); + expect(binding('value1')).toEqual('false'); + expect(binding('value2')).toEqual('NO'); + }); + +
    + */ + 'checkbox': checkboxInputType, + + 'hidden': noop, + 'button': noop, + 'submit': noop, + 'reset': noop +}; + + +function isEmpty(value) { + return isUndefined(value) || value === '' || value === null || value !== value; +} + + +function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { + + var listener = function() { + var value = trim(element.val()); + + if (ctrl.$viewValue !== value) { + scope.$apply(function() { + ctrl.$setViewValue(value); + }); + } + }; + + // if the browser does support "input" event, we are fine - except on IE9 which doesn't fire the + // input event on backspace, delete or cut + if ($sniffer.hasEvent('input')) { + element.bind('input', listener); + } else { + var timeout; + + element.bind('keydown', function(event) { + var key = event.keyCode; + + // ignore + // command modifiers arrows + if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return; + + if (!timeout) { + timeout = $browser.defer(function() { + listener(); + timeout = null; + }); + } + }); + + // if user paste into input using mouse, we need "change" event to catch it + element.bind('change', listener); + } + + + ctrl.$render = function() { + element.val(isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue); + }; + + // pattern validator + var pattern = attr.ngPattern, + patternValidator; + + var validate = function(regexp, value) { + if (isEmpty(value) || regexp.test(value)) { + ctrl.$setValidity('pattern', true); + return value; + } else { + ctrl.$setValidity('pattern', false); + return undefined; + } + }; + + if (pattern) { + if (pattern.match(/^\/(.*)\/$/)) { + pattern = new RegExp(pattern.substr(1, pattern.length - 2)); + patternValidator = function(value) { + return validate(pattern, value) + }; + } else { + patternValidator = function(value) { + var patternObj = scope.$eval(pattern); + + if (!patternObj || !patternObj.test) { + throw new Error('Expected ' + pattern + ' to be a RegExp but was ' + patternObj); + } + return validate(patternObj, value); + }; + } + + ctrl.$formatters.push(patternValidator); + ctrl.$parsers.push(patternValidator); + } + + // min length validator + if (attr.ngMinlength) { + var minlength = int(attr.ngMinlength); + var minLengthValidator = function(value) { + if (!isEmpty(value) && value.length < minlength) { + ctrl.$setValidity('minlength', false); + return undefined; + } else { + ctrl.$setValidity('minlength', true); + return value; + } + }; + + ctrl.$parsers.push(minLengthValidator); + ctrl.$formatters.push(minLengthValidator); + } + + // max length validator + if (attr.ngMaxlength) { + var maxlength = int(attr.ngMaxlength); + var maxLengthValidator = function(value) { + if (!isEmpty(value) && value.length > maxlength) { + ctrl.$setValidity('maxlength', false); + return undefined; + } else { + ctrl.$setValidity('maxlength', true); + return value; + } + }; + + ctrl.$parsers.push(maxLengthValidator); + ctrl.$formatters.push(maxLengthValidator); + } +} + +function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) { + textInputType(scope, element, attr, ctrl, $sniffer, $browser); + + ctrl.$parsers.push(function(value) { + var empty = isEmpty(value); + if (empty || NUMBER_REGEXP.test(value)) { + ctrl.$setValidity('number', true); + return value === '' ? null : (empty ? value : parseFloat(value)); + } else { + ctrl.$setValidity('number', false); + return undefined; + } + }); + + ctrl.$formatters.push(function(value) { + return isEmpty(value) ? '' : '' + value; + }); + + if (attr.min) { + var min = parseFloat(attr.min); + var minValidator = function(value) { + if (!isEmpty(value) && value < min) { + ctrl.$setValidity('min', false); + return undefined; + } else { + ctrl.$setValidity('min', true); + return value; + } + }; + + ctrl.$parsers.push(minValidator); + ctrl.$formatters.push(minValidator); + } + + if (attr.max) { + var max = parseFloat(attr.max); + var maxValidator = function(value) { + if (!isEmpty(value) && value > max) { + ctrl.$setValidity('max', false); + return undefined; + } else { + ctrl.$setValidity('max', true); + return value; + } + }; + + ctrl.$parsers.push(maxValidator); + ctrl.$formatters.push(maxValidator); + } + + ctrl.$formatters.push(function(value) { + + if (isEmpty(value) || isNumber(value)) { + ctrl.$setValidity('number', true); + return value; + } else { + ctrl.$setValidity('number', false); + return undefined; + } + }); +} + +function urlInputType(scope, element, attr, ctrl, $sniffer, $browser) { + textInputType(scope, element, attr, ctrl, $sniffer, $browser); + + var urlValidator = function(value) { + if (isEmpty(value) || URL_REGEXP.test(value)) { + ctrl.$setValidity('url', true); + return value; + } else { + ctrl.$setValidity('url', false); + return undefined; + } + }; + + ctrl.$formatters.push(urlValidator); + ctrl.$parsers.push(urlValidator); +} + +function emailInputType(scope, element, attr, ctrl, $sniffer, $browser) { + textInputType(scope, element, attr, ctrl, $sniffer, $browser); + + var emailValidator = function(value) { + if (isEmpty(value) || EMAIL_REGEXP.test(value)) { + ctrl.$setValidity('email', true); + return value; + } else { + ctrl.$setValidity('email', false); + return undefined; + } + }; + + ctrl.$formatters.push(emailValidator); + ctrl.$parsers.push(emailValidator); +} + +function radioInputType(scope, element, attr, ctrl) { + // make the name unique, if not defined + if (isUndefined(attr.name)) { + element.attr('name', nextUid()); + } + + element.bind('click', function() { + if (element[0].checked) { + scope.$apply(function() { + ctrl.$setViewValue(attr.value); + }); + } + }); + + ctrl.$render = function() { + var value = attr.value; + element[0].checked = (value == ctrl.$viewValue); + }; + + attr.$observe('value', ctrl.$render); +} + +function checkboxInputType(scope, element, attr, ctrl) { + var trueValue = attr.ngTrueValue, + falseValue = attr.ngFalseValue; + + if (!isString(trueValue)) trueValue = true; + if (!isString(falseValue)) falseValue = false; + + element.bind('click', function() { + scope.$apply(function() { + ctrl.$setViewValue(element[0].checked); + }); + }); + + ctrl.$render = function() { + element[0].checked = ctrl.$viewValue; + }; + + ctrl.$formatters.push(function(value) { + return value === trueValue; + }); + + ctrl.$parsers.push(function(value) { + return value ? trueValue : falseValue; + }); +} + + +/** + * @ngdoc directive + * @name ng.directive:textarea + * @restrict E + * + * @description + * HTML textarea element control with angular data-binding. The data-binding and validation + * properties of this element are exactly the same as those of the + * {@link ng.directive:input input element}. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than + * minlength. + * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than + * maxlength. + * @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the + * RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for + * patterns defined as scope expressions. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + */ + + +/** + * @ngdoc directive + * @name ng.directive:input + * @restrict E + * + * @description + * HTML input element control with angular data-binding. Input control follows HTML5 input types + * and polyfills the HTML5 validation behavior for older browsers. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than + * minlength. + * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than + * maxlength. + * @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the + * RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for + * patterns defined as scope expressions. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
    +
    + User name: + + Required!
    + Last name: + + Too short! + + Too long!
    +
    +
    + user = {{user}}
    + myForm.userName.$valid = {{myForm.userName.$valid}}
    + myForm.userName.$error = {{myForm.userName.$error}}
    + myForm.lastName.$valid = {{myForm.lastName.$valid}}
    + myForm.userName.$error = {{myForm.lastName.$error}}
    + myForm.$valid = {{myForm.$valid}}
    + myForm.$error.required = {{!!myForm.$error.required}}
    + myForm.$error.minlength = {{!!myForm.$error.minlength}}
    + myForm.$error.maxlength = {{!!myForm.$error.maxlength}}
    +
    +
    + + it('should initialize to model', function() { + expect(binding('user')).toEqual('{"name":"guest","last":"visitor"}'); + expect(binding('myForm.userName.$valid')).toEqual('true'); + expect(binding('myForm.$valid')).toEqual('true'); + }); + + it('should be invalid if empty when required', function() { + input('user.name').enter(''); + expect(binding('user')).toEqual('{"last":"visitor"}'); + expect(binding('myForm.userName.$valid')).toEqual('false'); + expect(binding('myForm.$valid')).toEqual('false'); + }); + + it('should be valid if empty when min length is set', function() { + input('user.last').enter(''); + expect(binding('user')).toEqual('{"name":"guest","last":""}'); + expect(binding('myForm.lastName.$valid')).toEqual('true'); + expect(binding('myForm.$valid')).toEqual('true'); + }); + + it('should be invalid if less than required min length', function() { + input('user.last').enter('xx'); + expect(binding('user')).toEqual('{"name":"guest"}'); + expect(binding('myForm.lastName.$valid')).toEqual('false'); + expect(binding('myForm.lastName.$error')).toMatch(/minlength/); + expect(binding('myForm.$valid')).toEqual('false'); + }); + + it('should be invalid if longer than max length', function() { + input('user.last').enter('some ridiculously long name'); + expect(binding('user')) + .toEqual('{"name":"guest"}'); + expect(binding('myForm.lastName.$valid')).toEqual('false'); + expect(binding('myForm.lastName.$error')).toMatch(/maxlength/); + expect(binding('myForm.$valid')).toEqual('false'); + }); + +
    + */ +var inputDirective = ['$browser', '$sniffer', function($browser, $sniffer) { + return { + restrict: 'E', + require: '?ngModel', + link: function(scope, element, attr, ctrl) { + if (ctrl) { + (inputType[lowercase(attr.type)] || inputType.text)(scope, element, attr, ctrl, $sniffer, + $browser); + } + } + }; +}]; + +var VALID_CLASS = 'ng-valid', + INVALID_CLASS = 'ng-invalid', + PRISTINE_CLASS = 'ng-pristine', + DIRTY_CLASS = 'ng-dirty'; + +/** + * @ngdoc object + * @name ng.directive:ngModel.NgModelController + * + * @property {string} $viewValue Actual string value in the view. + * @property {*} $modelValue The value in the model, that the control is bound to. + * @property {Array.} $parsers Whenever the control reads value from the DOM, it executes + * all of these functions to sanitize / convert the value as well as validate. + * + * @property {Array.} $formatters Whenever the model value changes, it executes all of + * these functions to convert the value as well as validate. + * + * @property {Object} $error An bject hash with all errors as keys. + * + * @property {boolean} $pristine True if user has not interacted with the control yet. + * @property {boolean} $dirty True if user has already interacted with the control. + * @property {boolean} $valid True if there is no error. + * @property {boolean} $invalid True if at least one error on the control. + * + * @description + * + * `NgModelController` provides API for the `ng-model` directive. The controller contains + * services for data-binding, validation, CSS update, value formatting and parsing. It + * specifically does not contain any logic which deals with DOM rendering or listening to + * DOM events. The `NgModelController` is meant to be extended by other directives where, the + * directive provides DOM manipulation and the `NgModelController` provides the data-binding. + * + * This example shows how to use `NgModelController` with a custom control to achieve + * data-binding. Notice how different directives (`contenteditable`, `ng-model`, and `required`) + * collaborate together to achieve the desired result. + * + * + + [contenteditable] { + border: 1px solid black; + background-color: white; + min-height: 20px; + } + + .ng-invalid { + border: 1px solid red; + } + + + + angular.module('customControl', []). + directive('contenteditable', function() { + return { + restrict: 'A', // only activate on element attribute + require: '?ngModel', // get a hold of NgModelController + link: function(scope, element, attrs, ngModel) { + if(!ngModel) return; // do nothing if no ng-model + + // Specify how UI should be updated + ngModel.$render = function() { + element.html(ngModel.$viewValue || ''); + }; + + // Listen for change events to enable binding + element.bind('blur keyup change', function() { + scope.$apply(read); + }); + read(); // initialize + + // Write data to the model + function read() { + ngModel.$setViewValue(element.html()); + } + } + }; + }); + + +
    +
    Change me!
    + Required! +
    + +
    +
    + + it('should data-bind and become invalid', function() { + var contentEditable = element('[contenteditable]'); + + expect(contentEditable.text()).toEqual('Change me!'); + input('userContent').enter(''); + expect(contentEditable.text()).toEqual(''); + expect(contentEditable.prop('className')).toMatch(/ng-invalid-required/); + }); + + *
    + * + */ +var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$parse', + function($scope, $exceptionHandler, $attr, $element, $parse) { + this.$viewValue = Number.NaN; + this.$modelValue = Number.NaN; + this.$parsers = []; + this.$formatters = []; + this.$viewChangeListeners = []; + this.$pristine = true; + this.$dirty = false; + this.$valid = true; + this.$invalid = false; + this.$name = $attr.name; + + var ngModelGet = $parse($attr.ngModel), + ngModelSet = ngModelGet.assign; + + if (!ngModelSet) { + throw Error(NON_ASSIGNABLE_MODEL_EXPRESSION + $attr.ngModel + + ' (' + startingTag($element) + ')'); + } + + /** + * @ngdoc function + * @name ng.directive:ngModel.NgModelController#$render + * @methodOf ng.directive:ngModel.NgModelController + * + * @description + * Called when the view needs to be updated. It is expected that the user of the ng-model + * directive will implement this method. + */ + this.$render = noop; + + var parentForm = $element.inheritedData('$formController') || nullFormCtrl, + invalidCount = 0, // used to easily determine if we are valid + $error = this.$error = {}; // keep invalid keys here + + + // Setup initial state of the control + $element.addClass(PRISTINE_CLASS); + toggleValidCss(true); + + // convenience method for easy toggling of classes + function toggleValidCss(isValid, validationErrorKey) { + validationErrorKey = validationErrorKey ? '-' + snake_case(validationErrorKey, '-') : ''; + $element. + removeClass((isValid ? INVALID_CLASS : VALID_CLASS) + validationErrorKey). + addClass((isValid ? VALID_CLASS : INVALID_CLASS) + validationErrorKey); + } + + /** + * @ngdoc function + * @name ng.directive:ngModel.NgModelController#$setValidity + * @methodOf ng.directive:ngModel.NgModelController + * + * @description + * Change the validity state, and notifies the form when the control changes validity. (i.e. it + * does not notify form if given validator is already marked as invalid). + * + * This method should be called by validators - i.e. the parser or formatter functions. + * + * @param {string} validationErrorKey Name of the validator. the `validationErrorKey` will assign + * to `$error[validationErrorKey]=isValid` so that it is available for data-binding. + * The `validationErrorKey` should be in camelCase and will get converted into dash-case + * for class name. Example: `myError` will result in `ng-valid-my-error` and `ng-invalid-my-error` + * class and can be bound to as `{{someForm.someControl.$error.myError}}` . + * @param {boolean} isValid Whether the current state is valid (true) or invalid (false). + */ + this.$setValidity = function(validationErrorKey, isValid) { + if ($error[validationErrorKey] === !isValid) return; + + if (isValid) { + if ($error[validationErrorKey]) invalidCount--; + if (!invalidCount) { + toggleValidCss(true); + this.$valid = true; + this.$invalid = false; + } + } else { + toggleValidCss(false); + this.$invalid = true; + this.$valid = false; + invalidCount++; + } + + $error[validationErrorKey] = !isValid; + toggleValidCss(isValid, validationErrorKey); + + parentForm.$setValidity(validationErrorKey, isValid, this); + }; + + + /** + * @ngdoc function + * @name ng.directive:ngModel.NgModelController#$setViewValue + * @methodOf ng.directive:ngModel.NgModelController + * + * @description + * Read a value from view. + * + * This method should be called from within a DOM event handler. + * For example {@link ng.directive:input input} or + * {@link ng.directive:select select} directives call it. + * + * It internally calls all `formatters` and if resulted value is valid, updates the model and + * calls all registered change listeners. + * + * @param {string} value Value from the view. + */ + this.$setViewValue = function(value) { + this.$viewValue = value; + + // change to dirty + if (this.$pristine) { + this.$dirty = true; + this.$pristine = false; + $element.removeClass(PRISTINE_CLASS).addClass(DIRTY_CLASS); + parentForm.$setDirty(); + } + + forEach(this.$parsers, function(fn) { + value = fn(value); + }); + + if (this.$modelValue !== value) { + this.$modelValue = value; + ngModelSet($scope, value); + forEach(this.$viewChangeListeners, function(listener) { + try { + listener(); + } catch(e) { + $exceptionHandler(e); + } + }) + } + }; + + // model -> value + var ctrl = this; + $scope.$watch(ngModelGet, function(value) { + + // ignore change from view + if (ctrl.$modelValue === value) return; + + var formatters = ctrl.$formatters, + idx = formatters.length; + + ctrl.$modelValue = value; + while(idx--) { + value = formatters[idx](value); + } + + if (ctrl.$viewValue !== value) { + ctrl.$viewValue = value; + ctrl.$render(); + } + }); +}]; + + +/** + * @ngdoc directive + * @name ng.directive:ngModel + * + * @element input + * + * @description + * Is directive that tells Angular to do two-way data binding. It works together with `input`, + * `select`, `textarea`. You can easily write your own directives to use `ngModel` as well. + * + * `ngModel` is responsible for: + * + * - binding the view into the model, which other directives such as `input`, `textarea` or `select` + * require, + * - providing validation behavior (i.e. required, number, email, url), + * - keeping state of the control (valid/invalid, dirty/pristine, validation errors), + * - setting related css class onto the element (`ng-valid`, `ng-invalid`, `ng-dirty`, `ng-pristine`), + * - register the control with parent {@link ng.directive:form form}. + * + * For basic examples, how to use `ngModel`, see: + * + * - {@link ng.directive:input input} + * - {@link ng.directive:input.text text} + * - {@link ng.directive:input.checkbox checkbox} + * - {@link ng.directive:input.radio radio} + * - {@link ng.directive:input.number number} + * - {@link ng.directive:input.email email} + * - {@link ng.directive:input.url url} + * - {@link ng.directive:select select} + * - {@link ng.directive:textarea textarea} + * + */ +var ngModelDirective = function() { + return { + require: ['ngModel', '^?form'], + controller: NgModelController, + link: function(scope, element, attr, ctrls) { + // notify others, especially parent forms + + var modelCtrl = ctrls[0], + formCtrl = ctrls[1] || nullFormCtrl; + + formCtrl.$addControl(modelCtrl); + + element.bind('$destroy', function() { + formCtrl.$removeControl(modelCtrl); + }); + } + }; +}; + + +/** + * @ngdoc directive + * @name ng.directive:ngChange + * @restrict E + * + * @description + * Evaluate given expression when user changes the input. + * The expression is not evaluated when the value change is coming from the model. + * + * Note, this directive requires `ngModel` to be present. + * + * @element input + * + * @example + * + * + * + *
    + * + * + *
    + * debug = {{confirmed}}
    + * counter = {{counter}} + *
    + *
    + * + * it('should evaluate the expression if changing from view', function() { + * expect(binding('counter')).toEqual('0'); + * element('#ng-change-example1').click(); + * expect(binding('counter')).toEqual('1'); + * expect(binding('confirmed')).toEqual('true'); + * }); + * + * it('should not evaluate the expression if changing from model', function() { + * element('#ng-change-example2').click(); + * expect(binding('counter')).toEqual('0'); + * expect(binding('confirmed')).toEqual('true'); + * }); + * + *
    + */ +var ngChangeDirective = valueFn({ + require: 'ngModel', + link: function(scope, element, attr, ctrl) { + ctrl.$viewChangeListeners.push(function() { + scope.$eval(attr.ngChange); + }); + } +}); + + +var requiredDirective = function() { + return { + require: '?ngModel', + link: function(scope, elm, attr, ctrl) { + if (!ctrl) return; + attr.required = true; // force truthy in case we are on non input element + + var validator = function(value) { + if (attr.required && (isEmpty(value) || value === false)) { + ctrl.$setValidity('required', false); + return; + } else { + ctrl.$setValidity('required', true); + return value; + } + }; + + ctrl.$formatters.push(validator); + ctrl.$parsers.unshift(validator); + + attr.$observe('required', function() { + validator(ctrl.$viewValue); + }); + } + }; +}; + + +/** + * @ngdoc directive + * @name ng.directive:ngList + * + * @description + * Text input that converts between comma-seperated string into an array of strings. + * + * @element input + * @param {string=} ngList optional delimiter that should be used to split the value. If + * specified in form `/something/` then the value will be converted into a regular expression. + * + * @example + + + +
    + List: + + Required! + names = {{names}}
    + myForm.namesInput.$valid = {{myForm.namesInput.$valid}}
    + myForm.namesInput.$error = {{myForm.namesInput.$error}}
    + myForm.$valid = {{myForm.$valid}}
    + myForm.$error.required = {{!!myForm.$error.required}}
    +
    +
    + + it('should initialize to model', function() { + expect(binding('names')).toEqual('["igor","misko","vojta"]'); + expect(binding('myForm.namesInput.$valid')).toEqual('true'); + }); + + it('should be invalid if empty', function() { + input('names').enter(''); + expect(binding('names')).toEqual('[]'); + expect(binding('myForm.namesInput.$valid')).toEqual('false'); + }); + +
    + */ +var ngListDirective = function() { + return { + require: 'ngModel', + link: function(scope, element, attr, ctrl) { + var match = /\/(.*)\//.exec(attr.ngList), + separator = match && new RegExp(match[1]) || attr.ngList || ','; + + var parse = function(viewValue) { + var list = []; + + if (viewValue) { + forEach(viewValue.split(separator), function(value) { + if (value) list.push(trim(value)); + }); + } + + return list; + }; + + ctrl.$parsers.push(parse); + ctrl.$formatters.push(function(value) { + if (isArray(value)) { + return value.join(', '); + } + + return undefined; + }); + } + }; +}; + + +var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/; + +var ngValueDirective = function() { + return { + priority: 100, + compile: function(tpl, tplAttr) { + if (CONSTANT_VALUE_REGEXP.test(tplAttr.ngValue)) { + return function(scope, elm, attr) { + attr.$set('value', scope.$eval(attr.ngValue)); + }; + } else { + return function(scope, elm, attr) { + scope.$watch(attr.ngValue, function(value) { + attr.$set('value', value, false); + }); + }; + } + } + }; +}; + +/** + * @ngdoc directive + * @name ng.directive:ngBind + * + * @description + * The `ngBind` attribute tells Angular to replace the text content of the specified HTML element + * with the value of a given expression, and to update the text content when the value of that + * expression changes. + * + * Typically, you don't use `ngBind` directly, but instead you use the double curly markup like + * `{{ expression }}` which is similar but less verbose. + * + * Once scenario in which the use of `ngBind` is prefered over `{{ expression }}` binding is when + * it's desirable to put bindings into template that is momentarily displayed by the browser in its + * raw state before Angular compiles it. Since `ngBind` is an element attribute, it makes the + * bindings invisible to the user while the page is loading. + * + * An alternative solution to this problem would be using the + * {@link ng.directive:ngCloak ngCloak} directive. + * + * + * @element ANY + * @param {expression} ngBind {@link guide/expression Expression} to evaluate. + * + * @example + * Enter a name in the Live Preview text box; the greeting below the text box changes instantly. + + + +
    + Enter name:
    + Hello ! +
    +
    + + it('should check ng-bind', function() { + expect(using('.doc-example-live').binding('name')).toBe('Whirled'); + using('.doc-example-live').input('name').enter('world'); + expect(using('.doc-example-live').binding('name')).toBe('world'); + }); + +
    + */ +var ngBindDirective = ngDirective(function(scope, element, attr) { + element.addClass('ng-binding').data('$binding', attr.ngBind); + scope.$watch(attr.ngBind, function(value) { + element.text(value == undefined ? '' : value); + }); +}); + + +/** + * @ngdoc directive + * @name ng.directive:ngBindTemplate + * + * @description + * The `ngBindTemplate` directive specifies that the element + * text should be replaced with the template in ngBindTemplate. + * Unlike ngBind the ngBindTemplate can contain multiple `{{` `}}` + * expressions. (This is required since some HTML elements + * can not have SPAN elements such as TITLE, or OPTION to name a few.) + * + * @element ANY + * @param {string} ngBindTemplate template of form + * {{ expression }} to eval. + * + * @example + * Try it here: enter text in text box and watch the greeting change. + + + +
    + Salutation:
    + Name:
    +
    
    +       
    +
    + + it('should check ng-bind', function() { + expect(using('.doc-example-live').binding('salutation')). + toBe('Hello'); + expect(using('.doc-example-live').binding('name')). + toBe('World'); + using('.doc-example-live').input('salutation').enter('Greetings'); + using('.doc-example-live').input('name').enter('user'); + expect(using('.doc-example-live').binding('salutation')). + toBe('Greetings'); + expect(using('.doc-example-live').binding('name')). + toBe('user'); + }); + +
    + */ +var ngBindTemplateDirective = ['$interpolate', function($interpolate) { + return function(scope, element, attr) { + // TODO: move this to scenario runner + var interpolateFn = $interpolate(element.attr(attr.$attr.ngBindTemplate)); + element.addClass('ng-binding').data('$binding', interpolateFn); + attr.$observe('ngBindTemplate', function(value) { + element.text(value); + }); + } +}]; + + +/** + * @ngdoc directive + * @name ng.directive:ngBindHtmlUnsafe + * + * @description + * Creates a binding that will innerHTML the result of evaluating the `expression` into the current + * element. *The innerHTML-ed content will not be sanitized!* You should use this directive only if + * {@link ngSanitize.directive:ngBindHtml ngBindHtml} directive is too + * restrictive and when you absolutely trust the source of the content you are binding to. + * + * See {@link ngSanitize.$sanitize $sanitize} docs for examples. + * + * @element ANY + * @param {expression} ngBindHtmlUnsafe {@link guide/expression Expression} to evaluate. + */ +var ngBindHtmlUnsafeDirective = [function() { + return function(scope, element, attr) { + element.addClass('ng-binding').data('$binding', attr.ngBindHtmlUnsafe); + scope.$watch(attr.ngBindHtmlUnsafe, function(value) { + element.html(value || ''); + }); + }; +}]; + +function classDirective(name, selector) { + name = 'ngClass' + name; + return ngDirective(function(scope, element, attr) { + scope.$watch(attr[name], function(newVal, oldVal) { + if (selector === true || scope.$index % 2 === selector) { + if (oldVal && (newVal !== oldVal)) { + if (isObject(oldVal) && !isArray(oldVal)) + oldVal = map(oldVal, function(v, k) { if (v) return k }); + element.removeClass(isArray(oldVal) ? oldVal.join(' ') : oldVal); + } + if (isObject(newVal) && !isArray(newVal)) + newVal = map(newVal, function(v, k) { if (v) return k }); + if (newVal) element.addClass(isArray(newVal) ? newVal.join(' ') : newVal); } + }, true); + }); +} + +/** + * @ngdoc directive + * @name ng.directive:ngClass + * + * @description + * The `ngClass` allows you to set CSS class on HTML element dynamically by databinding an + * expression that represents all classes to be added. + * + * The directive won't add duplicate classes if a particular class was already set. + * + * When the expression changes, the previously added classes are removed and only then the classes + * new classes are added. + * + * @element ANY + * @param {expression} ngClass {@link guide/expression Expression} to eval. The result + * of the evaluation can be a string representing space delimited class + * names, an array, or a map of class names to boolean values. + * + * @example + + + + +
    + Sample Text +
    + + .my-class { + color: red; + } + + + it('should check ng-class', function() { + expect(element('.doc-example-live span').prop('className')).not(). + toMatch(/my-class/); + + using('.doc-example-live').element(':button:first').click(); + + expect(element('.doc-example-live span').prop('className')). + toMatch(/my-class/); + + using('.doc-example-live').element(':button:last').click(); + + expect(element('.doc-example-live span').prop('className')).not(). + toMatch(/my-class/); + }); + +
    + */ +var ngClassDirective = classDirective('', true); + +/** + * @ngdoc directive + * @name ng.directive:ngClassOdd + * + * @description + * The `ngClassOdd` and `ngClassEven` directives work exactly as + * {@link ng.directive:ngClass ngClass}, except it works in + * conjunction with `ngRepeat` and takes affect only on odd (even) rows. + * + * This directive can be applied only within a scope of an + * {@link ng.directive:ngRepeat ngRepeat}. + * + * @element ANY + * @param {expression} ngClassOdd {@link guide/expression Expression} to eval. The result + * of the evaluation can be a string representing space delimited class names or an array. + * + * @example + + +
      +
    1. + + {{name}} + +
    2. +
    +
    + + .odd { + color: red; + } + .even { + color: blue; + } + + + it('should check ng-class-odd and ng-class-even', function() { + expect(element('.doc-example-live li:first span').prop('className')). + toMatch(/odd/); + expect(element('.doc-example-live li:last span').prop('className')). + toMatch(/even/); + }); + +
    + */ +var ngClassOddDirective = classDirective('Odd', 0); + +/** + * @ngdoc directive + * @name ng.directive:ngClassEven + * + * @description + * The `ngClassOdd` and `ngClassEven` works exactly as + * {@link ng.directive:ngClass ngClass}, except it works in + * conjunction with `ngRepeat` and takes affect only on odd (even) rows. + * + * This directive can be applied only within a scope of an + * {@link ng.directive:ngRepeat ngRepeat}. + * + * @element ANY + * @param {expression} ngClassEven {@link guide/expression Expression} to eval. The + * result of the evaluation can be a string representing space delimited class names or an array. + * + * @example + + +
      +
    1. + + {{name}}       + +
    2. +
    +
    + + .odd { + color: red; + } + .even { + color: blue; + } + + + it('should check ng-class-odd and ng-class-even', function() { + expect(element('.doc-example-live li:first span').prop('className')). + toMatch(/odd/); + expect(element('.doc-example-live li:last span').prop('className')). + toMatch(/even/); + }); + +
    + */ +var ngClassEvenDirective = classDirective('Even', 1); + +/** + * @ngdoc directive + * @name ng.directive:ngCloak + * + * @description + * The `ngCloak` directive is used to prevent the Angular html template from being briefly + * displayed by the browser in its raw (uncompiled) form while your application is loading. Use this + * directive to avoid the undesirable flicker effect caused by the html template display. + * + * The directive can be applied to the `` element, but typically a fine-grained application is + * prefered in order to benefit from progressive rendering of the browser view. + * + * `ngCloak` works in cooperation with a css rule that is embedded within `angular.js` and + * `angular.min.js` files. Following is the css rule: + * + *
    + * [ng\:cloak], [ng-cloak], .ng-cloak {
    + *   display: none;
    + * }
    + * 
    + * + * When this css rule is loaded by the browser, all html elements (including their children) that + * are tagged with the `ng-cloak` directive are hidden. When Angular comes across this directive + * during the compilation of the template it deletes the `ngCloak` element attribute, which + * makes the compiled element visible. + * + * For the best result, `angular.js` script must be loaded in the head section of the html file; + * alternatively, the css rule (above) must be included in the external stylesheet of the + * application. + * + * Legacy browsers, like IE7, do not provide attribute selector support (added in CSS 2.1) so they + * cannot match the `[ng\:cloak]` selector. To work around this limitation, you must add the css + * class `ngCloak` in addition to `ngCloak` directive as shown in the example below. + * + * @element ANY + * + * @example + + +
    {{ 'hello' }}
    +
    {{ 'hello IE7' }}
    +
    + + it('should remove the template directive and css class', function() { + expect(element('.doc-example-live #template1').attr('ng-cloak')). + not().toBeDefined(); + expect(element('.doc-example-live #template2').attr('ng-cloak')). + not().toBeDefined(); + }); + +
    + * + */ +var ngCloakDirective = ngDirective({ + compile: function(element, attr) { + attr.$set('ngCloak', undefined); + element.removeClass('ng-cloak'); + } +}); + +/** + * @ngdoc directive + * @name ng.directive:ngController + * + * @description + * The `ngController` directive assigns behavior to a scope. This is a key aspect of how angular + * supports the principles behind the Model-View-Controller design pattern. + * + * MVC components in angular: + * + * * Model — The Model is data in scope properties; scopes are attached to the DOM. + * * View — The template (HTML with data bindings) is rendered into the View. + * * Controller — The `ngController` directive specifies a Controller class; the class has + * methods that typically express the business logic behind the application. + * + * Note that an alternative way to define controllers is via the `{@link ng.$route}` + * service. + * + * @element ANY + * @scope + * @param {expression} ngController Name of a globally accessible constructor function or an + * {@link guide/expression expression} that on the current scope evaluates to a + * constructor function. + * + * @example + * Here is a simple form for editing user contact information. Adding, removing, clearing, and + * greeting are methods declared on the controller (see source tab). These methods can + * easily be called from the angular markup. Notice that the scope becomes the `this` for the + * controller's instance. This allows for easy access to the view data from the controller. Also + * notice that any changes to the data are automatically reflected in the View without the need + * for a manual update. + + + +
    + Name: + [ greet ]
    + Contact: +
      +
    • + + + [ clear + | X ] +
    • +
    • [ add ]
    • +
    +
    +
    + + it('should check controller', function() { + expect(element('.doc-example-live div>:input').val()).toBe('John Smith'); + expect(element('.doc-example-live li:nth-child(1) input').val()) + .toBe('408 555 1212'); + expect(element('.doc-example-live li:nth-child(2) input').val()) + .toBe('john.smith@example.org'); + + element('.doc-example-live li:first a:contains("clear")').click(); + expect(element('.doc-example-live li:first input').val()).toBe(''); + + element('.doc-example-live li:last a:contains("add")').click(); + expect(element('.doc-example-live li:nth-child(3) input').val()) + .toBe('yourname@example.org'); + }); + +
    + */ +var ngControllerDirective = [function() { + return { + scope: true, + controller: '@' + }; +}]; + +/** + * @ngdoc directive + * @name ng.directive:ngCsp + * @priority 1000 + * + * @description + * Enables [CSP (Content Security Policy)](https://developer.mozilla.org/en/Security/CSP) support. + * This directive should be used on the root element of the application (typically the `` + * element or other element with the {@link ng.directive:ngApp ngApp} + * directive). + * + * If enabled the performance of template expression evaluator will suffer slightly, so don't enable + * this mode unless you need it. + * + * @element html + */ + +var ngCspDirective = ['$sniffer', function($sniffer) { + return { + priority: 1000, + compile: function() { + $sniffer.csp = true; + } + }; +}]; + +/** + * @ngdoc directive + * @name ng.directive:ngClick + * + * @description + * The ngClick allows you to specify custom behavior when + * element is clicked. + * + * @element ANY + * @param {expression} ngClick {@link guide/expression Expression} to evaluate upon + * click. (Event object is available as `$event`) + * + * @example + + + + count: {{count}} + + + it('should check ng-click', function() { + expect(binding('count')).toBe('0'); + element('.doc-example-live :button').click(); + expect(binding('count')).toBe('1'); + }); + + + */ +/* + * A directive that allows creation of custom onclick handlers that are defined as angular + * expressions and are compiled and executed within the current scope. + * + * Events that are handled via these handler are always configured not to propagate further. + */ +var ngEventDirectives = {}; +forEach( + 'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave'.split(' '), + function(name) { + var directiveName = directiveNormalize('ng-' + name); + ngEventDirectives[directiveName] = ['$parse', function($parse) { + return function(scope, element, attr) { + var fn = $parse(attr[directiveName]); + element.bind(lowercase(name), function(event) { + scope.$apply(function() { + fn(scope, {$event:event}); + }); + }); + }; + }]; + } +); + +/** + * @ngdoc directive + * @name ng.directive:ngDblclick + * + * @description + * The `ngDblclick` directive allows you to specify custom behavior on dblclick event. + * + * @element ANY + * @param {expression} ngDblclick {@link guide/expression Expression} to evaluate upon + * dblclick. (Event object is available as `$event`) + * + * @example + * See {@link ng.directive:ngClick ngClick} + */ + + +/** + * @ngdoc directive + * @name ng.directive:ngMousedown + * + * @description + * The ngMousedown directive allows you to specify custom behavior on mousedown event. + * + * @element ANY + * @param {expression} ngMousedown {@link guide/expression Expression} to evaluate upon + * mousedown. (Event object is available as `$event`) + * + * @example + * See {@link ng.directive:ngClick ngClick} + */ + + +/** + * @ngdoc directive + * @name ng.directive:ngMouseup + * + * @description + * Specify custom behavior on mouseup event. + * + * @element ANY + * @param {expression} ngMouseup {@link guide/expression Expression} to evaluate upon + * mouseup. (Event object is available as `$event`) + * + * @example + * See {@link ng.directive:ngClick ngClick} + */ + +/** + * @ngdoc directive + * @name ng.directive:ngMouseover + * + * @description + * Specify custom behavior on mouseover event. + * + * @element ANY + * @param {expression} ngMouseover {@link guide/expression Expression} to evaluate upon + * mouseover. (Event object is available as `$event`) + * + * @example + * See {@link ng.directive:ngClick ngClick} + */ + + +/** + * @ngdoc directive + * @name ng.directive:ngMouseenter + * + * @description + * Specify custom behavior on mouseenter event. + * + * @element ANY + * @param {expression} ngMouseenter {@link guide/expression Expression} to evaluate upon + * mouseenter. (Event object is available as `$event`) + * + * @example + * See {@link ng.directive:ngClick ngClick} + */ + + +/** + * @ngdoc directive + * @name ng.directive:ngMouseleave + * + * @description + * Specify custom behavior on mouseleave event. + * + * @element ANY + * @param {expression} ngMouseleave {@link guide/expression Expression} to evaluate upon + * mouseleave. (Event object is available as `$event`) + * + * @example + * See {@link ng.directive:ngClick ngClick} + */ + + +/** + * @ngdoc directive + * @name ng.directive:ngMousemove + * + * @description + * Specify custom behavior on mousemove event. + * + * @element ANY + * @param {expression} ngMousemove {@link guide/expression Expression} to evaluate upon + * mousemove. (Event object is available as `$event`) + * + * @example + * See {@link ng.directive:ngClick ngClick} + */ + + +/** + * @ngdoc directive + * @name ng.directive:ngSubmit + * + * @description + * Enables binding angular expressions to onsubmit events. + * + * Additionally it prevents the default action (which for form means sending the request to the + * server and reloading the current page). + * + * @element form + * @param {expression} ngSubmit {@link guide/expression Expression} to eval. + * + * @example + + + +
    + Enter text and hit enter: + + +
    list={{list}}
    +
    +
    + + it('should check ng-submit', function() { + expect(binding('list')).toBe('[]'); + element('.doc-example-live #submit').click(); + expect(binding('list')).toBe('["hello"]'); + expect(input('text').val()).toBe(''); + }); + it('should ignore empty strings', function() { + expect(binding('list')).toBe('[]'); + element('.doc-example-live #submit').click(); + element('.doc-example-live #submit').click(); + expect(binding('list')).toBe('["hello"]'); + }); + +
    + */ +var ngSubmitDirective = ngDirective(function(scope, element, attrs) { + element.bind('submit', function() { + scope.$apply(attrs.ngSubmit); + }); +}); + +/** + * @ngdoc directive + * @name ng.directive:ngInclude + * @restrict ECA + * + * @description + * Fetches, compiles and includes an external HTML fragment. + * + * Keep in mind that Same Origin Policy applies to included resources + * (e.g. ngInclude won't work for cross-domain requests on all browsers and for + * file:// access on some browsers). + * + * @scope + * + * @param {string} ngInclude|src angular expression evaluating to URL. If the source is a string constant, + * make sure you wrap it in quotes, e.g. `src="'myPartialTemplate.html'"`. + * @param {string=} onload Expression to evaluate when a new partial is loaded. + * + * @param {string=} autoscroll Whether `ngInclude` should call {@link ng.$anchorScroll + * $anchorScroll} to scroll the viewport after the content is loaded. + * + * - If the attribute is not set, disable scrolling. + * - If the attribute is set without value, enable scrolling. + * - Otherwise enable scrolling only if the expression evaluates to truthy value. + * + * @example + + +
    + + url of the template: {{template.url}} +
    +
    +
    +
    + + function Ctrl($scope) { + $scope.templates = + [ { name: 'template1.html', url: 'template1.html'} + , { name: 'template2.html', url: 'template2.html'} ]; + $scope.template = $scope.templates[0]; + } + + + Content of template1.html + + + Content of template2.html + + + it('should load template1.html', function() { + expect(element('.doc-example-live [ng-include]').text()). + toMatch(/Content of template1.html/); + }); + it('should load template2.html', function() { + select('template').option('1'); + expect(element('.doc-example-live [ng-include]').text()). + toMatch(/Content of template2.html/); + }); + it('should change to blank', function() { + select('template').option(''); + expect(element('.doc-example-live [ng-include]').text()).toEqual(''); + }); + +
    + */ + + +/** + * @ngdoc event + * @name ng.directive:ngInclude#$includeContentLoaded + * @eventOf ng.directive:ngInclude + * @eventType emit on the current ngInclude scope + * @description + * Emitted every time the ngInclude content is reloaded. + */ +var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile', + function($http, $templateCache, $anchorScroll, $compile) { + return { + restrict: 'ECA', + terminal: true, + compile: function(element, attr) { + var srcExp = attr.ngInclude || attr.src, + onloadExp = attr.onload || '', + autoScrollExp = attr.autoscroll; + + return function(scope, element) { + var changeCounter = 0, + childScope; + + var clearContent = function() { + if (childScope) { + childScope.$destroy(); + childScope = null; + } + + element.html(''); + }; + + scope.$watch(srcExp, function(src) { + var thisChangeId = ++changeCounter; + + if (src) { + $http.get(src, {cache: $templateCache}).success(function(response) { + if (thisChangeId !== changeCounter) return; + + if (childScope) childScope.$destroy(); + childScope = scope.$new(); + + element.html(response); + $compile(element.contents())(childScope); + + if (isDefined(autoScrollExp) && (!autoScrollExp || scope.$eval(autoScrollExp))) { + $anchorScroll(); + } + + childScope.$emit('$includeContentLoaded'); + scope.$eval(onloadExp); + }).error(function() { + if (thisChangeId === changeCounter) clearContent(); + }); + } else clearContent(); + }); + }; + } + }; +}]; + +/** + * @ngdoc directive + * @name ng.directive:ngInit + * + * @description + * The `ngInit` directive specifies initialization tasks to be executed + * before the template enters execution mode during bootstrap. + * + * @element ANY + * @param {expression} ngInit {@link guide/expression Expression} to eval. + * + * @example + + +
    + {{greeting}} {{person}}! +
    +
    + + it('should check greeting', function() { + expect(binding('greeting')).toBe('Hello'); + expect(binding('person')).toBe('World'); + }); + +
    + */ +var ngInitDirective = ngDirective({ + compile: function() { + return { + pre: function(scope, element, attrs) { + scope.$eval(attrs.ngInit); + } + } + } +}); + +/** + * @ngdoc directive + * @name ng.directive:ngNonBindable + * @priority 1000 + * + * @description + * Sometimes it is necessary to write code which looks like bindings but which should be left alone + * by angular. Use `ngNonBindable` to make angular ignore a chunk of HTML. + * + * @element ANY + * + * @example + * In this example there are two location where a simple binding (`{{}}`) is present, but the one + * wrapped in `ngNonBindable` is left alone. + * + * @example + + +
    Normal: {{1 + 2}}
    +
    Ignored: {{1 + 2}}
    +
    + + it('should check ng-non-bindable', function() { + expect(using('.doc-example-live').binding('1 + 2')).toBe('3'); + expect(using('.doc-example-live').element('div:last').text()). + toMatch(/1 \+ 2/); + }); + +
    + */ +var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 }); + +/** + * @ngdoc directive + * @name ng.directive:ngPluralize + * @restrict EA + * + * @description + * # Overview + * `ngPluralize` is a directive that displays messages according to en-US localization rules. + * These rules are bundled with angular.js and the rules can be overridden + * (see {@link guide/i18n Angular i18n} dev guide). You configure ngPluralize directive + * by specifying the mappings between + * {@link http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html + * plural categories} and the strings to be displayed. + * + * # Plural categories and explicit number rules + * There are two + * {@link http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html + * plural categories} in Angular's default en-US locale: "one" and "other". + * + * While a pural category may match many numbers (for example, in en-US locale, "other" can match + * any number that is not 1), an explicit number rule can only match one number. For example, the + * explicit number rule for "3" matches the number 3. You will see the use of plural categories + * and explicit number rules throughout later parts of this documentation. + * + * # Configuring ngPluralize + * You configure ngPluralize by providing 2 attributes: `count` and `when`. + * You can also provide an optional attribute, `offset`. + * + * The value of the `count` attribute can be either a string or an {@link guide/expression + * Angular expression}; these are evaluated on the current scope for its bound value. + * + * The `when` attribute specifies the mappings between plural categories and the actual + * string to be displayed. The value of the attribute should be a JSON object so that Angular + * can interpret it correctly. + * + * The following example shows how to configure ngPluralize: + * + *
    + * 
    + * 
    + *
    + * + * In the example, `"0: Nobody is viewing."` is an explicit number rule. If you did not + * specify this rule, 0 would be matched to the "other" category and "0 people are viewing" + * would be shown instead of "Nobody is viewing". You can specify an explicit number rule for + * other numbers, for example 12, so that instead of showing "12 people are viewing", you can + * show "a dozen people are viewing". + * + * You can use a set of closed braces(`{}`) as a placeholder for the number that you want substituted + * into pluralized strings. In the previous example, Angular will replace `{}` with + * `{{personCount}}`. The closed braces `{}` is a placeholder + * for {{numberExpression}}. + * + * # Configuring ngPluralize with offset + * The `offset` attribute allows further customization of pluralized text, which can result in + * a better user experience. For example, instead of the message "4 people are viewing this document", + * you might display "John, Kate and 2 others are viewing this document". + * The offset attribute allows you to offset a number by any desired value. + * Let's take a look at an example: + * + *
    + * 
    + * 
    + * 
    + * + * Notice that we are still using two plural categories(one, other), but we added + * three explicit number rules 0, 1 and 2. + * When one person, perhaps John, views the document, "John is viewing" will be shown. + * When three people view the document, no explicit number rule is found, so + * an offset of 2 is taken off 3, and Angular uses 1 to decide the plural category. + * In this case, plural category 'one' is matched and "John, Marry and one other person are viewing" + * is shown. + * + * Note that when you specify offsets, you must provide explicit number rules for + * numbers from 0 up to and including the offset. If you use an offset of 3, for example, + * you must provide explicit number rules for 0, 1, 2 and 3. You must also provide plural strings for + * plural categories "one" and "other". + * + * @param {string|expression} count The variable to be bounded to. + * @param {string} when The mapping between plural category to its correspoding strings. + * @param {number=} offset Offset to deduct from the total number. + * + * @example + + + +
    + Person 1:
    + Person 2:
    + Number of People:
    + + + Without Offset: + +
    + + + With Offset(2): + + +
    +
    + + it('should show correct pluralized string', function() { + expect(element('.doc-example-live ng-pluralize:first').text()). + toBe('1 person is viewing.'); + expect(element('.doc-example-live ng-pluralize:last').text()). + toBe('Igor is viewing.'); + + using('.doc-example-live').input('personCount').enter('0'); + expect(element('.doc-example-live ng-pluralize:first').text()). + toBe('Nobody is viewing.'); + expect(element('.doc-example-live ng-pluralize:last').text()). + toBe('Nobody is viewing.'); + + using('.doc-example-live').input('personCount').enter('2'); + expect(element('.doc-example-live ng-pluralize:first').text()). + toBe('2 people are viewing.'); + expect(element('.doc-example-live ng-pluralize:last').text()). + toBe('Igor and Misko are viewing.'); + + using('.doc-example-live').input('personCount').enter('3'); + expect(element('.doc-example-live ng-pluralize:first').text()). + toBe('3 people are viewing.'); + expect(element('.doc-example-live ng-pluralize:last').text()). + toBe('Igor, Misko and one other person are viewing.'); + + using('.doc-example-live').input('personCount').enter('4'); + expect(element('.doc-example-live ng-pluralize:first').text()). + toBe('4 people are viewing.'); + expect(element('.doc-example-live ng-pluralize:last').text()). + toBe('Igor, Misko and 2 other people are viewing.'); + }); + + it('should show data-binded names', function() { + using('.doc-example-live').input('personCount').enter('4'); + expect(element('.doc-example-live ng-pluralize:last').text()). + toBe('Igor, Misko and 2 other people are viewing.'); + + using('.doc-example-live').input('person1').enter('Di'); + using('.doc-example-live').input('person2').enter('Vojta'); + expect(element('.doc-example-live ng-pluralize:last').text()). + toBe('Di, Vojta and 2 other people are viewing.'); + }); + +
    + */ +var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interpolate) { + var BRACE = /{}/g; + return { + restrict: 'EA', + link: function(scope, element, attr) { + var numberExp = attr.count, + whenExp = element.attr(attr.$attr.when), // this is because we have {{}} in attrs + offset = attr.offset || 0, + whens = scope.$eval(whenExp), + whensExpFns = {}, + startSymbol = $interpolate.startSymbol(), + endSymbol = $interpolate.endSymbol(); + + forEach(whens, function(expression, key) { + whensExpFns[key] = + $interpolate(expression.replace(BRACE, startSymbol + numberExp + '-' + + offset + endSymbol)); + }); + + scope.$watch(function() { + var value = parseFloat(scope.$eval(numberExp)); + + if (!isNaN(value)) { + //if explicit number rule such as 1, 2, 3... is defined, just use it. Otherwise, + //check it against pluralization rules in $locale service + if (!whens[value]) value = $locale.pluralCat(value - offset); + return whensExpFns[value](scope, element, true); + } else { + return ''; + } + }, function(newVal) { + element.text(newVal); + }); + } + }; +}]; + +/** + * @ngdoc directive + * @name ng.directive:ngRepeat + * + * @description + * The `ngRepeat` directive instantiates a template once per item from a collection. Each template + * instance gets its own scope, where the given loop variable is set to the current collection item, + * and `$index` is set to the item index or key. + * + * Special properties are exposed on the local scope of each template instance, including: + * + * * `$index` – `{number}` – iterator offset of the repeated element (0..length-1) + * * `$first` – `{boolean}` – true if the repeated element is first in the iterator. + * * `$middle` – `{boolean}` – true if the repeated element is between the first and last in the iterator. + * * `$last` – `{boolean}` – true if the repeated element is last in the iterator. + * + * + * @element ANY + * @scope + * @priority 1000 + * @param {repeat_expression} ngRepeat The expression indicating how to enumerate a collection. Two + * formats are currently supported: + * + * * `variable in expression` – where variable is the user defined loop variable and `expression` + * is a scope expression giving the collection to enumerate. + * + * For example: `track in cd.tracks`. + * + * * `(key, value) in expression` – where `key` and `value` can be any user defined identifiers, + * and `expression` is the scope expression giving the collection to enumerate. + * + * For example: `(name, age) in {'adam':10, 'amalie':12}`. + * + * @example + * This example initializes the scope to a list of names and + * then uses `ngRepeat` to display every person: + + +
    + I have {{friends.length}} friends. They are: +
      +
    • + [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old. +
    • +
    +
    +
    + + it('should check ng-repeat', function() { + var r = using('.doc-example-live').repeater('ul li'); + expect(r.count()).toBe(2); + expect(r.row(0)).toEqual(["1","John","25"]); + expect(r.row(1)).toEqual(["2","Mary","28"]); + }); + +
    + */ +var ngRepeatDirective = ngDirective({ + transclude: 'element', + priority: 1000, + terminal: true, + compile: function(element, attr, linker) { + return function(scope, iterStartElement, attr){ + var expression = attr.ngRepeat; + var match = expression.match(/^\s*(.+)\s+in\s+(.*)\s*$/), + lhs, rhs, valueIdent, keyIdent; + if (! match) { + throw Error("Expected ngRepeat in form of '_item_ in _collection_' but got '" + + expression + "'."); + } + lhs = match[1]; + rhs = match[2]; + match = lhs.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/); + if (!match) { + throw Error("'item' in 'item in collection' should be identifier or (key, value) but got '" + + lhs + "'."); + } + valueIdent = match[3] || match[1]; + keyIdent = match[2]; + + // Store a list of elements from previous run. This is a hash where key is the item from the + // iterator, and the value is an array of objects with following properties. + // - scope: bound scope + // - element: previous element. + // - index: position + // We need an array of these objects since the same object can be returned from the iterator. + // We expect this to be a rare case. + var lastOrder = new HashQueueMap(); + scope.$watch(function(scope){ + var index, length, + collection = scope.$eval(rhs), + collectionLength = size(collection, true), + childScope, + // Same as lastOrder but it has the current state. It will become the + // lastOrder on the next iteration. + nextOrder = new HashQueueMap(), + key, value, // key/value of iteration + array, last, // last object information {scope, element, index} + cursor = iterStartElement; // current position of the node + + if (!isArray(collection)) { + // if object, extract keys, sort them and use to determine order of iteration over obj props + array = []; + for(key in collection) { + if (collection.hasOwnProperty(key) && key.charAt(0) != '$') { + array.push(key); + } + } + array.sort(); + } else { + array = collection || []; + } + + // we are not using forEach for perf reasons (trying to avoid #call) + for (index = 0, length = array.length; index < length; index++) { + key = (collection === array) ? index : array[index]; + value = collection[key]; + last = lastOrder.shift(value); + if (last) { + // if we have already seen this object, then we need to reuse the + // associated scope/element + childScope = last.scope; + nextOrder.push(value, last); + + if (index === last.index) { + // do nothing + cursor = last.element; + } else { + // existing item which got moved + last.index = index; + // This may be a noop, if the element is next, but I don't know of a good way to + // figure this out, since it would require extra DOM access, so let's just hope that + // the browsers realizes that it is noop, and treats it as such. + cursor.after(last.element); + cursor = last.element; + } + } else { + // new item which we don't know about + childScope = scope.$new(); + } + + childScope[valueIdent] = value; + if (keyIdent) childScope[keyIdent] = key; + childScope.$index = index; + + childScope.$first = (index === 0); + childScope.$last = (index === (collectionLength - 1)); + childScope.$middle = !(childScope.$first || childScope.$last); + + if (!last) { + linker(childScope, function(clone){ + cursor.after(clone); + last = { + scope: childScope, + element: (cursor = clone), + index: index + }; + nextOrder.push(value, last); + }); + } + } + + //shrink children + for (key in lastOrder) { + if (lastOrder.hasOwnProperty(key)) { + array = lastOrder[key]; + while(array.length) { + value = array.pop(); + value.element.remove(); + value.scope.$destroy(); + } + } + } + + lastOrder = nextOrder; + }); + }; + } +}); + +/** + * @ngdoc directive + * @name ng.directive:ngShow + * + * @description + * The `ngShow` and `ngHide` directives show or hide a portion of the DOM tree (HTML) + * conditionally. + * + * @element ANY + * @param {expression} ngShow If the {@link guide/expression expression} is truthy + * then the element is shown or hidden respectively. + * + * @example + + + Click me:
    + Show: I show up when your checkbox is checked.
    + Hide: I hide when your checkbox is checked. +
    + + it('should check ng-show / ng-hide', function() { + expect(element('.doc-example-live span:first:hidden').count()).toEqual(1); + expect(element('.doc-example-live span:last:visible').count()).toEqual(1); + + input('checked').check(); + + expect(element('.doc-example-live span:first:visible').count()).toEqual(1); + expect(element('.doc-example-live span:last:hidden').count()).toEqual(1); + }); + +
    + */ +//TODO(misko): refactor to remove element from the DOM +var ngShowDirective = ngDirective(function(scope, element, attr){ + scope.$watch(attr.ngShow, function(value){ + element.css('display', toBoolean(value) ? '' : 'none'); + }); +}); + + +/** + * @ngdoc directive + * @name ng.directive:ngHide + * + * @description + * The `ngHide` and `ngShow` directives hide or show a portion + * of the HTML conditionally. + * + * @element ANY + * @param {expression} ngHide If the {@link guide/expression expression} truthy then + * the element is shown or hidden respectively. + * + * @example + + + Click me:
    + Show: I show up when you checkbox is checked?
    + Hide: I hide when you checkbox is checked? +
    + + it('should check ng-show / ng-hide', function() { + expect(element('.doc-example-live span:first:hidden').count()).toEqual(1); + expect(element('.doc-example-live span:last:visible').count()).toEqual(1); + + input('checked').check(); + + expect(element('.doc-example-live span:first:visible').count()).toEqual(1); + expect(element('.doc-example-live span:last:hidden').count()).toEqual(1); + }); + +
    + */ +//TODO(misko): refactor to remove element from the DOM +var ngHideDirective = ngDirective(function(scope, element, attr){ + scope.$watch(attr.ngHide, function(value){ + element.css('display', toBoolean(value) ? 'none' : ''); + }); +}); + +/** + * @ngdoc directive + * @name ng.directive:ngStyle + * + * @description + * The `ngStyle` directive allows you to set CSS style on an HTML element conditionally. + * + * @element ANY + * @param {expression} ngStyle {@link guide/expression Expression} which evals to an + * object whose keys are CSS style names and values are corresponding values for those CSS + * keys. + * + * @example + + + + +
    + Sample Text +
    myStyle={{myStyle}}
    +
    + + span { + color: black; + } + + + it('should check ng-style', function() { + expect(element('.doc-example-live span').css('color')).toBe('rgb(0, 0, 0)'); + element('.doc-example-live :button[value=set]').click(); + expect(element('.doc-example-live span').css('color')).toBe('rgb(255, 0, 0)'); + element('.doc-example-live :button[value=clear]').click(); + expect(element('.doc-example-live span').css('color')).toBe('rgb(0, 0, 0)'); + }); + +
    + */ +var ngStyleDirective = ngDirective(function(scope, element, attr) { + scope.$watch(attr.ngStyle, function(newStyles, oldStyles) { + if (oldStyles && (newStyles !== oldStyles)) { + forEach(oldStyles, function(val, style) { element.css(style, '');}); + } + if (newStyles) element.css(newStyles); + }, true); +}); + +/** + * @ngdoc directive + * @name ng.directive:ngSwitch + * @restrict EA + * + * @description + * Conditionally change the DOM structure. + * + * @usageContent + * ... + * ... + * ... + * ... + * + * @scope + * @param {*} ngSwitch|on expression to match against ng-switch-when. + * @paramDescription + * On child elments add: + * + * * `ngSwitchWhen`: the case statement to match against. If match then this + * case will be displayed. + * * `ngSwitchDefault`: the default case when no other casses match. + * + * @example + + + +
    + + selection={{selection}} +
    +
    +
    Settings Div
    + Home Span + default +
    +
    +
    + + it('should start in settings', function() { + expect(element('.doc-example-live [ng-switch]').text()).toMatch(/Settings Div/); + }); + it('should change to home', function() { + select('selection').option('home'); + expect(element('.doc-example-live [ng-switch]').text()).toMatch(/Home Span/); + }); + it('should select deafault', function() { + select('selection').option('other'); + expect(element('.doc-example-live [ng-switch]').text()).toMatch(/default/); + }); + +
    + */ +var NG_SWITCH = 'ng-switch'; +var ngSwitchDirective = valueFn({ + restrict: 'EA', + compile: function(element, attr) { + var watchExpr = attr.ngSwitch || attr.on, + cases = {}; + + element.data(NG_SWITCH, cases); + return function(scope, element){ + var selectedTransclude, + selectedElement, + selectedScope; + + scope.$watch(watchExpr, function(value) { + if (selectedElement) { + selectedScope.$destroy(); + selectedElement.remove(); + selectedElement = selectedScope = null; + } + if ((selectedTransclude = cases['!' + value] || cases['?'])) { + scope.$eval(attr.change); + selectedScope = scope.$new(); + selectedTransclude(selectedScope, function(caseElement) { + selectedElement = caseElement; + element.append(caseElement); + }); + } + }); + }; + } +}); + +var ngSwitchWhenDirective = ngDirective({ + transclude: 'element', + priority: 500, + compile: function(element, attrs, transclude) { + var cases = element.inheritedData(NG_SWITCH); + assertArg(cases); + cases['!' + attrs.ngSwitchWhen] = transclude; + } +}); + +var ngSwitchDefaultDirective = ngDirective({ + transclude: 'element', + priority: 500, + compile: function(element, attrs, transclude) { + var cases = element.inheritedData(NG_SWITCH); + assertArg(cases); + cases['?'] = transclude; + } +}); + +/** + * @ngdoc directive + * @name ng.directive:ngTransclude + * + * @description + * Insert the transcluded DOM here. + * + * @element ANY + * + * @example + + + +
    +
    +
    + {{text}} +
    +
    + + it('should have transcluded', function() { + input('title').enter('TITLE'); + input('text').enter('TEXT'); + expect(binding('title')).toEqual('TITLE'); + expect(binding('text')).toEqual('TEXT'); + }); + +
    + * + */ +var ngTranscludeDirective = ngDirective({ + controller: ['$transclude', '$element', function($transclude, $element) { + $transclude(function(clone) { + $element.append(clone); + }); + }] +}); + +/** + * @ngdoc directive + * @name ng.directive:ngView + * @restrict ECA + * + * @description + * # Overview + * `ngView` is a directive that complements the {@link ng.$route $route} service by + * including the rendered template of the current route into the main layout (`index.html`) file. + * Every time the current route changes, the included view changes with it according to the + * configuration of the `$route` service. + * + * @scope + * @example + + +
    + Choose: + Moby | + Moby: Ch1 | + Gatsby | + Gatsby: Ch4 | + Scarlet Letter
    + +
    +
    + +
    $location.path() = {{$location.path()}}
    +
    $route.current.template = {{$route.current.template}}
    +
    $route.current.params = {{$route.current.params}}
    +
    $route.current.scope.name = {{$route.current.scope.name}}
    +
    $routeParams = {{$routeParams}}
    +
    +
    + + + controller: {{name}}
    + Book Id: {{params.bookId}}
    +
    + + + controller: {{name}}
    + Book Id: {{params.bookId}}
    + Chapter Id: {{params.chapterId}} +
    + + + angular.module('ngView', [], function($routeProvider, $locationProvider) { + $routeProvider.when('/Book/:bookId', { + templateUrl: 'book.html', + controller: BookCntl + }); + $routeProvider.when('/Book/:bookId/ch/:chapterId', { + templateUrl: 'chapter.html', + controller: ChapterCntl + }); + + // configure html5 to get links working on jsfiddle + $locationProvider.html5Mode(true); + }); + + function MainCntl($scope, $route, $routeParams, $location) { + $scope.$route = $route; + $scope.$location = $location; + $scope.$routeParams = $routeParams; + } + + function BookCntl($scope, $routeParams) { + $scope.name = "BookCntl"; + $scope.params = $routeParams; + } + + function ChapterCntl($scope, $routeParams) { + $scope.name = "ChapterCntl"; + $scope.params = $routeParams; + } + + + + it('should load and compile correct template', function() { + element('a:contains("Moby: Ch1")').click(); + var content = element('.doc-example-live [ng-view]').text(); + expect(content).toMatch(/controller\: ChapterCntl/); + expect(content).toMatch(/Book Id\: Moby/); + expect(content).toMatch(/Chapter Id\: 1/); + + element('a:contains("Scarlet")').click(); + content = element('.doc-example-live [ng-view]').text(); + expect(content).toMatch(/controller\: BookCntl/); + expect(content).toMatch(/Book Id\: Scarlet/); + }); + +
    + */ + + +/** + * @ngdoc event + * @name ng.directive:ngView#$viewContentLoaded + * @eventOf ng.directive:ngView + * @eventType emit on the current ngView scope + * @description + * Emitted every time the ngView content is reloaded. + */ +var ngViewDirective = ['$http', '$templateCache', '$route', '$anchorScroll', '$compile', + '$controller', + function($http, $templateCache, $route, $anchorScroll, $compile, + $controller) { + return { + restrict: 'ECA', + terminal: true, + link: function(scope, element, attr) { + var lastScope, + onloadExp = attr.onload || ''; + + scope.$on('$routeChangeSuccess', update); + update(); + + + function destroyLastScope() { + if (lastScope) { + lastScope.$destroy(); + lastScope = null; + } + } + + function clearContent() { + element.html(''); + destroyLastScope(); + } + + function update() { + var locals = $route.current && $route.current.locals, + template = locals && locals.$template; + + if (template) { + element.html(template); + destroyLastScope(); + + var link = $compile(element.contents()), + current = $route.current, + controller; + + lastScope = current.scope = scope.$new(); + if (current.controller) { + locals.$scope = lastScope; + controller = $controller(current.controller, locals); + element.contents().data('$ngControllerController', controller); + } + + link(lastScope); + lastScope.$emit('$viewContentLoaded'); + lastScope.$eval(onloadExp); + + // $anchorScroll might listen on event... + $anchorScroll(); + } else { + clearContent(); + } + } + } + }; +}]; + +/** + * @ngdoc directive + * @name ng.directive:script + * + * @description + * Load content of a script tag, with type `text/ng-template`, into `$templateCache`, so that the + * template can be used by `ngInclude`, `ngView` or directive templates. + * + * @restrict E + * @param {'text/ng-template'} type must be set to `'text/ng-template'` + * + * @example + + + + + Load inlined template +
    +
    + + it('should load template defined inside script tag', function() { + element('#tpl-link').click(); + expect(element('#tpl-content').text()).toMatch(/Content of the template/); + }); + +
    + */ +var scriptDirective = ['$templateCache', function($templateCache) { + return { + restrict: 'E', + terminal: true, + compile: function(element, attr) { + if (attr.type == 'text/ng-template') { + var templateUrl = attr.id, + // IE is not consistent, in scripts we have to read .text but in other nodes we have to read .textContent + text = element[0].text; + + $templateCache.put(templateUrl, text); + } + } + }; +}]; + +/** + * @ngdoc directive + * @name ng.directive:select + * @restrict E + * + * @description + * HTML `SELECT` element with angular data-binding. + * + * # `ngOptions` + * + * Optionally `ngOptions` attribute can be used to dynamically generate a list of `