zucchini-ios 0.5.3
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.
- data/README.md +51 -0
- data/bin/zucchini +19 -0
- data/lib/config.rb +51 -0
- data/lib/feature.rb +87 -0
- data/lib/generator.rb +18 -0
- data/lib/report/css/zucchini.report.css +239 -0
- data/lib/report/js/jquery.effects.core.js +31 -0
- data/lib/report/js/jquery.js +4 -0
- data/lib/report/js/jquery.ui.core.js +18 -0
- data/lib/report/js/zucchini.report.js +59 -0
- data/lib/report/template.erb +47 -0
- data/lib/report/view.rb +16 -0
- data/lib/report.rb +30 -0
- data/lib/runner.rb +67 -0
- data/lib/screenshot.rb +82 -0
- data/lib/uia/base.coffee +63 -0
- data/lib/uia/screen.coffee +21 -0
- data/lib/version.rb +3 -0
- data/spec/lib/config_spec.rb +25 -0
- data/spec/lib/generator_spec.rb +27 -0
- data/spec/lib/report_spec.rb +34 -0
- data/spec/lib/runner_spec.rb +52 -0
- data/spec/lib/screenshot_spec.rb +73 -0
- data/spec/sample_setup/feature_one/feature.zucchini +1 -0
- data/spec/sample_setup/feature_one/masks/retina_ios5/06_sign up_spinner.png +0 -0
- data/spec/sample_setup/feature_one/reference/retina_ios5/06_sign up_spinner.png +0 -0
- data/spec/sample_setup/feature_one/reference/retina_ios5/06_sign up_spinner_error.png +0 -0
- data/spec/sample_setup/feature_one/run_data/Run 1/06_sign up_spinner.png +0 -0
- data/spec/sample_setup/feature_two/feature.zucchini +1 -0
- data/spec/sample_setup/feature_two/masks/retina_ios5/06_sign up_spinner.png +0 -0
- data/spec/sample_setup/feature_two/reference/retina_ios5/06_sign up_spinner.png +0 -0
- data/spec/sample_setup/feature_two/reference/retina_ios5/06_sign up_spinner_error.png +0 -0
- data/spec/sample_setup/feature_two/run_data/Run 1/06_sign up_spinner.png +0 -0
- data/spec/sample_setup/support/config.yml +13 -0
- data/spec/sample_setup/support/masks/retina_ios5.png +0 -0
- data/spec/sample_setup/support/screens/splash.coffee +8 -0
- data/spec/spec_helper.rb +16 -0
- data/templates/feature/feature.zucchini +6 -0
- data/templates/feature/masks/retina_ios5/.gitkeep +0 -0
- data/templates/feature/pending/retina_ios5/.gitkeep +0 -0
- data/templates/feature/reference/retina_ios5/.gitkeep +0 -0
- data/templates/feature/run_data/.gitignore +5 -0
- data/templates/feature/setup.rb +10 -0
- data/templates/project/features/support/config.yml +13 -0
- data/templates/project/features/support/masks/ipad_ios5.png +0 -0
- data/templates/project/features/support/masks/low_ios4.png +0 -0
- data/templates/project/features/support/masks/retina_ios5.png +0 -0
- data/templates/project/features/support/screens/welcome.coffee +13 -0
- data/zucchini.gemspec +24 -0
- metadata +155 -0
data/README.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
Pre-requisites
|
2
|
+
--------------
|
3
|
+
1. XCode 4.2
|
4
|
+
2. A few command line tools:
|
5
|
+
|
6
|
+
```
|
7
|
+
brew update && brew install imagemagick && brew install coffee-script
|
8
|
+
```
|
9
|
+
|
10
|
+
Start using Zucchini
|
11
|
+
----------------------
|
12
|
+
```
|
13
|
+
gem install zucchini-ios
|
14
|
+
```
|
15
|
+
|
16
|
+
Using Zucchini doesn't involve making any modifications to your application code.
|
17
|
+
You might as well keep your Zucchini tests in a separate project.
|
18
|
+
|
19
|
+
Start by creating a project scaffold:
|
20
|
+
|
21
|
+
```
|
22
|
+
zucchini generate --project /path/to/my_project
|
23
|
+
```
|
24
|
+
|
25
|
+
Create a feature scaffold for your first feature:
|
26
|
+
|
27
|
+
```
|
28
|
+
zucchini generate --feature /path/to/my_project/features/my_feature
|
29
|
+
```
|
30
|
+
|
31
|
+
Add your device to features/support/config.yml.
|
32
|
+
|
33
|
+
The [udidetect](https://github.com/vaskas/udidetect) utility comes in handy if you plan to add devices from time to time: `udidetect -z`.
|
34
|
+
|
35
|
+
Start hacking by modifying features/my_feature/feature.zucchini and features/support/screens/welcome.coffee.
|
36
|
+
|
37
|
+
Alternatively, check out the [zucchini-demo](https://github.com/rajbeniwal/zucchini-demo) project featuring an easy to explore Zucchini setup around Apple's CoreDataBooks sample.
|
38
|
+
|
39
|
+
Running a feature on the device
|
40
|
+
--------------------------------
|
41
|
+
```
|
42
|
+
ZUCCHINI_DEVICE="My Device" zucchini run /path/to/my_feature
|
43
|
+
```
|
44
|
+
|
45
|
+
See also
|
46
|
+
---------
|
47
|
+
```
|
48
|
+
zucchini --help
|
49
|
+
zucchini run --help
|
50
|
+
zucchini generate --help
|
51
|
+
```
|
data/bin/zucchini
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'clamp'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
$LOAD_PATH << File.expand_path("#{File.dirname(__FILE__)}/..")
|
7
|
+
require 'lib/config'
|
8
|
+
require 'lib/screenshot'
|
9
|
+
require 'lib/report'
|
10
|
+
require 'lib/feature'
|
11
|
+
require 'lib/runner'
|
12
|
+
require 'lib/generator'
|
13
|
+
|
14
|
+
class Zucchini::App < Clamp::Command
|
15
|
+
subcommand "generate", "Generate a project scaffold", Zucchini::Generator
|
16
|
+
subcommand "run", "Run zucchini", Zucchini::Runner
|
17
|
+
end
|
18
|
+
|
19
|
+
Zucchini::App.run
|
data/lib/config.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Zucchini
|
4
|
+
class Config
|
5
|
+
|
6
|
+
def self.base_path
|
7
|
+
@@base_path
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.base_path=(base_path)
|
11
|
+
@@base_path = base_path
|
12
|
+
@@config = YAML::load_file("#{base_path}/support/config.yml")
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.app
|
16
|
+
@@config['app']
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.template
|
20
|
+
@@config['template']
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.resolution_name(dimension)
|
24
|
+
@@config['resolutions'][dimension.to_i]
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.devices
|
28
|
+
@@config['devices']
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.device(device_name)
|
32
|
+
raise "Device not listed in config.yml" unless (device = devices[device_name])
|
33
|
+
{
|
34
|
+
:name => device_name,
|
35
|
+
:udid => device['UDID'],
|
36
|
+
:screen => device['screen']
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.server(server_name)
|
41
|
+
@@config['servers'][server_name]
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.url(server_name, href="")
|
45
|
+
server_config = server(server_name)
|
46
|
+
port = server_config['port'] ? ":#{server_config['port']}" : ""
|
47
|
+
|
48
|
+
"http://#{server_config['host']}#{port}#{href}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/feature.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
class Zucchini::Feature
|
2
|
+
attr_accessor :path
|
3
|
+
attr_accessor :device
|
4
|
+
attr_accessor :stats
|
5
|
+
|
6
|
+
attr_reader :succeeded
|
7
|
+
attr_reader :name
|
8
|
+
|
9
|
+
def initialize(path)
|
10
|
+
@path = path
|
11
|
+
@device = nil
|
12
|
+
@succeeded = false
|
13
|
+
@name = File.basename(path)
|
14
|
+
end
|
15
|
+
|
16
|
+
def run_data_path
|
17
|
+
"#{@path}/run_data"
|
18
|
+
end
|
19
|
+
|
20
|
+
def unmatched_pending_screenshots
|
21
|
+
Dir.glob("#{@path}/pending/#{@device[:screen]}/[^0-9]*.png").map do |file|
|
22
|
+
screenshot = Zucchini::Screenshot.new(file, nil, true)
|
23
|
+
screenshot.test_path = File.expand_path(file)
|
24
|
+
screenshot.diff = [:pending, "unmatched"]
|
25
|
+
screenshot
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def screenshots
|
30
|
+
@screenshots ||= Dir.glob("#{run_data_path}/Run\ 1/*.png").map do |file|
|
31
|
+
screenshot = Zucchini::Screenshot.new(file, @device)
|
32
|
+
screenshot.mask
|
33
|
+
screenshot.compare
|
34
|
+
screenshot
|
35
|
+
end + unmatched_pending_screenshots
|
36
|
+
end
|
37
|
+
|
38
|
+
def stats
|
39
|
+
@stats ||= screenshots.inject({:passed => [], :failed => [], :pending => []}) do |stats, s|
|
40
|
+
stats[s.diff[0]] << s
|
41
|
+
stats
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def compile_js
|
46
|
+
zucchini_base_path = File.expand_path("#{File.dirname(__FILE__)}/..")
|
47
|
+
|
48
|
+
feature_text = File.open("#{@path}/feature.zucchini").read.gsub(/#.+\n/,"").gsub(/\n/, "\\n")
|
49
|
+
File.open("#{run_data_path}/feature.coffee", "w+") { |f| f.write("Zucchini.run('#{feature_text}')") }
|
50
|
+
`coffee -o #{run_data_path} -j #{run_data_path}/feature.js -c #{zucchini_base_path}/lib/uia #{@path}/../support/screens #{run_data_path}/feature.coffee`
|
51
|
+
end
|
52
|
+
|
53
|
+
def collect
|
54
|
+
with_setup do
|
55
|
+
`rm -rf #{run_data_path}/*`
|
56
|
+
compile_js
|
57
|
+
|
58
|
+
begin
|
59
|
+
out = `instruments -w #{@device[:udid]} -t #{Zucchini::Config.template} #{Zucchini::Config.app} -e UIASCRIPT #{run_data_path}/feature.js -e UIARESULTSPATH #{run_data_path} 2>&1`
|
60
|
+
puts out
|
61
|
+
# Hack. Instruments don't issue error return codes when JS exceptions occur
|
62
|
+
raise "Instruments run error" if (out.match /JavaScript error/) || (out.match /Instruments\ .{0,5}\ Error\ :/ )
|
63
|
+
ensure
|
64
|
+
`rm -rf instrumentscli*.trace`
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def compare
|
70
|
+
`rm -rf #{run_data_path}/Diff/*`
|
71
|
+
@succeeded = (stats[:failed].length == 0)
|
72
|
+
end
|
73
|
+
|
74
|
+
def with_setup
|
75
|
+
setup = "#{@path}/setup.rb"
|
76
|
+
if File.exists?(setup)
|
77
|
+
require setup
|
78
|
+
begin
|
79
|
+
Setup.before { yield }
|
80
|
+
ensure
|
81
|
+
Setup.after
|
82
|
+
end
|
83
|
+
else
|
84
|
+
yield
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/generator.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
class Zucchini::Generator < Clamp::Command
|
2
|
+
option %W(-p --project), :flag, "Generate a project"
|
3
|
+
option %W(-f --feature), :flag, "Generate a feature"
|
4
|
+
|
5
|
+
parameter "PATH", "Path"
|
6
|
+
|
7
|
+
def templates_path
|
8
|
+
File.expand_path("#{File.dirname(__FILE__)}/../templates")
|
9
|
+
end
|
10
|
+
|
11
|
+
def execute
|
12
|
+
if project?
|
13
|
+
FileUtils.mkdir_p(path)
|
14
|
+
FileUtils.cp_r("#{templates_path}/project/.", path)
|
15
|
+
elsif feature? then FileUtils.cp_r("#{templates_path}/feature", path)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,239 @@
|
|
1
|
+
html {
|
2
|
+
font-family: Myriad Pro, sans-serif;
|
3
|
+
}
|
4
|
+
body {
|
5
|
+
margin: 0;
|
6
|
+
}
|
7
|
+
tr {
|
8
|
+
text-align: center;
|
9
|
+
}
|
10
|
+
td {
|
11
|
+
padding: 2px;
|
12
|
+
}
|
13
|
+
dl {
|
14
|
+
-webkit-margin-before: 0;
|
15
|
+
}
|
16
|
+
dd {
|
17
|
+
-webkit-margin-start: 0;
|
18
|
+
}
|
19
|
+
h1 {
|
20
|
+
margin: 16px;
|
21
|
+
font-weight: normal;
|
22
|
+
font-size: 24px;
|
23
|
+
}
|
24
|
+
h1 .time {
|
25
|
+
margin-left: 10px;
|
26
|
+
opacity: 0.5;
|
27
|
+
}
|
28
|
+
h3 {
|
29
|
+
margin: 0 0 6px 4px;
|
30
|
+
font-size: 24px;
|
31
|
+
width: 763px;
|
32
|
+
padding: 0;
|
33
|
+
float: left;
|
34
|
+
text-shadow: 1px 1px 1px white;
|
35
|
+
}
|
36
|
+
.indicators {
|
37
|
+
font-size: 12px;
|
38
|
+
width: 92px;
|
39
|
+
float: left;
|
40
|
+
margin: 5px 28px 5px 0;
|
41
|
+
-webkit-transition: all 0.1s ease-in-out;
|
42
|
+
}
|
43
|
+
.indicators div {
|
44
|
+
border-radius: 8px;
|
45
|
+
padding: 3px 8px;
|
46
|
+
margin-right: 5px;
|
47
|
+
float: right;
|
48
|
+
color: #FFF;
|
49
|
+
opacity: 0.8;
|
50
|
+
height: 11px;
|
51
|
+
line-height: 11px;
|
52
|
+
font-weight: bold;
|
53
|
+
}
|
54
|
+
.indicators div:hover {
|
55
|
+
-webkit-transition:opacity 0.3s ease-in-out;
|
56
|
+
}
|
57
|
+
.indicators .passed {
|
58
|
+
background: #65C400;
|
59
|
+
}
|
60
|
+
.indicators .failed {
|
61
|
+
background: #C20000;
|
62
|
+
}
|
63
|
+
.indicators .pending {
|
64
|
+
background: #F9E934;
|
65
|
+
color: #000;
|
66
|
+
}
|
67
|
+
.feature {
|
68
|
+
padding: 10px 9px 4px 9px;
|
69
|
+
border-radius: 5px;
|
70
|
+
width: 1012px;
|
71
|
+
margin: 15px 15px 24px 15px;
|
72
|
+
box-shadow: 0 0 4px rgba(0,0,0,0.2);
|
73
|
+
}
|
74
|
+
.ci .feature {
|
75
|
+
display: none;
|
76
|
+
}
|
77
|
+
.ci .first.feature {
|
78
|
+
display: block;
|
79
|
+
}
|
80
|
+
.buttons {
|
81
|
+
float: left;
|
82
|
+
width: 125px;
|
83
|
+
display: block;
|
84
|
+
}
|
85
|
+
.ci .buttons {
|
86
|
+
display: none;
|
87
|
+
}
|
88
|
+
.buttons a {
|
89
|
+
text-align: center;
|
90
|
+
width: 70px;
|
91
|
+
color: #484848;
|
92
|
+
text-decoration: none;
|
93
|
+
text-shadow: 0 1px 0 white;
|
94
|
+
font: bold 12px Helvetica, Arial, sans-serif;
|
95
|
+
margin-bottom: 6px;
|
96
|
+
line-height: 26px;
|
97
|
+
height: 25px;
|
98
|
+
display: block;
|
99
|
+
float: left;
|
100
|
+
padding: 0 5px;
|
101
|
+
background: -webkit-linear-gradient(top, #F4F4F4, #ECECEC);
|
102
|
+
border: solid 1px #D4D4D4;
|
103
|
+
border-radius: 5px;
|
104
|
+
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
|
105
|
+
-webkit-transition: border-color .218s;
|
106
|
+
cursor: pointer;
|
107
|
+
}
|
108
|
+
.buttons a.left {
|
109
|
+
border-radius: 5px 0 0 5px;
|
110
|
+
width: 50px;
|
111
|
+
float: left;
|
112
|
+
margin: 0;
|
113
|
+
}
|
114
|
+
.buttons a.right {
|
115
|
+
border-radius: 0 5px 5px 0;
|
116
|
+
width: 50px;
|
117
|
+
float: left;
|
118
|
+
position: relative;
|
119
|
+
left: -1px;
|
120
|
+
margin: 0;
|
121
|
+
}
|
122
|
+
.buttons a:hover {
|
123
|
+
border: solid 1px #7f7f7f;
|
124
|
+
color: #282828;
|
125
|
+
background: -webkit-linear-gradient(top, #ffffff, #dfdfdf);
|
126
|
+
}
|
127
|
+
.buttons a:active {
|
128
|
+
border: solid 1px #7f7f7f;
|
129
|
+
background: #d0d0d0;
|
130
|
+
background: -webkit-gradient(linear, left top, left bottom, from(#a8a8a8), color-stop(0.15, #c6c6c6), to(#d8d8d8));
|
131
|
+
background: -webkit-linear-gradient(top, #a8a8a8, #c6c6c6 15%, #d8d8d8);
|
132
|
+
}
|
133
|
+
|
134
|
+
.screen {
|
135
|
+
-webkit-transition:all 0.2s ease-in-out;
|
136
|
+
width: 990px;
|
137
|
+
height: 15px;
|
138
|
+
padding: 5px 0 5px 9px;
|
139
|
+
margin-bottom: 6px;
|
140
|
+
border-radius: 5px;
|
141
|
+
cursor: pointer;
|
142
|
+
overflow: hidden;
|
143
|
+
}
|
144
|
+
.screen.passed {
|
145
|
+
color: #65C400;
|
146
|
+
background-color: #DBFFB4;
|
147
|
+
border: 1px #65C400 solid;
|
148
|
+
border-left: 10px #65C400 solid;
|
149
|
+
}
|
150
|
+
.screen.passed img {
|
151
|
+
box-shadow: 0px 0px 4px #65C400;
|
152
|
+
}
|
153
|
+
.screen.failed {
|
154
|
+
color: #C20000;
|
155
|
+
background-color: #FFD6D6;
|
156
|
+
border: 1px #C20000 solid;
|
157
|
+
border-left: 10px #C20000 solid;
|
158
|
+
}
|
159
|
+
.screen.failed img {
|
160
|
+
box-shadow: 0px 0px 4px #C20000;
|
161
|
+
}
|
162
|
+
.screen.pending {
|
163
|
+
color: #F2CF32;
|
164
|
+
background-color: #FFFDBC;
|
165
|
+
border: 1px solid #F9E934;
|
166
|
+
border-left: 10px solid #F9E934;
|
167
|
+
}
|
168
|
+
.screen.pending img {
|
169
|
+
box-shadow: 0px 0px 4px #F9E934;
|
170
|
+
}
|
171
|
+
.screen dt {
|
172
|
+
color: #000;
|
173
|
+
font-size: 13px;
|
174
|
+
line-height: 17px;
|
175
|
+
margin: 0;
|
176
|
+
font-weight: normal;
|
177
|
+
}
|
178
|
+
.ci .screen dt {
|
179
|
+
position: relative;
|
180
|
+
z-index: 2;
|
181
|
+
}
|
182
|
+
.screen dd {
|
183
|
+
float: left;
|
184
|
+
margin-right: 10px;
|
185
|
+
-webkit-transition:all 0.3s ease-in-out;
|
186
|
+
opacity: 0;
|
187
|
+
position: relative;
|
188
|
+
top: -30px;
|
189
|
+
}
|
190
|
+
.screen dd.hidden {
|
191
|
+
visibility: hidden;
|
192
|
+
}
|
193
|
+
.screen.expanded, .ci .screen {
|
194
|
+
-webkit-transition:all 0.2s ease-in-out;
|
195
|
+
height: 510px;
|
196
|
+
}
|
197
|
+
.screen.expanded dd, .ci .screen dd {
|
198
|
+
opacity: 1.0;
|
199
|
+
-webkit-transition:all 0.3s ease-in-out;
|
200
|
+
}
|
201
|
+
.screen p {
|
202
|
+
margin-bottom: -3px;
|
203
|
+
padding: 5px;
|
204
|
+
font-size: 13px;
|
205
|
+
text-align: center;
|
206
|
+
font-weight: bold;
|
207
|
+
background-color: rgba(255, 255, 255, 0.5);;
|
208
|
+
border-radius: 5px;
|
209
|
+
opacity: 0.0;
|
210
|
+
position: relative;
|
211
|
+
z-index: 0;
|
212
|
+
}
|
213
|
+
.screen dd:hover p {
|
214
|
+
opacity: 1.0;
|
215
|
+
}
|
216
|
+
.ci .screen dd p {
|
217
|
+
opacity: 1.0;
|
218
|
+
background: transparent;
|
219
|
+
}
|
220
|
+
.screen img {
|
221
|
+
width: 320px;
|
222
|
+
height: 480px;
|
223
|
+
position: relative;
|
224
|
+
}
|
225
|
+
.ci .viewport {
|
226
|
+
width: 1018px;
|
227
|
+
height: 530px;
|
228
|
+
overflow: scroll;
|
229
|
+
}
|
230
|
+
.ci .surface {
|
231
|
+
height: 530px;
|
232
|
+
width: 100000px;
|
233
|
+
position: relative;
|
234
|
+
}
|
235
|
+
.ci .surface .screen {
|
236
|
+
float: left;
|
237
|
+
margin-right: 10px;
|
238
|
+
position: relative;
|
239
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
/*
|
2
|
+
* jQuery UI Effects 1.8.16
|
3
|
+
*
|
4
|
+
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
5
|
+
* Dual licensed under the MIT or GPL Version 2 licenses.
|
6
|
+
* http://jquery.org/license
|
7
|
+
*
|
8
|
+
* http://docs.jquery.com/UI/Effects/
|
9
|
+
*/
|
10
|
+
jQuery.effects||function(f,j){function m(c){var a;if(c&&c.constructor==Array&&c.length==3)return c;if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)];if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return[parseInt(a[1],
|
11
|
+
16),parseInt(a[2],16),parseInt(a[3],16)];if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(c))return n.transparent;return n[f.trim(c).toLowerCase()]}function s(c,a){var b;do{b=f.curCSS(c,a);if(b!=""&&b!="transparent"||f.nodeName(c,"body"))break;a="backgroundColor"}while(c=c.parentNode);return m(b)}function o(){var c=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,
|
12
|
+
a={},b,d;if(c&&c.length&&c[0]&&c[c[0]])for(var e=c.length;e--;){b=c[e];if(typeof c[b]=="string"){d=b.replace(/\-(\w)/g,function(g,h){return h.toUpperCase()});a[d]=c[b]}}else for(b in c)if(typeof c[b]==="string")a[b]=c[b];return a}function p(c){var a,b;for(a in c){b=c[a];if(b==null||f.isFunction(b)||a in t||/scrollbar/.test(a)||!/color/i.test(a)&&isNaN(parseFloat(b)))delete c[a]}return c}function u(c,a){var b={_:0},d;for(d in a)if(c[d]!=a[d])b[d]=a[d];return b}function k(c,a,b,d){if(typeof c=="object"){d=
|
13
|
+
a;b=null;a=c;c=a.effect}if(f.isFunction(a)){d=a;b=null;a={}}if(typeof a=="number"||f.fx.speeds[a]){d=b;b=a;a={}}if(f.isFunction(b)){d=b;b=null}a=a||{};b=b||a.duration;b=f.fx.off?0:typeof b=="number"?b:b in f.fx.speeds?f.fx.speeds[b]:f.fx.speeds._default;d=d||a.complete;return[c,a,b,d]}function l(c){if(!c||typeof c==="number"||f.fx.speeds[c])return true;if(typeof c==="string"&&!f.effects[c])return true;return false}f.effects={};f.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor",
|
14
|
+
"borderTopColor","borderColor","color","outlineColor"],function(c,a){f.fx.step[a]=function(b){if(!b.colorInit){b.start=s(b.elem,a);b.end=m(b.end);b.colorInit=true}b.elem.style[a]="rgb("+Math.max(Math.min(parseInt(b.pos*(b.end[0]-b.start[0])+b.start[0],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[1]-b.start[1])+b.start[1],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[2]-b.start[2])+b.start[2],10),255),0)+")"}});var n={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,
|
15
|
+
0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,
|
16
|
+
211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},q=["add","remove","toggle"],t={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};f.effects.animateClass=function(c,a,b,
|
17
|
+
d){if(f.isFunction(b)){d=b;b=null}return this.queue(function(){var e=f(this),g=e.attr("style")||" ",h=p(o.call(this)),r,v=e.attr("class");f.each(q,function(w,i){c[i]&&e[i+"Class"](c[i])});r=p(o.call(this));e.attr("class",v);e.animate(u(h,r),{queue:false,duration:a,easing:b,complete:function(){f.each(q,function(w,i){c[i]&&e[i+"Class"](c[i])});if(typeof e.attr("style")=="object"){e.attr("style").cssText="";e.attr("style").cssText=g}else e.attr("style",g);d&&d.apply(this,arguments);f.dequeue(this)}})})};
|
18
|
+
f.fn.extend({_addClass:f.fn.addClass,addClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{add:c},a,b,d]):this._addClass(c)},_removeClass:f.fn.removeClass,removeClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{remove:c},a,b,d]):this._removeClass(c)},_toggleClass:f.fn.toggleClass,toggleClass:function(c,a,b,d,e){return typeof a=="boolean"||a===j?b?f.effects.animateClass.apply(this,[a?{add:c}:{remove:c},b,d,e]):this._toggleClass(c,a):f.effects.animateClass.apply(this,
|
19
|
+
[{toggle:c},a,b,d])},switchClass:function(c,a,b,d,e){return f.effects.animateClass.apply(this,[{add:a,remove:c},b,d,e])}});f.extend(f.effects,{version:"1.8.16",save:function(c,a){for(var b=0;b<a.length;b++)a[b]!==null&&c.data("ec.storage."+a[b],c[0].style[a[b]])},restore:function(c,a){for(var b=0;b<a.length;b++)a[b]!==null&&c.css(a[b],c.data("ec.storage."+a[b]))},setMode:function(c,a){if(a=="toggle")a=c.is(":hidden")?"show":"hide";return a},getBaseline:function(c,a){var b;switch(c[0]){case "top":b=
|
20
|
+
0;break;case "middle":b=0.5;break;case "bottom":b=1;break;default:b=c[0]/a.height}switch(c[1]){case "left":c=0;break;case "center":c=0.5;break;case "right":c=1;break;default:c=c[1]/a.width}return{x:c,y:b}},createWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent();var a={width:c.outerWidth(true),height:c.outerHeight(true),"float":c.css("float")},b=f("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),
|
21
|
+
d=document.activeElement;c.wrap(b);if(c[0]===d||f.contains(c[0],d))f(d).focus();b=c.parent();if(c.css("position")=="static"){b.css({position:"relative"});c.css({position:"relative"})}else{f.extend(a,{position:c.css("position"),zIndex:c.css("z-index")});f.each(["top","left","bottom","right"],function(e,g){a[g]=c.css(g);if(isNaN(parseInt(a[g],10)))a[g]="auto"});c.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}return b.css(a).show()},removeWrapper:function(c){var a,b=document.activeElement;
|
22
|
+
if(c.parent().is(".ui-effects-wrapper")){a=c.parent().replaceWith(c);if(c[0]===b||f.contains(c[0],b))f(b).focus();return a}return c},setTransition:function(c,a,b,d){d=d||{};f.each(a,function(e,g){unit=c.cssUnit(g);if(unit[0]>0)d[g]=unit[0]*b+unit[1]});return d}});f.fn.extend({effect:function(c){var a=k.apply(this,arguments),b={options:a[1],duration:a[2],callback:a[3]};a=b.options.mode;var d=f.effects[c];if(f.fx.off||!d)return a?this[a](b.duration,b.callback):this.each(function(){b.callback&&b.callback.call(this)});
|
23
|
+
return d.call(this,b)},_show:f.fn.show,show:function(c){if(l(c))return this._show.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="show";return this.effect.apply(this,a)}},_hide:f.fn.hide,hide:function(c){if(l(c))return this._hide.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="hide";return this.effect.apply(this,a)}},__toggle:f.fn.toggle,toggle:function(c){if(l(c)||typeof c==="boolean"||f.isFunction(c))return this.__toggle.apply(this,arguments);else{var a=k.apply(this,
|
24
|
+
arguments);a[1].mode="toggle";return this.effect.apply(this,a)}},cssUnit:function(c){var a=this.css(c),b=[];f.each(["em","px","%","pt"],function(d,e){if(a.indexOf(e)>0)b=[parseFloat(a),e]});return b}});f.easing.jswing=f.easing.swing;f.extend(f.easing,{def:"easeOutQuad",swing:function(c,a,b,d,e){return f.easing[f.easing.def](c,a,b,d,e)},easeInQuad:function(c,a,b,d,e){return d*(a/=e)*a+b},easeOutQuad:function(c,a,b,d,e){return-d*(a/=e)*(a-2)+b},easeInOutQuad:function(c,a,b,d,e){if((a/=e/2)<1)return d/
|
25
|
+
2*a*a+b;return-d/2*(--a*(a-2)-1)+b},easeInCubic:function(c,a,b,d,e){return d*(a/=e)*a*a+b},easeOutCubic:function(c,a,b,d,e){return d*((a=a/e-1)*a*a+1)+b},easeInOutCubic:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a+b;return d/2*((a-=2)*a*a+2)+b},easeInQuart:function(c,a,b,d,e){return d*(a/=e)*a*a*a+b},easeOutQuart:function(c,a,b,d,e){return-d*((a=a/e-1)*a*a*a-1)+b},easeInOutQuart:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a+b;return-d/2*((a-=2)*a*a*a-2)+b},easeInQuint:function(c,a,b,
|
26
|
+
d,e){return d*(a/=e)*a*a*a*a+b},easeOutQuint:function(c,a,b,d,e){return d*((a=a/e-1)*a*a*a*a+1)+b},easeInOutQuint:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a*a+b;return d/2*((a-=2)*a*a*a*a+2)+b},easeInSine:function(c,a,b,d,e){return-d*Math.cos(a/e*(Math.PI/2))+d+b},easeOutSine:function(c,a,b,d,e){return d*Math.sin(a/e*(Math.PI/2))+b},easeInOutSine:function(c,a,b,d,e){return-d/2*(Math.cos(Math.PI*a/e)-1)+b},easeInExpo:function(c,a,b,d,e){return a==0?b:d*Math.pow(2,10*(a/e-1))+b},easeOutExpo:function(c,
|
27
|
+
a,b,d,e){return a==e?b+d:d*(-Math.pow(2,-10*a/e)+1)+b},easeInOutExpo:function(c,a,b,d,e){if(a==0)return b;if(a==e)return b+d;if((a/=e/2)<1)return d/2*Math.pow(2,10*(a-1))+b;return d/2*(-Math.pow(2,-10*--a)+2)+b},easeInCirc:function(c,a,b,d,e){return-d*(Math.sqrt(1-(a/=e)*a)-1)+b},easeOutCirc:function(c,a,b,d,e){return d*Math.sqrt(1-(a=a/e-1)*a)+b},easeInOutCirc:function(c,a,b,d,e){if((a/=e/2)<1)return-d/2*(Math.sqrt(1-a*a)-1)+b;return d/2*(Math.sqrt(1-(a-=2)*a)+1)+b},easeInElastic:function(c,a,b,
|
28
|
+
d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/h);return-(h*Math.pow(2,10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g))+b},easeOutElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/h);return h*Math.pow(2,-10*a)*Math.sin((a*e-c)*2*Math.PI/g)+d+b},easeInOutElastic:function(c,a,b,d,e){c=1.70158;var g=
|
29
|
+
0,h=d;if(a==0)return b;if((a/=e/2)==2)return b+d;g||(g=e*0.3*1.5);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/h);if(a<1)return-0.5*h*Math.pow(2,10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g)+b;return h*Math.pow(2,-10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g)*0.5+d+b},easeInBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;return d*(a/=e)*a*((g+1)*a-g)+b},easeOutBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;return d*((a=a/e-1)*a*((g+1)*a+g)+1)+b},easeInOutBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;
|
30
|
+
if((a/=e/2)<1)return d/2*a*a*(((g*=1.525)+1)*a-g)+b;return d/2*((a-=2)*a*(((g*=1.525)+1)*a+g)+2)+b},easeInBounce:function(c,a,b,d,e){return d-f.easing.easeOutBounce(c,e-a,0,d,e)+b},easeOutBounce:function(c,a,b,d,e){return(a/=e)<1/2.75?d*7.5625*a*a+b:a<2/2.75?d*(7.5625*(a-=1.5/2.75)*a+0.75)+b:a<2.5/2.75?d*(7.5625*(a-=2.25/2.75)*a+0.9375)+b:d*(7.5625*(a-=2.625/2.75)*a+0.984375)+b},easeInOutBounce:function(c,a,b,d,e){if(a<e/2)return f.easing.easeInBounce(c,a*2,0,d,e)*0.5+b;return f.easing.easeOutBounce(c,
|
31
|
+
a*2-e,0,d,e)*0.5+d*0.5+b}})}(jQuery);
|