polymer-paper-elements-rails 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +51 -0
- data/Rakefile +1 -0
- data/app/assets/components/iron-a11y-announcer/iron-a11y-announcer.html +125 -0
- data/app/assets/components/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html +418 -0
- data/app/assets/components/iron-autogrow-textarea/hero.svg +33 -0
- data/app/assets/components/iron-autogrow-textarea/iron-autogrow-textarea.html +263 -0
- data/app/assets/components/iron-behaviors/iron-button-state.html +195 -0
- data/app/assets/components/iron-behaviors/iron-control-state.html +102 -0
- data/app/assets/components/iron-fit-behavior/iron-fit-behavior.html +230 -0
- data/app/assets/components/iron-flex-layout/classes/iron-flex-layout.html +307 -0
- data/app/assets/components/iron-flex-layout/classes/iron-shadow-flex-layout.html +302 -0
- data/app/assets/components/iron-flex-layout/iron-flex-layout.html +313 -0
- data/app/assets/components/iron-form-element-behavior/iron-form-element-behavior.html +50 -0
- data/app/assets/components/iron-icon/hero.svg +19 -0
- data/app/assets/components/iron-icon/iron-icon.html +187 -0
- data/app/assets/components/iron-icons/av-icons.html +73 -0
- data/app/assets/components/iron-icons/communication-icons.html +59 -0
- data/app/assets/components/iron-icons/device-icons.html +94 -0
- data/app/assets/components/iron-icons/editor-icons.html +70 -0
- data/app/assets/components/iron-icons/hardware-icons.html +61 -0
- data/app/assets/components/iron-icons/hero.svg +35 -0
- data/app/assets/components/iron-icons/image-icons.html +164 -0
- data/app/assets/components/iron-icons/iron-icons.html +303 -0
- data/app/assets/components/iron-icons/maps-icons.html +71 -0
- data/app/assets/components/iron-icons/notification-icons.html +62 -0
- data/app/assets/components/iron-icons/social-icons.html +40 -0
- data/app/assets/components/iron-iconset-svg/iron-iconset-svg.html +191 -0
- data/app/assets/components/iron-input/hero.svg +19 -0
- data/app/assets/components/iron-input/iron-input.html +235 -0
- data/app/assets/components/iron-media-query/hero.svg +29 -0
- data/app/assets/components/iron-media-query/iron-media-query.html +84 -0
- data/app/assets/components/iron-menu-behavior/iron-menu-behavior.html +214 -0
- data/app/assets/components/iron-menu-behavior/iron-menubar-behavior.html +65 -0
- data/app/assets/components/iron-meta/hero.svg +33 -0
- data/app/assets/components/iron-meta/iron-meta.html +352 -0
- data/app/assets/components/iron-overlay-behavior/iron-overlay-backdrop.html +132 -0
- data/app/assets/components/iron-overlay-behavior/iron-overlay-behavior.html +432 -0
- data/app/assets/components/iron-overlay-behavior/iron-overlay-manager.html +107 -0
- data/app/assets/components/iron-range-behavior/iron-range-behavior.html +101 -0
- data/app/assets/components/iron-resizable-behavior/iron-resizable-behavior.html +139 -0
- data/app/assets/components/iron-selector/iron-multi-selectable.html +120 -0
- data/app/assets/components/iron-selector/iron-selectable.html +307 -0
- data/app/assets/components/iron-selector/iron-selection.html +115 -0
- data/app/assets/components/iron-selector/iron-selector.html +71 -0
- data/app/assets/components/iron-validatable-behavior/iron-validatable-behavior.html +100 -0
- data/app/assets/components/neon-animation/animations/cascaded-animation.html +84 -0
- data/app/assets/components/neon-animation/animations/fade-in-animation.html +49 -0
- data/app/assets/components/neon-animation/animations/fade-out-animation.html +49 -0
- data/app/assets/components/neon-animation/animations/hero-animation.html +83 -0
- data/app/assets/components/neon-animation/animations/opaque-animation.html +46 -0
- data/app/assets/components/neon-animation/animations/ripple-animation.html +92 -0
- data/app/assets/components/neon-animation/animations/scale-down-animation.html +65 -0
- data/app/assets/components/neon-animation/animations/scale-up-animation.html +58 -0
- data/app/assets/components/neon-animation/animations/slide-down-animation.html +59 -0
- data/app/assets/components/neon-animation/animations/slide-from-left-animation.html +60 -0
- data/app/assets/components/neon-animation/animations/slide-from-right-animation.html +60 -0
- data/app/assets/components/neon-animation/animations/slide-left-animation.html +59 -0
- data/app/assets/components/neon-animation/animations/slide-right-animation.html +59 -0
- data/app/assets/components/neon-animation/animations/slide-up-animation.html +59 -0
- data/app/assets/components/neon-animation/animations/transform-animation.html +61 -0
- data/app/assets/components/neon-animation/guides/neon-animation.md +313 -0
- data/app/assets/components/neon-animation/neon-animatable-behavior.html +156 -0
- data/app/assets/components/neon-animation/neon-animatable.html +54 -0
- data/app/assets/components/neon-animation/neon-animated-pages.html +208 -0
- data/app/assets/components/neon-animation/neon-animation-behavior.html +88 -0
- data/app/assets/components/neon-animation/neon-animation-runner-behavior.html +110 -0
- data/app/assets/components/neon-animation/neon-animation.html +17 -0
- data/app/assets/components/neon-animation/neon-animations.html +25 -0
- data/app/assets/components/neon-animation/neon-shared-element-animatable-behavior.html +37 -0
- data/app/assets/components/neon-animation/neon-shared-element-animation-behavior.html +66 -0
- data/app/assets/components/neon-animation/web-animations.html +11 -0
- data/app/assets/components/paper-behaviors/paper-button-behavior.html +55 -0
- data/app/assets/components/paper-behaviors/paper-inky-focus-behavior.html +44 -0
- data/app/assets/components/paper-button/paper-button.html +177 -0
- data/app/assets/components/paper-checkbox/metadata.html +17 -0
- data/app/assets/components/paper-checkbox/paper-checkbox.css +149 -0
- data/app/assets/components/paper-checkbox/paper-checkbox.html +163 -0
- data/app/assets/components/paper-dialog-behavior/hero.svg +51 -0
- data/app/assets/components/paper-dialog-behavior/paper-dialog-behavior.html +236 -0
- data/app/assets/components/paper-dialog-behavior/paper-dialog-common.css +58 -0
- data/app/assets/components/paper-dialog-scrollable/hero.svg +69 -0
- data/app/assets/components/paper-dialog-scrollable/paper-dialog-scrollable.html +150 -0
- data/app/assets/components/paper-dialog/hero.svg +58 -0
- data/app/assets/components/paper-dialog/paper-dialog.html +122 -0
- data/app/assets/components/paper-drawer-panel/hero.svg +21 -0
- data/app/assets/components/paper-drawer-panel/paper-drawer-panel.css +142 -0
- data/app/assets/components/paper-drawer-panel/paper-drawer-panel.html +585 -0
- data/app/assets/components/paper-fab/paper-fab.html +159 -0
- data/app/assets/components/paper-header-panel/hero.svg +38 -0
- data/app/assets/components/paper-header-panel/paper-header-panel.html +496 -0
- data/app/assets/components/paper-icon-button/paper-icon-button.html +141 -0
- data/app/assets/components/paper-input/all-imports.html +12 -0
- data/app/assets/components/paper-input/hero.svg +19 -0
- data/app/assets/components/paper-input/paper-input-addon-behavior.html +43 -0
- data/app/assets/components/paper-input/paper-input-behavior.html +293 -0
- data/app/assets/components/paper-input/paper-input-char-counter.html +95 -0
- data/app/assets/components/paper-input/paper-input-container.html +495 -0
- data/app/assets/components/paper-input/paper-input-error.html +99 -0
- data/app/assets/components/paper-input/paper-input.html +126 -0
- data/app/assets/components/paper-input/paper-textarea.html +100 -0
- data/app/assets/components/paper-item/all-imports.html +13 -0
- data/app/assets/components/paper-item/paper-icon-item.html +86 -0
- data/app/assets/components/paper-item/paper-item-body.html +93 -0
- data/app/assets/components/paper-item/paper-item-shared.css +19 -0
- data/app/assets/components/paper-item/paper-item.html +95 -0
- data/app/assets/components/paper-material/paper-material.html +98 -0
- data/app/assets/components/paper-menu/hero.svg +35 -0
- data/app/assets/components/paper-menu/paper-menu.html +133 -0
- data/app/assets/components/paper-progress/hero.svg +21 -0
- data/app/assets/components/paper-progress/paper-progress.html +199 -0
- data/app/assets/components/paper-radio-button/hero.svg +22 -0
- data/app/assets/components/paper-radio-button/paper-radio-button.css +109 -0
- data/app/assets/components/paper-radio-button/paper-radio-button.html +148 -0
- data/app/assets/components/paper-radio-group/hero.svg +25 -0
- data/app/assets/components/paper-radio-group/paper-radio-group.html +186 -0
- data/app/assets/components/paper-ripple/hero.svg +30 -0
- data/app/assets/components/paper-ripple/paper-ripple.html +714 -0
- data/app/assets/components/paper-scroll-header-panel/hero.svg +41 -0
- data/app/assets/components/paper-scroll-header-panel/paper-scroll-header-panel.html +455 -0
- data/app/assets/components/paper-slider/hero.svg +20 -0
- data/app/assets/components/paper-slider/paper-slider.css +252 -0
- data/app/assets/components/paper-slider/paper-slider.html +449 -0
- data/app/assets/components/paper-spinner/hero.svg +27 -0
- data/app/assets/components/paper-spinner/paper-spinner.css +325 -0
- data/app/assets/components/paper-spinner/paper-spinner.html +222 -0
- data/app/assets/components/paper-styles/classes/global.html +96 -0
- data/app/assets/components/paper-styles/classes/shadow-layout.html +302 -0
- data/app/assets/components/paper-styles/classes/shadow.html +39 -0
- data/app/assets/components/paper-styles/classes/typography.html +171 -0
- data/app/assets/components/paper-styles/color.html +333 -0
- data/app/assets/components/paper-styles/default-theme.html +39 -0
- data/app/assets/components/paper-styles/paper-styles-classes.html +14 -0
- data/app/assets/components/paper-styles/paper-styles.html +17 -0
- data/app/assets/components/paper-styles/shadow.html +61 -0
- data/app/assets/components/paper-styles/typography.html +240 -0
- data/app/assets/components/paper-tabs/hero.svg +23 -0
- data/app/assets/components/paper-tabs/paper-tab.html +158 -0
- data/app/assets/components/paper-tabs/paper-tabs-icons.html +18 -0
- data/app/assets/components/paper-tabs/paper-tabs.html +483 -0
- data/app/assets/components/paper-toast/hero.svg +20 -0
- data/app/assets/components/paper-toast/paper-toast.html +164 -0
- data/app/assets/components/paper-toggle-button/hero.svg +22 -0
- data/app/assets/components/paper-toggle-button/paper-toggle-button.css +108 -0
- data/app/assets/components/paper-toggle-button/paper-toggle-button.html +183 -0
- data/app/assets/components/paper-toolbar/paper-toolbar.html +375 -0
- data/app/assets/components/polymer-gestures/Gruntfile.js +60 -0
- data/app/assets/components/polymer-gestures/banner.txt +9 -0
- data/app/assets/components/polymer-gestures/build.json +17 -0
- data/app/assets/components/polymer-gestures/conf/karma.conf.js +39 -0
- data/app/assets/components/polymer-gestures/package.json +20 -0
- data/app/assets/components/polymer-gestures/polymer-gestures.html +21 -0
- data/app/assets/components/polymer-gestures/polymer-gestures.js +46 -0
- data/app/assets/components/polymer-gestures/src/dispatcher.js +474 -0
- data/app/assets/components/polymer-gestures/src/eventFactory.js +127 -0
- data/app/assets/components/polymer-gestures/src/hold.js +129 -0
- data/app/assets/components/polymer-gestures/src/mouse.js +135 -0
- data/app/assets/components/polymer-gestures/src/ms.js +80 -0
- data/app/assets/components/polymer-gestures/src/pinch.js +186 -0
- data/app/assets/components/polymer-gestures/src/platform-events.js +39 -0
- data/app/assets/components/polymer-gestures/src/pointer.js +68 -0
- data/app/assets/components/polymer-gestures/src/pointermap.js +67 -0
- data/app/assets/components/polymer-gestures/src/scope.js +10 -0
- data/app/assets/components/polymer-gestures/src/tap.js +103 -0
- data/app/assets/components/polymer-gestures/src/targetfind.js +244 -0
- data/app/assets/components/polymer-gestures/src/touch-action.js +60 -0
- data/app/assets/components/polymer-gestures/src/touch.js +341 -0
- data/app/assets/components/polymer-gestures/src/track.js +230 -0
- data/app/assets/components/web-animations-js/web-animations-next-lite.min.js +17 -0
- data/app/assets/components/web-animations-js/web-animations-next.min.js +17 -0
- data/app/assets/components/web-animations-js/web-animations.min.js +17 -0
- data/app/assets/components/webcomponentsjs/CustomElements.js +956 -0
- data/app/assets/components/webcomponentsjs/CustomElements.min.js +11 -0
- data/app/assets/components/webcomponentsjs/HTMLImports.js +1078 -0
- data/app/assets/components/webcomponentsjs/HTMLImports.min.js +11 -0
- data/app/assets/components/webcomponentsjs/MutationObserver.js +344 -0
- data/app/assets/components/webcomponentsjs/MutationObserver.min.js +11 -0
- data/app/assets/components/webcomponentsjs/ShadowDOM.js +4414 -0
- data/app/assets/components/webcomponentsjs/ShadowDOM.min.js +15 -0
- data/app/assets/components/webcomponentsjs/package.json +31 -0
- data/app/assets/components/webcomponentsjs/webcomponents-lite.js +2300 -0
- data/app/assets/components/webcomponentsjs/webcomponents-lite.min.js +13 -0
- data/app/assets/components/webcomponentsjs/webcomponents.js +7112 -0
- data/app/assets/components/webcomponentsjs/webcomponents.min.js +15 -0
- data/lib/polymer-paper-elements-rails.rb +2 -0
- data/lib/polymer-paper-elements-rails/engine.rb +4 -0
- data/lib/polymer-paper-elements-rails/version.rb +3 -0
- metadata +272 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
3
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
4
|
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
5
|
+
viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
|
|
6
|
+
<g id="background" display="none">
|
|
7
|
+
<rect display="inline" fill="#B0BEC5" width="225" height="126"/>
|
|
8
|
+
</g>
|
|
9
|
+
<g id="label">
|
|
10
|
+
</g>
|
|
11
|
+
<g id="art">
|
|
12
|
+
<path d="M175,81H49V45h126V81z M51,79h122V47H51V79z"/>
|
|
13
|
+
<g>
|
|
14
|
+
<defs>
|
|
15
|
+
<rect id="SVGID_5_" x="50" y="46" width="124" height="34"/>
|
|
16
|
+
</defs>
|
|
17
|
+
<clipPath id="SVGID_2_">
|
|
18
|
+
<use xlink:href="#SVGID_5_" overflow="visible"/>
|
|
19
|
+
</clipPath>
|
|
20
|
+
<circle opacity="0.5" clip-path="url(#SVGID_2_)" cx="84.4" cy="62.7" r="41.9"/>
|
|
21
|
+
<circle opacity="0.6" clip-path="url(#SVGID_2_)" cx="84.4" cy="62.7" r="26.3"/>
|
|
22
|
+
<circle opacity="0.6" clip-path="url(#SVGID_2_)" cx="66.4" cy="62.7" r="26.3"/>
|
|
23
|
+
</g>
|
|
24
|
+
<circle cx="50" cy="80" r="4"/>
|
|
25
|
+
<g id="ic_x5F_add_x0D_">
|
|
26
|
+
</g>
|
|
27
|
+
</g>
|
|
28
|
+
<g id="Guides">
|
|
29
|
+
</g>
|
|
30
|
+
</svg>
|
|
@@ -0,0 +1,714 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
|
3
|
+
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
|
4
|
+
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
|
5
|
+
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
|
6
|
+
Code distributed by Google as part of the polymer project is also
|
|
7
|
+
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
|
8
|
+
-->
|
|
9
|
+
|
|
10
|
+
<link rel="import" href="../polymer/polymer.html">
|
|
11
|
+
<link rel="import" href="../iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
|
|
12
|
+
|
|
13
|
+
<!--
|
|
14
|
+
`paper-ripple` provides a visual effect that other paper elements can
|
|
15
|
+
use to simulate a rippling effect emanating from the point of contact. The
|
|
16
|
+
effect can be visualized as a concentric circle with motion.
|
|
17
|
+
|
|
18
|
+
Example:
|
|
19
|
+
|
|
20
|
+
<paper-ripple></paper-ripple>
|
|
21
|
+
|
|
22
|
+
`paper-ripple` listens to "mousedown" and "mouseup" events so it would display ripple
|
|
23
|
+
effect when touches on it. You can also defeat the default behavior and
|
|
24
|
+
manually route the down and up actions to the ripple element. Note that it is
|
|
25
|
+
important if you call downAction() you will have to make sure to call
|
|
26
|
+
upAction() so that `paper-ripple` would end the animation loop.
|
|
27
|
+
|
|
28
|
+
Example:
|
|
29
|
+
|
|
30
|
+
<paper-ripple id="ripple" style="pointer-events: none;"></paper-ripple>
|
|
31
|
+
...
|
|
32
|
+
downAction: function(e) {
|
|
33
|
+
this.$.ripple.downAction({x: e.x, y: e.y});
|
|
34
|
+
},
|
|
35
|
+
upAction: function(e) {
|
|
36
|
+
this.$.ripple.upAction();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
Styling ripple effect:
|
|
40
|
+
|
|
41
|
+
Use CSS color property to style the ripple:
|
|
42
|
+
|
|
43
|
+
paper-ripple {
|
|
44
|
+
color: #4285f4;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
Note that CSS color property is inherited so it is not required to set it on
|
|
48
|
+
the `paper-ripple` element directly.
|
|
49
|
+
|
|
50
|
+
By default, the ripple is centered on the point of contact. Apply the `recenters`
|
|
51
|
+
attribute to have the ripple grow toward the center of its container.
|
|
52
|
+
|
|
53
|
+
<paper-ripple recenters></paper-ripple>
|
|
54
|
+
|
|
55
|
+
You can also center the ripple inside its container from the start.
|
|
56
|
+
|
|
57
|
+
<paper-ripple center></paper-ripple>
|
|
58
|
+
|
|
59
|
+
Apply `circle` class to make the rippling effect within a circle.
|
|
60
|
+
|
|
61
|
+
<paper-ripple class="circle"></paper-ripple>
|
|
62
|
+
|
|
63
|
+
@group Paper Elements
|
|
64
|
+
@element paper-ripple
|
|
65
|
+
@hero hero.svg
|
|
66
|
+
@demo demo/index.html
|
|
67
|
+
-->
|
|
68
|
+
|
|
69
|
+
<dom-module id="paper-ripple">
|
|
70
|
+
|
|
71
|
+
<!--
|
|
72
|
+
Fired when the animation finishes. This is useful if you want to wait until the ripple
|
|
73
|
+
animation finishes to perform some action.
|
|
74
|
+
|
|
75
|
+
@event transitionend
|
|
76
|
+
@param {Object} detail
|
|
77
|
+
@param {Object} detail.node The animated node
|
|
78
|
+
-->
|
|
79
|
+
|
|
80
|
+
<style>
|
|
81
|
+
:host {
|
|
82
|
+
display: block;
|
|
83
|
+
position: absolute;
|
|
84
|
+
border-radius: inherit;
|
|
85
|
+
overflow: hidden;
|
|
86
|
+
top: 0;
|
|
87
|
+
left: 0;
|
|
88
|
+
right: 0;
|
|
89
|
+
bottom: 0;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
:host([animating]) {
|
|
93
|
+
/* This resolves a rendering issue in Chrome (as of 40) where the
|
|
94
|
+
ripple is not properly clipped by its parent (which may have
|
|
95
|
+
rounded corners). See: http://jsbin.com/temexa/4
|
|
96
|
+
|
|
97
|
+
Note: We only apply this style conditionally. Otherwise, the browser
|
|
98
|
+
will create a new compositing layer for every ripple element on the
|
|
99
|
+
page, and that would be bad. */
|
|
100
|
+
-webkit-transform: translate(0, 0);
|
|
101
|
+
transform: translate3d(0, 0, 0);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
:host([noink]) {
|
|
105
|
+
pointer-events: none;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
#background,
|
|
109
|
+
#waves,
|
|
110
|
+
.wave-container,
|
|
111
|
+
.wave {
|
|
112
|
+
pointer-events: none;
|
|
113
|
+
position: absolute;
|
|
114
|
+
top: 0;
|
|
115
|
+
left: 0;
|
|
116
|
+
width: 100%;
|
|
117
|
+
height: 100%;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
#background,
|
|
121
|
+
.wave {
|
|
122
|
+
opacity: 0;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
#waves,
|
|
126
|
+
.wave {
|
|
127
|
+
overflow: hidden;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.wave-container,
|
|
131
|
+
.wave {
|
|
132
|
+
border-radius: 50%;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
:host(.circle) #background,
|
|
136
|
+
:host(.circle) #waves {
|
|
137
|
+
border-radius: 50%;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
:host(.circle) .wave-container {
|
|
141
|
+
overflow: hidden;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
</style>
|
|
145
|
+
<template>
|
|
146
|
+
<div id="background"></div>
|
|
147
|
+
<div id="waves"></div>
|
|
148
|
+
</template>
|
|
149
|
+
</dom-module>
|
|
150
|
+
<script>
|
|
151
|
+
(function() {
|
|
152
|
+
var Utility = {
|
|
153
|
+
cssColorWithAlpha: function(cssColor, alpha) {
|
|
154
|
+
var parts = cssColor.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
|
|
155
|
+
|
|
156
|
+
if (typeof alpha == 'undefined') {
|
|
157
|
+
alpha = 1;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (!parts) {
|
|
161
|
+
return 'rgba(255, 255, 255, ' + alpha + ')';
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return 'rgba(' + parts[1] + ', ' + parts[2] + ', ' + parts[3] + ', ' + alpha + ')';
|
|
165
|
+
},
|
|
166
|
+
|
|
167
|
+
distance: function(x1, y1, x2, y2) {
|
|
168
|
+
var xDelta = (x1 - x2);
|
|
169
|
+
var yDelta = (y1 - y2);
|
|
170
|
+
|
|
171
|
+
return Math.sqrt(xDelta * xDelta + yDelta * yDelta);
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
now: (function() {
|
|
175
|
+
if (window.performance && window.performance.now) {
|
|
176
|
+
return window.performance.now.bind(window.performance);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return Date.now;
|
|
180
|
+
})()
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* @param {HTMLElement} element
|
|
185
|
+
* @constructor
|
|
186
|
+
*/
|
|
187
|
+
function ElementMetrics(element) {
|
|
188
|
+
this.element = element;
|
|
189
|
+
this.width = this.boundingRect.width;
|
|
190
|
+
this.height = this.boundingRect.height;
|
|
191
|
+
|
|
192
|
+
this.size = Math.max(this.width, this.height);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
ElementMetrics.prototype = {
|
|
196
|
+
get boundingRect () {
|
|
197
|
+
return this.element.getBoundingClientRect();
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
furthestCornerDistanceFrom: function(x, y) {
|
|
201
|
+
var topLeft = Utility.distance(x, y, 0, 0);
|
|
202
|
+
var topRight = Utility.distance(x, y, this.width, 0);
|
|
203
|
+
var bottomLeft = Utility.distance(x, y, 0, this.height);
|
|
204
|
+
var bottomRight = Utility.distance(x, y, this.width, this.height);
|
|
205
|
+
|
|
206
|
+
return Math.max(topLeft, topRight, bottomLeft, bottomRight);
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* @param {HTMLElement} element
|
|
212
|
+
* @constructor
|
|
213
|
+
*/
|
|
214
|
+
function Ripple(element) {
|
|
215
|
+
this.element = element;
|
|
216
|
+
this.color = window.getComputedStyle(element).color;
|
|
217
|
+
|
|
218
|
+
this.wave = document.createElement('div');
|
|
219
|
+
this.waveContainer = document.createElement('div');
|
|
220
|
+
this.wave.style.backgroundColor = this.color;
|
|
221
|
+
this.wave.classList.add('wave');
|
|
222
|
+
this.waveContainer.classList.add('wave-container');
|
|
223
|
+
Polymer.dom(this.waveContainer).appendChild(this.wave);
|
|
224
|
+
|
|
225
|
+
this.resetInteractionState();
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
Ripple.MAX_RADIUS = 300;
|
|
229
|
+
|
|
230
|
+
Ripple.prototype = {
|
|
231
|
+
get recenters() {
|
|
232
|
+
return this.element.recenters;
|
|
233
|
+
},
|
|
234
|
+
|
|
235
|
+
get center() {
|
|
236
|
+
return this.element.center;
|
|
237
|
+
},
|
|
238
|
+
|
|
239
|
+
get mouseDownElapsed() {
|
|
240
|
+
var elapsed;
|
|
241
|
+
|
|
242
|
+
if (!this.mouseDownStart) {
|
|
243
|
+
return 0;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
elapsed = Utility.now() - this.mouseDownStart;
|
|
247
|
+
|
|
248
|
+
if (this.mouseUpStart) {
|
|
249
|
+
elapsed -= this.mouseUpElapsed;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return elapsed;
|
|
253
|
+
},
|
|
254
|
+
|
|
255
|
+
get mouseUpElapsed() {
|
|
256
|
+
return this.mouseUpStart ?
|
|
257
|
+
Utility.now () - this.mouseUpStart : 0;
|
|
258
|
+
},
|
|
259
|
+
|
|
260
|
+
get mouseDownElapsedSeconds() {
|
|
261
|
+
return this.mouseDownElapsed / 1000;
|
|
262
|
+
},
|
|
263
|
+
|
|
264
|
+
get mouseUpElapsedSeconds() {
|
|
265
|
+
return this.mouseUpElapsed / 1000;
|
|
266
|
+
},
|
|
267
|
+
|
|
268
|
+
get mouseInteractionSeconds() {
|
|
269
|
+
return this.mouseDownElapsedSeconds + this.mouseUpElapsedSeconds;
|
|
270
|
+
},
|
|
271
|
+
|
|
272
|
+
get initialOpacity() {
|
|
273
|
+
return this.element.initialOpacity;
|
|
274
|
+
},
|
|
275
|
+
|
|
276
|
+
get opacityDecayVelocity() {
|
|
277
|
+
return this.element.opacityDecayVelocity;
|
|
278
|
+
},
|
|
279
|
+
|
|
280
|
+
get radius() {
|
|
281
|
+
var width2 = this.containerMetrics.width * this.containerMetrics.width;
|
|
282
|
+
var height2 = this.containerMetrics.height * this.containerMetrics.height;
|
|
283
|
+
var waveRadius = Math.min(
|
|
284
|
+
Math.sqrt(width2 + height2),
|
|
285
|
+
Ripple.MAX_RADIUS
|
|
286
|
+
) * 1.1 + 5;
|
|
287
|
+
|
|
288
|
+
var duration = 1.1 - 0.2 * (waveRadius / Ripple.MAX_RADIUS);
|
|
289
|
+
var timeNow = this.mouseInteractionSeconds / duration;
|
|
290
|
+
var size = waveRadius * (1 - Math.pow(80, -timeNow));
|
|
291
|
+
|
|
292
|
+
return Math.abs(size);
|
|
293
|
+
},
|
|
294
|
+
|
|
295
|
+
get opacity() {
|
|
296
|
+
if (!this.mouseUpStart) {
|
|
297
|
+
return this.initialOpacity;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
return Math.max(
|
|
301
|
+
0,
|
|
302
|
+
this.initialOpacity - this.mouseUpElapsedSeconds * this.opacityDecayVelocity
|
|
303
|
+
);
|
|
304
|
+
},
|
|
305
|
+
|
|
306
|
+
get outerOpacity() {
|
|
307
|
+
// Linear increase in background opacity, capped at the opacity
|
|
308
|
+
// of the wavefront (waveOpacity).
|
|
309
|
+
var outerOpacity = this.mouseUpElapsedSeconds * 0.3;
|
|
310
|
+
var waveOpacity = this.opacity;
|
|
311
|
+
|
|
312
|
+
return Math.max(
|
|
313
|
+
0,
|
|
314
|
+
Math.min(outerOpacity, waveOpacity)
|
|
315
|
+
);
|
|
316
|
+
},
|
|
317
|
+
|
|
318
|
+
get isOpacityFullyDecayed() {
|
|
319
|
+
return this.opacity < 0.01 &&
|
|
320
|
+
this.radius >= Math.min(this.maxRadius, Ripple.MAX_RADIUS);
|
|
321
|
+
},
|
|
322
|
+
|
|
323
|
+
get isRestingAtMaxRadius() {
|
|
324
|
+
return this.opacity >= this.initialOpacity &&
|
|
325
|
+
this.radius >= Math.min(this.maxRadius, Ripple.MAX_RADIUS);
|
|
326
|
+
},
|
|
327
|
+
|
|
328
|
+
get isAnimationComplete() {
|
|
329
|
+
return this.mouseUpStart ?
|
|
330
|
+
this.isOpacityFullyDecayed : this.isRestingAtMaxRadius;
|
|
331
|
+
},
|
|
332
|
+
|
|
333
|
+
get translationFraction() {
|
|
334
|
+
return Math.min(
|
|
335
|
+
1,
|
|
336
|
+
this.radius / this.containerMetrics.size * 2 / Math.sqrt(2)
|
|
337
|
+
);
|
|
338
|
+
},
|
|
339
|
+
|
|
340
|
+
get xNow() {
|
|
341
|
+
if (this.xEnd) {
|
|
342
|
+
return this.xStart + this.translationFraction * (this.xEnd - this.xStart);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
return this.xStart;
|
|
346
|
+
},
|
|
347
|
+
|
|
348
|
+
get yNow() {
|
|
349
|
+
if (this.yEnd) {
|
|
350
|
+
return this.yStart + this.translationFraction * (this.yEnd - this.yStart);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
return this.yStart;
|
|
354
|
+
},
|
|
355
|
+
|
|
356
|
+
get isMouseDown() {
|
|
357
|
+
return this.mouseDownStart && !this.mouseUpStart;
|
|
358
|
+
},
|
|
359
|
+
|
|
360
|
+
resetInteractionState: function() {
|
|
361
|
+
this.maxRadius = 0;
|
|
362
|
+
this.mouseDownStart = 0;
|
|
363
|
+
this.mouseUpStart = 0;
|
|
364
|
+
|
|
365
|
+
this.xStart = 0;
|
|
366
|
+
this.yStart = 0;
|
|
367
|
+
this.xEnd = 0;
|
|
368
|
+
this.yEnd = 0;
|
|
369
|
+
this.slideDistance = 0;
|
|
370
|
+
|
|
371
|
+
this.containerMetrics = new ElementMetrics(this.element);
|
|
372
|
+
},
|
|
373
|
+
|
|
374
|
+
draw: function() {
|
|
375
|
+
var scale;
|
|
376
|
+
var translateString;
|
|
377
|
+
var dx;
|
|
378
|
+
var dy;
|
|
379
|
+
|
|
380
|
+
this.wave.style.opacity = this.opacity;
|
|
381
|
+
|
|
382
|
+
scale = this.radius / (this.containerMetrics.size / 2);
|
|
383
|
+
dx = this.xNow - (this.containerMetrics.width / 2);
|
|
384
|
+
dy = this.yNow - (this.containerMetrics.height / 2);
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
// 2d transform for safari because of border-radius and overflow:hidden clipping bug.
|
|
388
|
+
// https://bugs.webkit.org/show_bug.cgi?id=98538
|
|
389
|
+
this.waveContainer.style.webkitTransform = 'translate(' + dx + 'px, ' + dy + 'px)';
|
|
390
|
+
this.waveContainer.style.transform = 'translate3d(' + dx + 'px, ' + dy + 'px, 0)';
|
|
391
|
+
this.wave.style.webkitTransform = 'scale(' + scale + ',' + scale + ')';
|
|
392
|
+
this.wave.style.transform = 'scale3d(' + scale + ',' + scale + ',1)';
|
|
393
|
+
},
|
|
394
|
+
|
|
395
|
+
downAction: function(event) {
|
|
396
|
+
var xCenter = this.containerMetrics.width / 2;
|
|
397
|
+
var yCenter = this.containerMetrics.height / 2;
|
|
398
|
+
|
|
399
|
+
this.resetInteractionState();
|
|
400
|
+
this.mouseDownStart = Utility.now();
|
|
401
|
+
|
|
402
|
+
if (this.center) {
|
|
403
|
+
this.xStart = xCenter;
|
|
404
|
+
this.yStart = yCenter;
|
|
405
|
+
this.slideDistance = Utility.distance(
|
|
406
|
+
this.xStart, this.yStart, this.xEnd, this.yEnd
|
|
407
|
+
);
|
|
408
|
+
} else {
|
|
409
|
+
this.xStart = event ?
|
|
410
|
+
event.detail.x - this.containerMetrics.boundingRect.left :
|
|
411
|
+
this.containerMetrics.width / 2;
|
|
412
|
+
this.yStart = event ?
|
|
413
|
+
event.detail.y - this.containerMetrics.boundingRect.top :
|
|
414
|
+
this.containerMetrics.height / 2;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
if (this.recenters) {
|
|
418
|
+
this.xEnd = xCenter;
|
|
419
|
+
this.yEnd = yCenter;
|
|
420
|
+
this.slideDistance = Utility.distance(
|
|
421
|
+
this.xStart, this.yStart, this.xEnd, this.yEnd
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
this.maxRadius = this.containerMetrics.furthestCornerDistanceFrom(
|
|
426
|
+
this.xStart,
|
|
427
|
+
this.yStart
|
|
428
|
+
);
|
|
429
|
+
|
|
430
|
+
this.waveContainer.style.top =
|
|
431
|
+
(this.containerMetrics.height - this.containerMetrics.size) / 2 + 'px';
|
|
432
|
+
this.waveContainer.style.left =
|
|
433
|
+
(this.containerMetrics.width - this.containerMetrics.size) / 2 + 'px';
|
|
434
|
+
|
|
435
|
+
this.waveContainer.style.width = this.containerMetrics.size + 'px';
|
|
436
|
+
this.waveContainer.style.height = this.containerMetrics.size + 'px';
|
|
437
|
+
},
|
|
438
|
+
|
|
439
|
+
upAction: function(event) {
|
|
440
|
+
if (!this.isMouseDown) {
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
this.mouseUpStart = Utility.now();
|
|
445
|
+
},
|
|
446
|
+
|
|
447
|
+
remove: function() {
|
|
448
|
+
Polymer.dom(this.waveContainer.parentNode).removeChild(
|
|
449
|
+
this.waveContainer
|
|
450
|
+
);
|
|
451
|
+
}
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
Polymer({
|
|
455
|
+
is: 'paper-ripple',
|
|
456
|
+
|
|
457
|
+
behaviors: [
|
|
458
|
+
Polymer.IronA11yKeysBehavior
|
|
459
|
+
],
|
|
460
|
+
|
|
461
|
+
properties: {
|
|
462
|
+
/**
|
|
463
|
+
* The initial opacity set on the wave.
|
|
464
|
+
*
|
|
465
|
+
* @attribute initialOpacity
|
|
466
|
+
* @type number
|
|
467
|
+
* @default 0.25
|
|
468
|
+
*/
|
|
469
|
+
initialOpacity: {
|
|
470
|
+
type: Number,
|
|
471
|
+
value: 0.25
|
|
472
|
+
},
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* How fast (opacity per second) the wave fades out.
|
|
476
|
+
*
|
|
477
|
+
* @attribute opacityDecayVelocity
|
|
478
|
+
* @type number
|
|
479
|
+
* @default 0.8
|
|
480
|
+
*/
|
|
481
|
+
opacityDecayVelocity: {
|
|
482
|
+
type: Number,
|
|
483
|
+
value: 0.8
|
|
484
|
+
},
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* If true, ripples will exhibit a gravitational pull towards
|
|
488
|
+
* the center of their container as they fade away.
|
|
489
|
+
*
|
|
490
|
+
* @attribute recenters
|
|
491
|
+
* @type boolean
|
|
492
|
+
* @default false
|
|
493
|
+
*/
|
|
494
|
+
recenters: {
|
|
495
|
+
type: Boolean,
|
|
496
|
+
value: false
|
|
497
|
+
},
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* If true, ripples will center inside its container
|
|
501
|
+
*
|
|
502
|
+
* @attribute recenters
|
|
503
|
+
* @type boolean
|
|
504
|
+
* @default false
|
|
505
|
+
*/
|
|
506
|
+
center: {
|
|
507
|
+
type: Boolean,
|
|
508
|
+
value: false
|
|
509
|
+
},
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* A list of the visual ripples.
|
|
513
|
+
*
|
|
514
|
+
* @attribute ripples
|
|
515
|
+
* @type Array
|
|
516
|
+
* @default []
|
|
517
|
+
*/
|
|
518
|
+
ripples: {
|
|
519
|
+
type: Array,
|
|
520
|
+
value: function() {
|
|
521
|
+
return [];
|
|
522
|
+
}
|
|
523
|
+
},
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* True when there are visible ripples animating within the
|
|
527
|
+
* element.
|
|
528
|
+
*/
|
|
529
|
+
animating: {
|
|
530
|
+
type: Boolean,
|
|
531
|
+
readOnly: true,
|
|
532
|
+
reflectToAttribute: true,
|
|
533
|
+
value: false
|
|
534
|
+
},
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* If true, the ripple will remain in the "down" state until `holdDown`
|
|
538
|
+
* is set to false again.
|
|
539
|
+
*/
|
|
540
|
+
holdDown: {
|
|
541
|
+
type: Boolean,
|
|
542
|
+
value: false,
|
|
543
|
+
observer: '_holdDownChanged'
|
|
544
|
+
},
|
|
545
|
+
|
|
546
|
+
_animating: {
|
|
547
|
+
type: Boolean
|
|
548
|
+
},
|
|
549
|
+
|
|
550
|
+
_boundAnimate: {
|
|
551
|
+
type: Function,
|
|
552
|
+
value: function() {
|
|
553
|
+
return this.animate.bind(this);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
},
|
|
557
|
+
|
|
558
|
+
get target () {
|
|
559
|
+
var ownerRoot = Polymer.dom(this).getOwnerRoot();
|
|
560
|
+
var target;
|
|
561
|
+
|
|
562
|
+
if (ownerRoot) {
|
|
563
|
+
target = ownerRoot.host;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
if (!target) {
|
|
567
|
+
target = this.parentNode;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
return target;
|
|
571
|
+
},
|
|
572
|
+
|
|
573
|
+
keyBindings: {
|
|
574
|
+
'enter:keydown': '_onEnterKeydown',
|
|
575
|
+
'space:keydown': '_onSpaceKeydown',
|
|
576
|
+
'space:keyup': '_onSpaceKeyup'
|
|
577
|
+
},
|
|
578
|
+
|
|
579
|
+
attached: function() {
|
|
580
|
+
this._listen(this.target, 'up', this.upAction.bind(this));
|
|
581
|
+
this._listen(this.target, 'down', this.downAction.bind(this));
|
|
582
|
+
|
|
583
|
+
if (!this.target.hasAttribute('noink')) {
|
|
584
|
+
this.keyEventTarget = this.target;
|
|
585
|
+
}
|
|
586
|
+
},
|
|
587
|
+
|
|
588
|
+
get shouldKeepAnimating () {
|
|
589
|
+
for (var index = 0; index < this.ripples.length; ++index) {
|
|
590
|
+
if (!this.ripples[index].isAnimationComplete) {
|
|
591
|
+
return true;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
return false;
|
|
596
|
+
},
|
|
597
|
+
|
|
598
|
+
simulatedRipple: function() {
|
|
599
|
+
this.downAction(null);
|
|
600
|
+
|
|
601
|
+
// Please see polymer/polymer#1305
|
|
602
|
+
this.async(function() {
|
|
603
|
+
this.upAction();
|
|
604
|
+
}, 1);
|
|
605
|
+
},
|
|
606
|
+
|
|
607
|
+
downAction: function(event) {
|
|
608
|
+
if (this.holdDown && this.ripples.length > 0) {
|
|
609
|
+
return;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
var ripple = this.addRipple();
|
|
613
|
+
|
|
614
|
+
ripple.downAction(event);
|
|
615
|
+
|
|
616
|
+
if (!this._animating) {
|
|
617
|
+
this.animate();
|
|
618
|
+
}
|
|
619
|
+
},
|
|
620
|
+
|
|
621
|
+
upAction: function(event) {
|
|
622
|
+
if (this.holdDown) {
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
this.ripples.forEach(function(ripple) {
|
|
627
|
+
ripple.upAction(event);
|
|
628
|
+
});
|
|
629
|
+
|
|
630
|
+
this.animate();
|
|
631
|
+
},
|
|
632
|
+
|
|
633
|
+
onAnimationComplete: function() {
|
|
634
|
+
this._animating = false;
|
|
635
|
+
this.$.background.style.backgroundColor = null;
|
|
636
|
+
this.fire('transitionend');
|
|
637
|
+
},
|
|
638
|
+
|
|
639
|
+
addRipple: function() {
|
|
640
|
+
var ripple = new Ripple(this);
|
|
641
|
+
|
|
642
|
+
Polymer.dom(this.$.waves).appendChild(ripple.waveContainer);
|
|
643
|
+
this.$.background.style.backgroundColor = ripple.color;
|
|
644
|
+
this.ripples.push(ripple);
|
|
645
|
+
|
|
646
|
+
this._setAnimating(true);
|
|
647
|
+
|
|
648
|
+
return ripple;
|
|
649
|
+
},
|
|
650
|
+
|
|
651
|
+
removeRipple: function(ripple) {
|
|
652
|
+
var rippleIndex = this.ripples.indexOf(ripple);
|
|
653
|
+
|
|
654
|
+
if (rippleIndex < 0) {
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
this.ripples.splice(rippleIndex, 1);
|
|
659
|
+
|
|
660
|
+
ripple.remove();
|
|
661
|
+
|
|
662
|
+
if (!this.ripples.length) {
|
|
663
|
+
this._setAnimating(false);
|
|
664
|
+
}
|
|
665
|
+
},
|
|
666
|
+
|
|
667
|
+
animate: function() {
|
|
668
|
+
var index;
|
|
669
|
+
var ripple;
|
|
670
|
+
|
|
671
|
+
this._animating = true;
|
|
672
|
+
|
|
673
|
+
for (index = 0; index < this.ripples.length; ++index) {
|
|
674
|
+
ripple = this.ripples[index];
|
|
675
|
+
|
|
676
|
+
ripple.draw();
|
|
677
|
+
|
|
678
|
+
this.$.background.style.opacity = ripple.outerOpacity;
|
|
679
|
+
|
|
680
|
+
if (ripple.isOpacityFullyDecayed && !ripple.isRestingAtMaxRadius) {
|
|
681
|
+
this.removeRipple(ripple);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
if (!this.shouldKeepAnimating && this.ripples.length === 0) {
|
|
686
|
+
this.onAnimationComplete();
|
|
687
|
+
} else {
|
|
688
|
+
window.requestAnimationFrame(this._boundAnimate);
|
|
689
|
+
}
|
|
690
|
+
},
|
|
691
|
+
|
|
692
|
+
_onEnterKeydown: function() {
|
|
693
|
+
this.downAction();
|
|
694
|
+
this.async(this.upAction, 1);
|
|
695
|
+
},
|
|
696
|
+
|
|
697
|
+
_onSpaceKeydown: function() {
|
|
698
|
+
this.downAction();
|
|
699
|
+
},
|
|
700
|
+
|
|
701
|
+
_onSpaceKeyup: function() {
|
|
702
|
+
this.upAction();
|
|
703
|
+
},
|
|
704
|
+
|
|
705
|
+
_holdDownChanged: function(holdDown) {
|
|
706
|
+
if (holdDown) {
|
|
707
|
+
this.downAction();
|
|
708
|
+
} else {
|
|
709
|
+
this.upAction();
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
});
|
|
713
|
+
})();
|
|
714
|
+
</script>
|